From 15fc3ddf8c0267367a33918a5a60af8889f04ac5 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 23 May 2023 17:01:48 +0800 Subject: [PATCH 001/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/engine/dao/PipelineResDao.kt | 46 ++++++++++++----- .../engine/dao/PipelineResVersionDao.kt | 49 +++++++++++++------ .../service/PipelineRepositoryService.kt | 44 ++++++++++++----- 3 files changed, 100 insertions(+), 39 deletions(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt index 291e4022620..53481ab4d2b 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt @@ -29,7 +29,9 @@ package com.tencent.devops.process.engine.dao import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.common.pipeline.container.TriggerContainer import com.tencent.devops.model.process.Tables.T_PIPELINE_RESOURCE +import com.tencent.devops.model.process.tables.records.TPipelineResourceRecord import com.tencent.devops.process.pojo.setting.PipelineModelVersion import org.jooq.Condition import org.jooq.DSLContext @@ -50,29 +52,49 @@ class PipelineResDao { pipelineId: String, creator: String, version: Int, - model: Model + versionName: String = "init", + model: Model, + trigger: TriggerContainer, + modelVersion: Int, + triggerVersion: Int, + settingVersion: Int ) { logger.info("Create the pipeline model pipelineId=$pipelineId, version=$version") with(T_PIPELINE_RESOURCE) { val modelString = JsonUtil.toJson(model, formatted = false) - dslContext.insertInto( - this, - PROJECT_ID, - PIPELINE_ID, - VERSION, - MODEL, - CREATOR, - CREATE_TIME - ) - .values(projectId, pipelineId, version, modelString, creator, LocalDateTime.now()) - .onDuplicateKeyUpdate() + val triggerString = JsonUtil.toJson(trigger, formatted = false) + dslContext.insertInto(this) + .set(PROJECT_ID, projectId) + .set(PIPELINE_ID, pipelineId) + .set(VERSION, version) + .set(VERSION_NAME, versionName) .set(MODEL, modelString) + .set(TRIGGER, triggerString) .set(CREATOR, creator) .set(CREATE_TIME, LocalDateTime.now()) + .set(MODEL_VERSION, modelVersion) + .set(TRIGGER_VERSION, triggerVersion) + .set(SETTING_VERSION, settingVersion) + .onDuplicateKeyUpdate() + .set(MODEL, modelString) + .set(TRIGGER, triggerString) + .set(CREATOR, creator) + .set(VERSION_NAME, versionName) + .set(MODEL_VERSION, modelVersion) + .set(TRIGGER_VERSION, triggerVersion) + .set(SETTING_VERSION, settingVersion) .execute() } } + fun getLatestVersionRecord(dslContext: DSLContext, projectId: String, pipelineId: String): TPipelineResourceRecord? { + return with(T_PIPELINE_RESOURCE) { + dslContext.selectFrom(this) + .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) + .fetchAny() + } + } + fun getLatestVersionModelString(dslContext: DSLContext, projectId: String, pipelineId: String) = getVersionModelString(dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, version = null) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt index a51191d453f..68b2b918025 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt @@ -30,6 +30,7 @@ package com.tencent.devops.process.engine.dao import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.api.util.timestampmilli import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.common.pipeline.container.TriggerContainer import com.tencent.devops.model.process.Tables.T_PIPELINE_RESOURCE_VERSION import com.tencent.devops.process.pojo.setting.PipelineVersionSimple import org.jooq.DSLContext @@ -47,10 +48,13 @@ class PipelineResVersionDao { pipelineId: String, creator: String, version: Int, - versionName: String = "init", - model: Model + versionName: String, + model: Model, + trigger: TriggerContainer, + modelVersion: Int, + triggerVersion: Int, + settingVersion: Int ) { - val modelString = JsonUtil.toJson(model, formatted = false) create( dslContext = dslContext, projectId = projectId, @@ -58,7 +62,11 @@ class PipelineResVersionDao { creator = creator, version = version, versionName = versionName, - modelString = modelString + modelString = JsonUtil.toJson(model, formatted = false), + triggerString = JsonUtil.toJson(trigger, formatted = false), + modelVersion = modelVersion, + triggerVersion = triggerVersion, + settingVersion = settingVersion ) } @@ -69,24 +77,33 @@ class PipelineResVersionDao { creator: String, version: Int, versionName: String = "init", - modelString: String + modelString: String, + triggerString: String, + modelVersion: Int, + triggerVersion: Int, + settingVersion: Int ) { with(T_PIPELINE_RESOURCE_VERSION) { - dslContext.insertInto( - this, - PROJECT_ID, - PIPELINE_ID, - VERSION, - VERSION_NAME, - MODEL, - CREATOR, - CREATE_TIME - ).values(projectId, pipelineId, version, versionName, modelString, creator, LocalDateTime.now()) + dslContext.insertInto(this) + .set(PROJECT_ID, projectId) + .set(PIPELINE_ID, pipelineId) + .set(VERSION, version) + .set(VERSION_NAME, versionName) + .set(MODEL, modelString) + .set(TRIGGER, triggerString) + .set(CREATOR, creator) + .set(CREATE_TIME, LocalDateTime.now()) + .set(MODEL_VERSION, modelVersion) + .set(TRIGGER_VERSION, triggerVersion) + .set(SETTING_VERSION, settingVersion) .onDuplicateKeyUpdate() .set(MODEL, modelString) + .set(TRIGGER, triggerString) .set(CREATOR, creator) .set(VERSION_NAME, versionName) - .set(CREATE_TIME, LocalDateTime.now()) + .set(MODEL_VERSION, modelVersion) + .set(TRIGGER_VERSION, triggerVersion) + .set(SETTING_VERSION, settingVersion) .execute() } } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index 48bc03b0023..e14d86bb1b6 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -127,6 +127,14 @@ class PipelineRepositoryService constructor( private val redisOperation: RedisOperation ) { + companion object { + private const val MAX_LEN_FOR_NAME = 255 + private val logger = LoggerFactory.getLogger(PipelineRepositoryService::class.java) + private const val PIPELINE_SETTING_VERSION_BIZ_TAG_NAME = "PIPELINE_SETTING_VERSION" + private fun getVersionName(modelVersion: Int, triggerVersion: Int, settingVersion: Int) = + "P$modelVersion.T$triggerVersion.$settingVersion" + } + fun deployPipeline( model: Model, projectId: String, @@ -192,7 +200,8 @@ class PipelineRepositoryService constructor( buildNo = buildNo, modelTasks = modelTasks, useTemplateSettings = useTemplateSettings, - templateId = templateId + templateId = templateId, + trigger = triggerContainer ) } } @@ -466,6 +475,7 @@ class PipelineRepositoryService constructor( projectId: String, pipelineId: String, model: Model, + trigger: TriggerContainer, userId: String, channelCode: ChannelCode, canManualStartup: Boolean, @@ -498,21 +508,33 @@ class PipelineRepositoryService constructor( id = id ) model.latestVersion = 1 + // 最新版本永远是新增逻辑 pipelineResDao.create( dslContext = transactionContext, projectId = projectId, pipelineId = pipelineId, creator = userId, version = 1, - model = model + model = model, + trigger = trigger, + versionName = getVersionName(1, 1, 1), + modelVersion = 1, + triggerVersion = 1, + settingVersion = 1 ) + // 同步记录到历史版本表 pipelineResVersionDao.create( dslContext = transactionContext, projectId = projectId, pipelineId = pipelineId, creator = userId, version = 1, - model = model + model = model, + trigger = trigger, + versionName = getVersionName(1, 1, 1), + modelVersion = 1, + triggerVersion = 1, + settingVersion = 1 ) if (model.instanceFromTemplate != true) { if (null == pipelineSettingDao.getSetting(transactionContext, projectId, pipelineId)) { @@ -616,6 +638,7 @@ class PipelineRepositoryService constructor( updateLastModifyUser: Boolean? = true ): DeployPipelineResult { val taskCount: Int = model.taskCount() + val triggerContainer = model.stages[0].containers[0] as TriggerContainer var version = 0 val lock = PipelineModelLock(redisOperation, pipelineId) try { @@ -656,13 +679,17 @@ class PipelineRepositoryService constructor( throw ErrorCodeException(errorCode = ProcessMessageCode.ERROR_PIPELINE_IS_NOT_THE_LATEST) } model.latestVersion = version + val latestResRecord = pipelineResDao.getLatestVersionRecord( + transactionContext, projectId, pipelineId + ) pipelineResDao.create( dslContext = transactionContext, projectId = projectId, pipelineId = pipelineId, creator = userId, version = version, - model = model + model = model, + trigger = latestResRecord?. ) pipelineResVersionDao.create( dslContext = transactionContext, @@ -670,7 +697,8 @@ class PipelineRepositoryService constructor( pipelineId = pipelineId, creator = userId, version = version, - model = model + model = model, + trigger = triggerContainer ) if (version > 1 && pipelineResVersionDao.getVersionModelString( dslContext = transactionContext, @@ -1288,10 +1316,4 @@ class PipelineRepositoryService constructor( maxConRunningQueueSize = maxConRunningQueueSize ) } - - companion object { - private const val MAX_LEN_FOR_NAME = 255 - private val logger = LoggerFactory.getLogger(PipelineRepositoryService::class.java) - private const val PIPELINE_SETTING_VERSION_BIZ_TAG_NAME = "PIPELINE_SETTING_VERSION" - } } From df6f791408d461f8a84158be333a1331c0d8df2d Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 29 May 2023 00:20:30 +0800 Subject: [PATCH 002/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0=E7=9B=B8=E5=85=B3=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../apigw/v3/ApigwPipelineResourceV3Impl.kt | 2 +- .../apigw/v4/ApigwPipelineResourceV4Impl.kt | 2 +- .../api/service/ServicePipelineResource.kt | 37 +++++++- .../process/api/user/UserPipelineResource.kt | 43 ++++++++-- .../process/engine/pojo/PipelineResVersion.kt | 84 ++++++++++++++++++ .../pojo/setting/PipelineVersionSimple.kt | 14 ++- .../process/engine/dao/PipelineResDao.kt | 23 +++-- .../engine/dao/PipelineResVersionDao.kt | 54 +++++++----- .../service/PipelineRepositoryService.kt | 86 +++++++++++++++---- .../PipelineRepositoryVersionService.kt | 30 +++++-- .../api/ServicePipelineResourceImpl.kt | 28 +++++- .../process/api/UserPipelineResourceImpl.kt | 82 +++++++++++++----- .../service/PipelineVersionFacadeService.kt | 4 +- .../service/PipelineInfoFacadeService.kt | 25 ++++-- .../pipeline/PipelineSettingFacadeService.kt | 4 +- .../impl/AtomIndexTriggerCalServiceImpl.kt | 2 +- .../stream/service/StreamPipelineService.kt | 2 +- .../stream/trigger/StreamYamlBaseBuild.kt | 4 +- .../ticket/pojo/enums/CredentialType.kt | 18 ++-- 19 files changed, 436 insertions(+), 108 deletions(-) create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt diff --git a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v3/ApigwPipelineResourceV3Impl.kt b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v3/ApigwPipelineResourceV3Impl.kt index 7a7c4220718..4a535304283 100644 --- a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v3/ApigwPipelineResourceV3Impl.kt +++ b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v3/ApigwPipelineResourceV3Impl.kt @@ -90,7 +90,7 @@ class ApigwPipelineResourceV3Impl @Autowired constructor( pipeline: Model ): Result { logger.info("OPENAPI_PIPELINE_V3|$userId|edit|$projectId|$pipelineId") - return client.get(ServicePipelineResource::class).edit( + return client.get(ServicePipelineResource::class).editPipeline( userId = userId, projectId = projectId, pipelineId = pipelineId, diff --git a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/ApigwPipelineResourceV4Impl.kt b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/ApigwPipelineResourceV4Impl.kt index b63784c397d..0cbf0eb0f9a 100644 --- a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/ApigwPipelineResourceV4Impl.kt +++ b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/ApigwPipelineResourceV4Impl.kt @@ -92,7 +92,7 @@ class ApigwPipelineResourceV4Impl @Autowired constructor( pipeline: Model ): Result { logger.info("OPENAPI_PIPELINE_V4|$userId|edit|$projectId|$pipelineId") - return client.get(ServicePipelineResource::class).edit( + return client.get(ServicePipelineResource::class).editPipeline( userId = userId, projectId = projectId, pipelineId = pipelineId, diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt index 7797adca7cd..4db98fe1278 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt @@ -95,7 +95,7 @@ interface ServicePipelineResource { @PUT // @Path("/projects/{projectId}/pipelines/{pipelineId}/") @Path("/{projectId}/{pipelineId}/") - fun edit( + fun editPipeline( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) userId: String, @@ -113,7 +113,35 @@ interface ServicePipelineResource { @ApiParam("是否修改最后修改人", required = false) @QueryParam("updateLastModifyUser") @DefaultValue("true") - updateLastModifyUser: Boolean? = true + updateLastModifyUser: Boolean? = true, + @QueryParam("draft") + @DefaultValue("false") + saveDraft: Boolean? + ): Result + + @ApiOperation("编辑流水线配置") + @PUT + // @Path("/projects/{projectId}/pipelines/{pipelineId}/") + @Path("/{projectId}/{pipelineId}/setting") + fun editSetting( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String, + @ApiParam(value = "流水线设置", required = true) + @Valid + setting: PipelineSetting, + @ApiParam("渠道号,默认为BS", required = false) + @QueryParam("channelCode") + channelCode: ChannelCode, + @QueryParam("draft") + @DefaultValue("false") + saveDraft: Boolean? ): Result @ApiOperation("复制流水线编排") @@ -172,7 +200,10 @@ interface ServicePipelineResource { modelAndSetting: PipelineModelAndSetting, @ApiParam("渠道号,默认为BS", required = false) @QueryParam("channelCode") - channelCode: ChannelCode + channelCode: ChannelCode, + @QueryParam("draft") + @DefaultValue("false") + saveDraft: Boolean? ): Result @ApiOperation("获取流水线编排") diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt index 1402bec8696..b3fab07d94e 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt @@ -34,6 +34,7 @@ import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.pojo.MatrixPipelineInfo import com.tencent.devops.process.engine.pojo.PipelineInfo +import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.pojo.Permission import com.tencent.devops.process.pojo.Pipeline import com.tencent.devops.process.pojo.PipelineCollation @@ -57,6 +58,7 @@ import io.swagger.annotations.ApiParam import javax.validation.Valid import javax.ws.rs.Consumes import javax.ws.rs.DELETE +import javax.ws.rs.DefaultValue import javax.ws.rs.GET import javax.ws.rs.HeaderParam import javax.ws.rs.POST @@ -188,7 +190,7 @@ interface UserPipelineResource { @PUT // @Path("/projects/{projectId}/pipelines/{pipelineId}/") @Path("/{projectId}/{pipelineId}/") - fun edit( + fun editPipeline( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) userId: String, @@ -199,7 +201,32 @@ interface UserPipelineResource { @PathParam("pipelineId") pipelineId: String, @ApiParam(value = "流水线模型", required = true) - pipeline: Model + pipeline: Model, + @QueryParam("draft") + @DefaultValue("false") + saveDraft: Boolean? + ): Result + + @ApiOperation("编辑流水线配置") + @PUT + // @Path("/projects/{projectId}/pipelines/{pipelineId}/") + @Path("/{projectId}/{pipelineId}/setting") + fun editSetting( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String, + @ApiParam(value = "流水线设置", required = true) + @Valid + setting: PipelineSetting, + @QueryParam("draft") + @DefaultValue("false") + saveDraft: Boolean? ): Result @ApiOperation("编辑流水线编排以及设置") @@ -218,7 +245,10 @@ interface UserPipelineResource { pipelineId: String, @ApiParam(value = "流水线模型与设置", required = true) @Valid - modelAndSetting: PipelineModelAndSetting + modelAndSetting: PipelineModelAndSetting, + @QueryParam("draft") + @DefaultValue("false") + saveDraft: Boolean? ): Result @ApiOperation("保存流水线设置") @@ -252,7 +282,10 @@ interface UserPipelineResource { projectId: String, @ApiParam("流水线ID", required = true) @PathParam("pipelineId") - pipelineId: String + pipelineId: String, + @QueryParam("draft") + @DefaultValue("false") + includeDraft: Boolean? ): Result @ApiOperation("获取流水线编排版本") @@ -564,7 +597,7 @@ interface UserPipelineResource { @ApiParam("每页多少条", required = false, defaultValue = "20") @QueryParam("pageSize") pageSize: Int? - ): Result> + ): Result> @ApiOperation("校验matrix yaml格式") @POST diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt new file mode 100644 index 00000000000..0de581b4f75 --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt @@ -0,0 +1,84 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.engine.pojo + +import com.tencent.devops.common.pipeline.enums.ChannelCode +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty + +@ApiModel("流水线信息") +data class PipelineResVersion( + @ApiModelProperty("项目ID") + val projectId: String, + @ApiModelProperty("流水线DI") + val pipelineId: String, + @ApiModelProperty("模板ID") + val templateId: String?, + @ApiModelProperty("流水线名称") + val pipelineName: String, + @ApiModelProperty("流水线描述") + val pipelineDesc: String, + @ApiModelProperty("版本") + var version: Int = 1, + @ApiModelProperty("创建时间") + val createTime: Long = 0, + @ApiModelProperty("更新时间") + val updateTime: Long = 0, + @ApiModelProperty("创建者") + val creator: String, + @ApiModelProperty("上一次的更新者") + val lastModifyUser: String, + @ApiModelProperty("渠道号") + val channelCode: ChannelCode, + @ApiModelProperty("是否能够手动启动") + val canManualStartup: Boolean, + @ApiModelProperty("是否可以跳过") + val canElementSkip: Boolean, + @ApiModelProperty("任务数") + val taskCount: Int, + @ApiModelProperty("版本名称") + var versionName: String = "init", + @ApiModelProperty("ID") + val id: Long?, + @ApiModelProperty("流水线组名称列表", required = false) + var viewNames: List? = null, + @ApiModelProperty("关联构建记录总数", required = false) + val referCount: Int? = null, + @ApiModelProperty("编排版本号", required = false) + val modelVersion: Int? = null, + @ApiModelProperty("触发器版本号", required = false) + val triggerVersion: Int? = null, + @ApiModelProperty("配置版本号", required = false) + val settingVersion: Int? = null, + @ApiModelProperty("标识是否为草稿", required = false) + val draftFlag: Boolean? = null, + @ApiModelProperty("调试构建ID", required = false) + val debugBuildId: String? = null, + @ApiModelProperty("来源代码库标识(分支名)", required = false) + val pacRefs: String? = null +) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineVersionSimple.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineVersionSimple.kt index 324b222f968..a00ba31300f 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineVersionSimple.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineVersionSimple.kt @@ -45,5 +45,17 @@ data class PipelineVersionSimple( @ApiModelProperty("是否还有构建记录引用该版本标识", required = false) val referFlag: Boolean? = null, @ApiModelProperty("关联构建记录总数", required = false) - val referCount: Int? = null + val referCount: Int? = null, + @ApiModelProperty("编排版本号", required = false) + val modelVersion: Int? = null, + @ApiModelProperty("触发器版本号", required = false) + val triggerVersion: Int? = null, + @ApiModelProperty("配置版本号", required = false) + val settingVersion: Int? = null, + @ApiModelProperty("标识是否为草稿", required = false) + val draftFlag: Boolean? = null, + @ApiModelProperty("调试构建ID", required = false) + val debugBuildId: String? = null, + @ApiModelProperty("来源代码库标识(分支名)", required = false) + val pacRefs: String? = null ) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt index 53481ab4d2b..32baf6858fb 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt @@ -52,7 +52,7 @@ class PipelineResDao { pipelineId: String, creator: String, version: Int, - versionName: String = "init", + versionName: String, model: Model, trigger: TriggerContainer, modelVersion: Int, @@ -87,7 +87,11 @@ class PipelineResDao { } } - fun getLatestVersionRecord(dslContext: DSLContext, projectId: String, pipelineId: String): TPipelineResourceRecord? { + fun getLatestVersionRecord( + dslContext: DSLContext, + projectId: String, + pipelineId: String + ): TPipelineResourceRecord? { return with(T_PIPELINE_RESOURCE) { dslContext.selectFrom(this) .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) @@ -95,14 +99,23 @@ class PipelineResDao { } } - fun getLatestVersionModelString(dslContext: DSLContext, projectId: String, pipelineId: String) = - getVersionModelString(dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, version = null) + fun getLatestVersionModelString( + dslContext: DSLContext, + projectId: String, + pipelineId: String + ) = getVersionModelString( + dslContext = dslContext, + projectId = projectId, + pipelineId = pipelineId, + version = null + ) fun getVersionModelString( dslContext: DSLContext, projectId: String, pipelineId: String, - version: Int? + version: Int?, + includeDraft: Boolean? = false ): String? { return with(T_PIPELINE_RESOURCE) { diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt index 68b2b918025..7291a86e573 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt @@ -51,9 +51,10 @@ class PipelineResVersionDao { versionName: String, model: Model, trigger: TriggerContainer, - modelVersion: Int, - triggerVersion: Int, - settingVersion: Int + modelVersion: Int?, + triggerVersion: Int?, + settingVersion: Int?, + draftFlag: Boolean ) { create( dslContext = dslContext, @@ -66,7 +67,8 @@ class PipelineResVersionDao { triggerString = JsonUtil.toJson(trigger, formatted = false), modelVersion = modelVersion, triggerVersion = triggerVersion, - settingVersion = settingVersion + settingVersion = settingVersion, + draftFlag = draftFlag ) } @@ -78,10 +80,11 @@ class PipelineResVersionDao { version: Int, versionName: String = "init", modelString: String, - triggerString: String, - modelVersion: Int, - triggerVersion: Int, - settingVersion: Int + triggerString: String?, + modelVersion: Int?, + triggerVersion: Int?, + settingVersion: Int?, + draftFlag: Boolean ) { with(T_PIPELINE_RESOURCE_VERSION) { dslContext.insertInto(this) @@ -96,6 +99,7 @@ class PipelineResVersionDao { .set(MODEL_VERSION, modelVersion) .set(TRIGGER_VERSION, triggerVersion) .set(SETTING_VERSION, settingVersion) + .set(DRAFT_FLAG, draftFlag) .onDuplicateKeyUpdate() .set(MODEL, modelString) .set(TRIGGER, triggerString) @@ -112,7 +116,8 @@ class PipelineResVersionDao { dslContext: DSLContext, projectId: String, pipelineId: String, - version: Int? + version: Int?, + includeDraft: Boolean? = null ): String? { return with(T_PIPELINE_RESOURCE_VERSION) { @@ -122,6 +127,8 @@ class PipelineResVersionDao { if (version != null) { where.and(VERSION.eq(version)) } else { + // 非新的逻辑请求则保持旧逻辑 + if (includeDraft != true) where.and(DRAFT_FLAG.ne(true)) where.orderBy(VERSION.desc()).limit(1) } where.fetchAny(0, String::class.java) @@ -164,23 +171,30 @@ class PipelineResVersionDao { ): List { val list = mutableListOf() with(T_PIPELINE_RESOURCE_VERSION) { - val result = dslContext.select(CREATE_TIME, CREATOR, VERSION_NAME, VERSION, REFER_FLAG, REFER_COUNT) - .from(this) + val result = dslContext.selectFrom(this) .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) .orderBy(VERSION.desc()) .limit(limit).offset(offset) .fetch() result.forEach { - list.add(PipelineVersionSimple( - pipelineId = pipelineId, - creator = it[CREATOR] ?: "unknown", - createTime = it.get(CREATE_TIME)?.timestampmilli() ?: 0, - version = it[VERSION] ?: 1, - versionName = it[VERSION_NAME] ?: "init", - referFlag = it[REFER_FLAG], - referCount = it[REFER_COUNT] - )) + list.add( + PipelineVersionSimple( + pipelineId = pipelineId, + creator = it.creator ?: "unknown", + createTime = it.createTime?.timestampmilli() ?: 0, + version = it.version ?: 1, + versionName = it.versionName ?: "init", + referFlag = it.referFlag, + referCount = it.referCount, + modelVersion = it.modelVersion, + triggerVersion = it.triggerVersion, + settingVersion = it.settingVersion, + draftFlag = it.draftFlag, + debugBuildId = it.debugBuildId, + pacRefs = it.pacRefs + ) + ) } } return list diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index e14d86bb1b6..c338f0b3bc0 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -131,8 +131,15 @@ class PipelineRepositoryService constructor( private const val MAX_LEN_FOR_NAME = 255 private val logger = LoggerFactory.getLogger(PipelineRepositoryService::class.java) private const val PIPELINE_SETTING_VERSION_BIZ_TAG_NAME = "PIPELINE_SETTING_VERSION" - private fun getVersionName(modelVersion: Int, triggerVersion: Int, settingVersion: Int) = - "P$modelVersion.T$triggerVersion.$settingVersion" + private fun getVersionName( + modelVersion: Int?, + triggerVersion: Int?, + settingVersion: Int? + ): String { + return if (modelVersion == null || triggerVersion == null || settingVersion == null) { + "init" + } else "P$modelVersion.T$triggerVersion.$settingVersion" + } } fun deployPipeline( @@ -144,7 +151,8 @@ class PipelineRepositoryService constructor( create: Boolean, useTemplateSettings: Boolean? = false, templateId: String? = null, - updateLastModifyUser: Boolean? = true + updateLastModifyUser: Boolean? = true, + saveDraft: Boolean? = false ): DeployPipelineResult { // 生成流水线ID,新流水线以p-开头,以区分以前旧数据 @@ -186,7 +194,8 @@ class PipelineRepositoryService constructor( modelTasks = modelTasks, channelCode = channelCode, maxPipelineResNum = pipelineSetting?.maxPipelineResNum, - updateLastModifyUser = updateLastModifyUser + updateLastModifyUser = updateLastModifyUser, + saveDraft = saveDraft ) } else { create( @@ -201,7 +210,8 @@ class PipelineRepositoryService constructor( modelTasks = modelTasks, useTemplateSettings = useTemplateSettings, templateId = templateId, - trigger = triggerContainer + trigger = triggerContainer, + saveDraft = saveDraft ) } } @@ -483,7 +493,8 @@ class PipelineRepositoryService constructor( buildNo: BuildNo?, modelTasks: Collection, useTemplateSettings: Boolean? = false, - templateId: String? = null + templateId: String? = null, + saveDraft: Boolean? = false ): DeployPipelineResult { val taskCount: Int = model.taskCount() @@ -508,8 +519,8 @@ class PipelineRepositoryService constructor( id = id ) model.latestVersion = 1 - // 最新版本永远是新增逻辑 - pipelineResDao.create( + // 如果不是草稿保存,最新版本永远是新增逻辑 + if (saveDraft != true) pipelineResDao.create( dslContext = transactionContext, projectId = projectId, pipelineId = pipelineId, @@ -534,7 +545,8 @@ class PipelineRepositoryService constructor( versionName = getVersionName(1, 1, 1), modelVersion = 1, triggerVersion = 1, - settingVersion = 1 + settingVersion = 1, + draftFlag = saveDraft == true ) if (model.instanceFromTemplate != true) { if (null == pipelineSettingDao.getSetting(transactionContext, projectId, pipelineId)) { @@ -635,7 +647,8 @@ class PipelineRepositoryService constructor( modelTasks: Collection, channelCode: ChannelCode, maxPipelineResNum: Int? = null, - updateLastModifyUser: Boolean? = true + updateLastModifyUser: Boolean? = true, + saveDraft: Boolean? = false ): DeployPipelineResult { val taskCount: Int = model.taskCount() val triggerContainer = model.stages[0].containers[0] as TriggerContainer @@ -679,17 +692,26 @@ class PipelineRepositoryService constructor( throw ErrorCodeException(errorCode = ProcessMessageCode.ERROR_PIPELINE_IS_NOT_THE_LATEST) } model.latestVersion = version + // 如果不是草稿保存,最新版本永远是新增逻辑 + // TODO #8161 根据差异对比进行小版本号计算 val latestResRecord = pipelineResDao.getLatestVersionRecord( transactionContext, projectId, pipelineId ) - pipelineResDao.create( + val modelVersion = 1 + val triggerVersion = 1 + val settingVersion = 1 + if (saveDraft != true) pipelineResDao.create( dslContext = transactionContext, projectId = projectId, pipelineId = pipelineId, creator = userId, version = version, model = model, - trigger = latestResRecord?. + trigger = triggerContainer, + versionName = getVersionName(modelVersion, triggerVersion, settingVersion), + modelVersion = modelVersion, + triggerVersion = triggerVersion, + settingVersion = settingVersion ) pipelineResVersionDao.create( dslContext = transactionContext, @@ -698,8 +720,14 @@ class PipelineRepositoryService constructor( creator = userId, version = version, model = model, - trigger = triggerContainer + trigger = triggerContainer, + versionName = getVersionName(modelVersion, triggerVersion, settingVersion), + modelVersion = modelVersion, + triggerVersion = triggerVersion, + settingVersion = settingVersion, + draftFlag = saveDraft == true ) + // 针对新增version表做的数据迁移 if (version > 1 && pipelineResVersionDao.getVersionModelString( dslContext = transactionContext, projectId = projectId, @@ -715,13 +743,25 @@ class PipelineRepositoryService constructor( version = version - 1 ) if (!lastVersionModelStr.isNullOrEmpty()) { + val triggerStr = try { + val trigger = str2model(lastVersionModelStr, pipelineId) + ?.stages?.get(0)?.containers?.get(0) as TriggerContainer + JsonUtil.toJson(trigger, false) + } catch (ignore: Throwable) { + null + } pipelineResVersionDao.create( dslContext = transactionContext, projectId = projectId, pipelineId = pipelineId, creator = userId, version = version - 1, - modelString = lastVersionModelStr + modelString = lastVersionModelStr, + triggerString = triggerStr, + modelVersion = null, + triggerVersion = null, + settingVersion = null, + draftFlag = false ) } } @@ -803,17 +843,29 @@ class PipelineRepositoryService constructor( ).map { it.key to str2model(it.value, it.key) }.toMap() } - fun getModel(projectId: String, pipelineId: String, version: Int? = null): Model? { + fun getModel( + projectId: String, + pipelineId: String, + version: Int? = null, + includeDraft: Boolean? = false + ): Model? { var modelString: String? if (version == null) { // 取最新版,直接从旧版本表读 modelString = pipelineResDao.getVersionModelString( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, - version = version + version = null, + includeDraft = includeDraft ) ?: return null } else { - modelString = pipelineResVersionDao.getVersionModelString(dslContext, projectId, pipelineId, version) + modelString = pipelineResVersionDao.getVersionModelString( + dslContext = dslContext, + projectId = projectId, + pipelineId = pipelineId, + version = version, + includeDraft = includeDraft + ) if (modelString.isNullOrBlank()) { // 兼容处理:取不到再从旧的版本表取 modelString = pipelineResDao.getVersionModelString( diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt index 0e1cda236e5..26aa1ab3026 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt @@ -35,6 +35,7 @@ import com.tencent.devops.process.engine.control.lock.PipelineVersionLock import com.tencent.devops.process.engine.dao.PipelineBuildDao import com.tencent.devops.process.engine.dao.PipelineResVersionDao import com.tencent.devops.process.engine.pojo.PipelineInfo +import com.tencent.devops.process.engine.pojo.PipelineResVersion import org.jooq.DSLContext import org.jooq.impl.DSL import org.springframework.stereotype.Service @@ -112,7 +113,7 @@ class PipelineRepositoryVersionService( pipelineId: String, offset: Int, limit: Int - ): Pair> { + ): Pair> { if (pipelineInfo == null) { return Pair(0, emptyList()) } @@ -125,15 +126,32 @@ class PipelineRepositoryVersionService( offset = offset, limit = limit ) - val list = mutableListOf() + val list = mutableListOf() result.forEach { list.add( - pipelineInfo.copy( - createTime = it.createTime, - creator = it.creator, + PipelineResVersion( + createTime = pipelineInfo.createTime, + creator = pipelineInfo.creator, + canElementSkip = pipelineInfo.canElementSkip, + canManualStartup = pipelineInfo.canManualStartup, + channelCode = pipelineInfo.channelCode, + id = pipelineInfo.id, + lastModifyUser = pipelineInfo.lastModifyUser, + pipelineDesc = pipelineInfo.pipelineDesc, + pipelineId = pipelineInfo.pipelineId, + pipelineName = pipelineInfo.pipelineName, + projectId = pipelineInfo.projectId, + taskCount = pipelineInfo.taskCount, + templateId = pipelineInfo.templateId, version = it.version, - versionName = it.versionName + versionName = it.versionName, + modelVersion = it.modelVersion, + triggerVersion = it.triggerVersion, + settingVersion = it.settingVersion, + draftFlag = it.draftFlag, + debugBuildId = it.debugBuildId, + pacRefs = it.pacRefs ) ) } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt index 8e684f8e884..e7f3eeeca04 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt @@ -114,13 +114,14 @@ class ServicePipelineResourceImpl @Autowired constructor( ) } - override fun edit( + override fun editPipeline( userId: String, projectId: String, pipelineId: String, pipeline: Model, channelCode: ChannelCode, - updateLastModifyUser: Boolean? + updateLastModifyUser: Boolean?, + saveDraft: Boolean? ): Result { checkParams(userId, projectId) val deployPipelineResult = pipelineInfoFacadeService.editPipeline( @@ -146,6 +147,25 @@ class ServicePipelineResourceImpl @Autowired constructor( return Result(true) } + override fun editSetting( + userId: String, + projectId: String, + pipelineId: String, + setting: PipelineSetting, + channelCode: ChannelCode, + saveDraft: Boolean? + ): Result { + // TODO #8161 单独保存设置的鉴权 + pipelineSettingFacadeService.saveSetting( + userId = userId, + setting = setting, + checkPermission = false, + dispatchPipelineUpdateEvent = false, + saveDraft = saveDraft + ) + return Result(true) + } + override fun copy( userId: String, projectId: String, @@ -210,7 +230,8 @@ class ServicePipelineResourceImpl @Autowired constructor( projectId: String, pipelineId: String, modelAndSetting: PipelineModelAndSetting, - channelCode: ChannelCode + channelCode: ChannelCode, + saveDraft: Boolean? ): Result { modelAndSetting.setting.checkParam() val buildNumRule = modelAndSetting.setting.buildNumRule @@ -223,6 +244,7 @@ class ServicePipelineResourceImpl @Autowired constructor( pipelineId = pipelineId, model = modelAndSetting.model, setting = modelAndSetting.setting, + saveDraft = saveDraft, channelCode = ChannelCode.BS ) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index f9548968418..4bcfaf0d488 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -43,6 +43,7 @@ import com.tencent.devops.process.api.user.UserPipelineResource import com.tencent.devops.process.audit.service.AuditService import com.tencent.devops.process.constant.ProcessMessageCode import com.tencent.devops.process.engine.pojo.PipelineInfo +import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.engine.service.PipelineVersionFacadeService import com.tencent.devops.process.engine.service.rule.PipelineRuleService import com.tencent.devops.process.permission.PipelinePermissionService @@ -237,13 +238,20 @@ class UserPipelineResourceImpl @Autowired constructor( return Result(pid) } - override fun edit(userId: String, projectId: String, pipelineId: String, pipeline: Model): Result { + override fun editPipeline( + userId: String, + projectId: String, + pipelineId: String, + pipeline: Model, + saveDraft: Boolean? + ): Result { checkParam(userId, projectId) val pipelineResult = pipelineInfoFacadeService.editPipeline( userId = userId, projectId = projectId, pipelineId = pipelineId, model = pipeline, + saveDraft = saveDraft, channelCode = ChannelCode.BS ) auditService.createAudit( @@ -260,11 +268,30 @@ class UserPipelineResourceImpl @Autowired constructor( return Result(true) } + override fun editSetting( + userId: String, + projectId: String, + pipelineId: String, + setting: PipelineSetting, + saveDraft: Boolean? + ): Result { + // TODO #8161 单独保存设置的鉴权 + pipelineSettingFacadeService.saveSetting( + userId = userId, + setting = setting, + checkPermission = false, + dispatchPipelineUpdateEvent = false, + saveDraft = saveDraft + ) + return Result(true) + } + override fun saveAll( userId: String, projectId: String, pipelineId: String, - modelAndSetting: PipelineModelAndSetting + modelAndSetting: PipelineModelAndSetting, + saveDraft: Boolean? ): Result { checkParam(userId, projectId) modelAndSetting.setting.checkParam() @@ -278,6 +305,7 @@ class UserPipelineResourceImpl @Autowired constructor( pipelineId = pipelineId, model = modelAndSetting.model, setting = modelAndSetting.setting, + saveDraft = saveDraft, channelCode = ChannelCode.BS ) auditService.createAudit( @@ -328,12 +356,18 @@ class UserPipelineResourceImpl @Autowired constructor( return Result(true) } - override fun get(userId: String, projectId: String, pipelineId: String): Result { + override fun get( + userId: String, + projectId: String, + pipelineId: String, + includeDraft: Boolean? + ): Result { checkParam(userId, projectId) val pipeline = pipelineInfoFacadeService.getPipeline( userId = userId, projectId = projectId, pipelineId = pipelineId, + includeDraft = includeDraft, channelCode = ChannelCode.BS ) pipelineRecentUseService.record(userId, projectId, pipelineId) @@ -408,7 +442,7 @@ class UserPipelineResourceImpl @Autowired constructor( val result = pipelineIds.associateWith { try { softDelete(userId, batchDeletePipeline.projectId, it).data ?: false - } catch (e: Exception) { + } catch (ignore: Exception) { false } } @@ -560,24 +594,26 @@ class UserPipelineResourceImpl @Autowired constructor( checkParam(userId, projectId) val status = pipelineListFacadeService.getPipelineStatus(userId, projectId, pipelines) val currentTimestamp = System.currentTimeMillis() - return Result(status.associate { - it.pipelineId to PipelineStatus( - taskCount = it.taskCount, - buildCount = it.buildCount, - lock = it.lock, - canManualStartup = it.canManualStartup, - latestBuildStartTime = it.latestBuildStartTime, - latestBuildEndTime = it.latestBuildEndTime, - latestBuildStatus = it.latestBuildStatus, - latestBuildNum = it.latestBuildNum, - latestBuildTaskName = it.latestBuildTaskName, - latestBuildEstimatedExecutionSeconds = it.latestBuildEstimatedExecutionSeconds, - latestBuildId = it.latestBuildId, - currentTimestamp = currentTimestamp, - runningBuildCount = it.runningBuildCount, - hasCollect = it.hasCollect - ) - }) + return Result( + status.associate { + it.pipelineId to PipelineStatus( + taskCount = it.taskCount, + buildCount = it.buildCount, + lock = it.lock, + canManualStartup = it.canManualStartup, + latestBuildStartTime = it.latestBuildStartTime, + latestBuildEndTime = it.latestBuildEndTime, + latestBuildStatus = it.latestBuildStatus, + latestBuildNum = it.latestBuildNum, + latestBuildTaskName = it.latestBuildTaskName, + latestBuildEstimatedExecutionSeconds = it.latestBuildEstimatedExecutionSeconds, + latestBuildId = it.latestBuildId, + currentTimestamp = currentTimestamp, + runningBuildCount = it.runningBuildCount, + hasCollect = it.hasCollect + ) + } + ) } override fun getStageTag(userId: String): Result> { @@ -634,7 +670,7 @@ class UserPipelineResourceImpl @Autowired constructor( pipelineId: String, page: Int?, pageSize: Int? - ): Result> { + ): Result> { checkParam(userId, projectId) return Result( pipelineVersionFacadeService.listPipelineVersion( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt index d4b8b5d2ee0..413e1207c2c 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt @@ -30,7 +30,7 @@ package com.tencent.devops.process.engine.service import com.tencent.devops.common.api.model.SQLLimit import com.tencent.devops.common.api.util.PageUtil import com.tencent.devops.common.auth.api.AuthPermission -import com.tencent.devops.process.engine.pojo.PipelineInfo +import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.permission.PipelinePermissionService import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import org.springframework.beans.factory.annotation.Autowired @@ -74,7 +74,7 @@ class PipelineVersionFacadeService @Autowired constructor( pipelineId: String, page: Int?, pageSize: Int? - ): PipelineViewPipelinePage { + ): PipelineViewPipelinePage { val pageNotNull = page ?: 0 val pageSizeNotNull = pageSize ?: -1 var slqLimit: SQLLimit? = null diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index 185b3935d07..e4f335c81bf 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -595,7 +595,8 @@ class PipelineInfoFacadeService @Autowired constructor( channelCode: ChannelCode, checkPermission: Boolean = true, checkTemplate: Boolean = true, - updateLastModifyUser: Boolean? = true + updateLastModifyUser: Boolean? = true, + saveDraft: Boolean? = false ): DeployPipelineResult { if (checkTemplate && templateService.isTemplatePipeline(projectId, pipelineId)) { throw ErrorCodeException( @@ -669,7 +670,8 @@ class PipelineInfoFacadeService @Autowired constructor( userId = userId, channelCode = channelCode, create = false, - updateLastModifyUser = updateLastModifyUser + updateLastModifyUser = updateLastModifyUser, + saveDraft = saveDraft ) if (checkPermission) { pipelinePermissionService.modifyResource(projectId, pipelineId, model.name) @@ -708,7 +710,8 @@ class PipelineInfoFacadeService @Autowired constructor( setting: PipelineSetting, channelCode: ChannelCode, checkPermission: Boolean = true, - checkTemplate: Boolean = true + checkTemplate: Boolean = true, + saveDraft: Boolean? = false ): DeployPipelineResult { val pipelineResult = editPipeline( userId = userId, @@ -717,7 +720,8 @@ class PipelineInfoFacadeService @Autowired constructor( model = model, channelCode = channelCode, checkPermission = checkPermission, - checkTemplate = checkTemplate + checkTemplate = checkTemplate, + saveDraft = saveDraft ) if (setting.projectId.isBlank()) { setting.projectId = projectId @@ -728,7 +732,8 @@ class PipelineInfoFacadeService @Autowired constructor( setting = setting, checkPermission = false, version = pipelineResult.version, - dispatchPipelineUpdateEvent = false + dispatchPipelineUpdateEvent = false, + saveDraft = saveDraft ) return pipelineResult } @@ -739,7 +744,8 @@ class PipelineInfoFacadeService @Autowired constructor( pipelineId: String, channelCode: ChannelCode, version: Int? = null, - checkPermission: Boolean = true + checkPermission: Boolean = true, + includeDraft: Boolean? = false ): Model { if (checkPermission) { pipelinePermissionService.validPipelinePermission( @@ -767,7 +773,12 @@ class PipelineInfoFacadeService @Autowired constructor( ) } - val model = pipelineRepositoryService.getModel(projectId, pipelineId, version) + val model = pipelineRepositoryService.getModel( + projectId = projectId, + pipelineId = pipelineId, + version = version, + includeDraft = includeDraft + ) ?: throw ErrorCodeException( statusCode = Response.Status.NOT_FOUND.statusCode, errorCode = ProcessMessageCode.ERROR_PIPELINE_MODEL_NOT_EXISTS, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt index 0229a3ad2ee..7b016939c54 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt @@ -85,8 +85,10 @@ class PipelineSettingFacadeService @Autowired constructor( version: Int = 0, updateLastModifyUser: Boolean? = true, dispatchPipelineUpdateEvent: Boolean = true, - updateLabels: Boolean = true + updateLabels: Boolean = true, + saveDraft: Boolean? = false ): String { + // TODO #8161 增加配置的版本管理 if (checkPermission) { checkEditPermission( userId = userId, diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomIndexTriggerCalServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomIndexTriggerCalServiceImpl.kt index 5d1c3044977..36006b413d6 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomIndexTriggerCalServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/AtomIndexTriggerCalServiceImpl.kt @@ -126,7 +126,7 @@ class AtomIndexTriggerCalServiceImpl @Autowired constructor( // 修改插件的版本号 updateModelVersion(model, atomCode, version) // 修改插件对应的指标计算流水线模型 - client.get(ServicePipelineResource::class).edit( + client.get(ServicePipelineResource::class).editPipeline( userId = userId, projectId = initProjectCode, pipelineId = pipelineId, diff --git a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/service/StreamPipelineService.kt b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/service/StreamPipelineService.kt index 0c090dcec5d..268772165e2 100644 --- a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/service/StreamPipelineService.kt +++ b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/service/StreamPipelineService.kt @@ -505,7 +505,7 @@ class StreamPipelineService @Autowired constructor( model: Model ): Boolean? { try { - val response = processClient.edit( + val response = processClient.editPipeline( userId = userId, projectId = GitCommonUtils.getCiProjectId(gitProjectId, gitConfig.getScmType()), pipelineId = pipelineId, diff --git a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlBaseBuild.kt b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlBaseBuild.kt index 47afa36e896..3d7d210cc60 100644 --- a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlBaseBuild.kt +++ b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlBaseBuild.kt @@ -154,7 +154,7 @@ class StreamYamlBaseBuild @Autowired constructor( // md5不一致时更新蓝盾的model if (oldMd5 != md5) { // 编辑流水线model - processClient.edit( + processClient.editPipeline( userId = userId, projectId = projectCode, pipelineId = pipeline.pipelineId, @@ -180,7 +180,7 @@ class StreamYamlBaseBuild @Autowired constructor( } } else { // 编辑流水线model - processClient.edit( + processClient.editPipeline( userId = userId, projectId = projectCode, pipelineId = pipeline.pipelineId, diff --git a/src/backend/ci/core/ticket/api-ticket/src/main/kotlin/com/tencent/devops/ticket/pojo/enums/CredentialType.kt b/src/backend/ci/core/ticket/api-ticket/src/main/kotlin/com/tencent/devops/ticket/pojo/enums/CredentialType.kt index 7778b446008..d007061ece0 100644 --- a/src/backend/ci/core/ticket/api-ticket/src/main/kotlin/com/tencent/devops/ticket/pojo/enums/CredentialType.kt +++ b/src/backend/ci/core/ticket/api-ticket/src/main/kotlin/com/tencent/devops/ticket/pojo/enums/CredentialType.kt @@ -28,15 +28,15 @@ package com.tencent.devops.ticket.pojo.enums enum class CredentialType { - PASSWORD, // v1 = password, v2=v3=v4=null - ACCESSTOKEN, // v1 = access_token - OAUTHTOKEN, // v1 = oauth_token - USERNAME_PASSWORD, // v1 = username, v2 = password, other = null - SECRETKEY, // v1 = secretKey, other = null - APPID_SECRETKEY, // v1 = appId, v2 = secretKey, other = null - SSH_PRIVATEKEY, // v1 = privateKey, v2=passphrase? - TOKEN_SSH_PRIVATEKEY, // v1 = token, v2 = privateKey, v3=passphrase? - TOKEN_USERNAME_PASSWORD, // v1 = token, v2 = username, v3=password + PASSWORD, // v1 = password, v2=v3=v4=null + ACCESSTOKEN, // v1 = access_token + OAUTHTOKEN, // v1 = oauth_token + USERNAME_PASSWORD, // v1 = username, v2 = password, other = null + SECRETKEY, // v1 = secretKey, other = null + APPID_SECRETKEY, // v1 = appId, v2 = secretKey, other = null + SSH_PRIVATEKEY, // v1 = privateKey, v2=passphrase? + TOKEN_SSH_PRIVATEKEY, // v1 = token, v2 = privateKey, v3=passphrase? + TOKEN_USERNAME_PASSWORD, // v1 = token, v2 = username, v3=password COS_APPID_SECRETID_SECRETKEY_REGION, // v1 = cosappId, v2 = secretId, v3 = secretKey, v4 = region MULTI_LINE_PASSWORD; // 密码中有换行符 v1 = password, v2=v3=v4=null From 35acc78b4e49dc30c055721367eaf1e5ed340ad5 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 29 May 2023 11:12:36 +0800 Subject: [PATCH 003/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/engine/dao/PipelineResDao.kt | 40 ++++++++++++------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt index 32baf6858fb..9340662f482 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt @@ -63,26 +63,38 @@ class PipelineResDao { with(T_PIPELINE_RESOURCE) { val modelString = JsonUtil.toJson(model, formatted = false) val triggerString = JsonUtil.toJson(trigger, formatted = false) - dslContext.insertInto(this) - .set(PROJECT_ID, projectId) - .set(PIPELINE_ID, pipelineId) - .set(VERSION, version) - .set(VERSION_NAME, versionName) + dslContext.insertInto( + this, + PROJECT_ID, + PIPELINE_ID, + VERSION, + MODEL, + TRIGGER, + CREATOR, + CREATE_TIME, + VERSION_NAME, + MODEL_VERSION, + TRIGGER_VERSION, + SETTING_VERSION + ).values( + projectId, + pipelineId, + version, + modelString, + triggerString, + creator, + LocalDateTime.now(), + versionName, + modelVersion, + triggerVersion, + settingVersion + ).onDuplicateKeyUpdate() .set(MODEL, modelString) - .set(TRIGGER, triggerString) .set(CREATOR, creator) .set(CREATE_TIME, LocalDateTime.now()) .set(MODEL_VERSION, modelVersion) .set(TRIGGER_VERSION, triggerVersion) .set(SETTING_VERSION, settingVersion) - .onDuplicateKeyUpdate() - .set(MODEL, modelString) - .set(TRIGGER, triggerString) - .set(CREATOR, creator) - .set(VERSION_NAME, versionName) - .set(MODEL_VERSION, modelVersion) - .set(TRIGGER_VERSION, triggerVersion) - .set(SETTING_VERSION, settingVersion) .execute() } } From f7799454c515c53f48d588be2869f19dfda60ed7 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 29 May 2023 11:26:12 +0800 Subject: [PATCH 004/852] =?UTF-8?q?Revert=20"feat=EF=BC=9A=E6=B5=81?= =?UTF-8?q?=E6=B0=B4=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA?= =?UTF-8?q?=E5=88=B6=20#8161"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 35acc78b4e49dc30c055721367eaf1e5ed340ad5. --- .../process/engine/dao/PipelineResDao.kt | 40 +++++++------------ 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt index 9340662f482..32baf6858fb 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt @@ -63,38 +63,26 @@ class PipelineResDao { with(T_PIPELINE_RESOURCE) { val modelString = JsonUtil.toJson(model, formatted = false) val triggerString = JsonUtil.toJson(trigger, formatted = false) - dslContext.insertInto( - this, - PROJECT_ID, - PIPELINE_ID, - VERSION, - MODEL, - TRIGGER, - CREATOR, - CREATE_TIME, - VERSION_NAME, - MODEL_VERSION, - TRIGGER_VERSION, - SETTING_VERSION - ).values( - projectId, - pipelineId, - version, - modelString, - triggerString, - creator, - LocalDateTime.now(), - versionName, - modelVersion, - triggerVersion, - settingVersion - ).onDuplicateKeyUpdate() + dslContext.insertInto(this) + .set(PROJECT_ID, projectId) + .set(PIPELINE_ID, pipelineId) + .set(VERSION, version) + .set(VERSION_NAME, versionName) .set(MODEL, modelString) + .set(TRIGGER, triggerString) .set(CREATOR, creator) .set(CREATE_TIME, LocalDateTime.now()) .set(MODEL_VERSION, modelVersion) .set(TRIGGER_VERSION, triggerVersion) .set(SETTING_VERSION, settingVersion) + .onDuplicateKeyUpdate() + .set(MODEL, modelString) + .set(TRIGGER, triggerString) + .set(CREATOR, creator) + .set(VERSION_NAME, versionName) + .set(MODEL_VERSION, modelVersion) + .set(TRIGGER_VERSION, triggerVersion) + .set(SETTING_VERSION, settingVersion) .execute() } } From 8cbf0f450c215614afa445b6212fc1cf7c8f572b Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 29 May 2023 12:23:06 +0800 Subject: [PATCH 005/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/service/ServicePipelineResource.kt | 25 ------------------- .../process/api/user/UserPipelineResource.kt | 22 ---------------- .../api/ServicePipelineResourceImpl.kt | 19 -------------- .../process/api/UserPipelineResourceImpl.kt | 18 ------------- 4 files changed, 84 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt index 4db98fe1278..9ec048b2880 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt @@ -119,31 +119,6 @@ interface ServicePipelineResource { saveDraft: Boolean? ): Result - @ApiOperation("编辑流水线配置") - @PUT - // @Path("/projects/{projectId}/pipelines/{pipelineId}/") - @Path("/{projectId}/{pipelineId}/setting") - fun editSetting( - @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) - @HeaderParam(AUTH_HEADER_USER_ID) - userId: String, - @ApiParam("项目ID", required = true) - @PathParam("projectId") - projectId: String, - @ApiParam("流水线ID", required = true) - @PathParam("pipelineId") - pipelineId: String, - @ApiParam(value = "流水线设置", required = true) - @Valid - setting: PipelineSetting, - @ApiParam("渠道号,默认为BS", required = false) - @QueryParam("channelCode") - channelCode: ChannelCode, - @QueryParam("draft") - @DefaultValue("false") - saveDraft: Boolean? - ): Result - @ApiOperation("复制流水线编排") @POST @Path("/{projectId}/{pipelineId}/copy") diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt index b3fab07d94e..8238a8d24e0 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt @@ -207,28 +207,6 @@ interface UserPipelineResource { saveDraft: Boolean? ): Result - @ApiOperation("编辑流水线配置") - @PUT - // @Path("/projects/{projectId}/pipelines/{pipelineId}/") - @Path("/{projectId}/{pipelineId}/setting") - fun editSetting( - @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) - @HeaderParam(AUTH_HEADER_USER_ID) - userId: String, - @ApiParam("项目ID", required = true) - @PathParam("projectId") - projectId: String, - @ApiParam("流水线ID", required = true) - @PathParam("pipelineId") - pipelineId: String, - @ApiParam(value = "流水线设置", required = true) - @Valid - setting: PipelineSetting, - @QueryParam("draft") - @DefaultValue("false") - saveDraft: Boolean? - ): Result - @ApiOperation("编辑流水线编排以及设置") @POST // @Path("/projects/{projectId}/pipelines/{pipelineId}/saveAll") diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt index e7f3eeeca04..f25a0eb615e 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt @@ -147,25 +147,6 @@ class ServicePipelineResourceImpl @Autowired constructor( return Result(true) } - override fun editSetting( - userId: String, - projectId: String, - pipelineId: String, - setting: PipelineSetting, - channelCode: ChannelCode, - saveDraft: Boolean? - ): Result { - // TODO #8161 单独保存设置的鉴权 - pipelineSettingFacadeService.saveSetting( - userId = userId, - setting = setting, - checkPermission = false, - dispatchPipelineUpdateEvent = false, - saveDraft = saveDraft - ) - return Result(true) - } - override fun copy( userId: String, projectId: String, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index 4bcfaf0d488..fdf2d7540c0 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -268,24 +268,6 @@ class UserPipelineResourceImpl @Autowired constructor( return Result(true) } - override fun editSetting( - userId: String, - projectId: String, - pipelineId: String, - setting: PipelineSetting, - saveDraft: Boolean? - ): Result { - // TODO #8161 单独保存设置的鉴权 - pipelineSettingFacadeService.saveSetting( - userId = userId, - setting = setting, - checkPermission = false, - dispatchPipelineUpdateEvent = false, - saveDraft = saveDraft - ) - return Result(true) - } - override fun saveAll( userId: String, projectId: String, From 975549e7665ebc2a63c68e807f30bd94e28b65c1 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 29 May 2023 14:46:47 +0800 Subject: [PATCH 006/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/api/service/ServicePipelineResource.kt | 4 ++-- .../tencent/devops/process/api/user/UserPipelineResource.kt | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt index 9ec048b2880..4fad39b75c3 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt @@ -116,7 +116,7 @@ interface ServicePipelineResource { updateLastModifyUser: Boolean? = true, @QueryParam("draft") @DefaultValue("false") - saveDraft: Boolean? + saveDraft: Boolean? = false ): Result @ApiOperation("复制流水线编排") @@ -178,7 +178,7 @@ interface ServicePipelineResource { channelCode: ChannelCode, @QueryParam("draft") @DefaultValue("false") - saveDraft: Boolean? + saveDraft: Boolean? = false ): Result @ApiOperation("获取流水线编排") diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt index 8238a8d24e0..2a59e7029b1 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt @@ -204,7 +204,7 @@ interface UserPipelineResource { pipeline: Model, @QueryParam("draft") @DefaultValue("false") - saveDraft: Boolean? + saveDraft: Boolean? = false ): Result @ApiOperation("编辑流水线编排以及设置") @@ -226,7 +226,7 @@ interface UserPipelineResource { modelAndSetting: PipelineModelAndSetting, @QueryParam("draft") @DefaultValue("false") - saveDraft: Boolean? + saveDraft: Boolean? = false ): Result @ApiOperation("保存流水线设置") @@ -263,7 +263,7 @@ interface UserPipelineResource { pipelineId: String, @QueryParam("draft") @DefaultValue("false") - includeDraft: Boolean? + includeDraft: Boolean? = false ): Result @ApiOperation("获取流水线编排版本") From 3c3d8422b6c72eb4677b271e566839ce11bf617a Mon Sep 17 00:00:00 2001 From: royalhuang Date: Wed, 28 Jun 2023 15:17:50 +0800 Subject: [PATCH 007/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0=E6=B5=81=E6=B0=B4=E7=BA=BF?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tencent/devops/process/pojo/setting/PipelineSetting.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSetting.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSetting.kt index be60c2f691e..b2cdfb746ac 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSetting.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSetting.kt @@ -48,7 +48,7 @@ import com.tencent.devops.process.utils.PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_ import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty -@ApiModel("") +@ApiModel("流水线配置") data class PipelineSetting( @ApiModelProperty("项目id", required = false, accessMode = ApiModelProperty.AccessMode.READ_ONLY) var projectId: String = "", @@ -64,6 +64,10 @@ data class PipelineSetting( var successSubscription: Subscription = Subscription(), @ApiModelProperty("订阅失败相关", required = false) var failSubscription: Subscription = Subscription(), + @ApiModelProperty("订阅成功相关", required = false) + var successSubscriptionList: List = listOf(Subscription()), + @ApiModelProperty("订阅失败相关", required = false) + var failSubscriptionList: List = listOf(Subscription()), @ApiModelProperty("标签列表", required = false) var labels: List = emptyList(), @ApiModelProperty("最大排队时长", required = false) From 4927a3c7eb426a5f47b127201ef45de14b5f64bb Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 3 Jul 2023 21:48:03 +0800 Subject: [PATCH 008/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0=E8=AE=BE=E7=BD=AE=E4=B8=AD?= =?UTF-8?q?=E7=9A=84=E9=80=9A=E7=9F=A5=E7=BB=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/pojo/setting/PipelineSetting.kt | 4 +- .../devops/process/dao/PipelineSettingDao.kt | 113 +++++++++++------- .../service/PipelineRepositoryService.kt | 51 ++++---- .../pipeline/PipelineSettingFacadeService.kt | 2 + .../service/template/TemplateFacadeService.kt | 4 +- 5 files changed, 111 insertions(+), 63 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSetting.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSetting.kt index b2cdfb746ac..2e93aa34509 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSetting.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSetting.kt @@ -65,9 +65,9 @@ data class PipelineSetting( @ApiModelProperty("订阅失败相关", required = false) var failSubscription: Subscription = Subscription(), @ApiModelProperty("订阅成功相关", required = false) - var successSubscriptionList: List = listOf(Subscription()), + var successSubscriptionList: List? = listOf(Subscription()), @ApiModelProperty("订阅失败相关", required = false) - var failSubscriptionList: List = listOf(Subscription()), + var failSubscriptionList: List? = listOf(Subscription()), @ApiModelProperty("标签列表", required = false) var labels: List = emptyList(), @ApiModelProperty("最大排队时长", required = false) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt index 9dd9b7f40b1..93005f11997 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt @@ -33,8 +33,10 @@ import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.notify.enums.NotifyType import com.tencent.devops.model.process.tables.TPipelineSetting import com.tencent.devops.model.process.tables.records.TPipelineSettingRecord +import com.tencent.devops.process.pojo.pipeline.PipelineSubscriptionType import com.tencent.devops.process.pojo.setting.PipelineRunLockType import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.process.pojo.setting.Subscription import com.tencent.devops.process.util.NotifyTemplateUtils import com.tencent.devops.process.utils.PIPELINE_RES_NUM_MIN import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_QUEUE_SIZE_DEFAULT @@ -64,6 +66,22 @@ class PipelineSettingDao { pipelineAsCodeSettings: PipelineAsCodeSettings? ): Int { with(TPipelineSetting.T_PIPELINE_SETTING) { + val successType = successNotifyTypes.split(",").filter { i -> i.isNotBlank() } + .map { type -> PipelineSubscriptionType.valueOf(type) }.toSet() + val failType = failNotifyTypes.split(",").filter { i -> i.isNotBlank() } + .map { type -> PipelineSubscriptionType.valueOf(type) }.toSet() + val successSubscription = Subscription( + types = successType, + groups = emptySet(), + users = "\${$PIPELINE_START_USER_NAME}", + content = NotifyTemplateUtils.getCommonShutdownSuccessContent() + ) + val failSubscription = Subscription( + types = failType, + groups = emptySet(), + users = "\${$PIPELINE_START_USER_NAME}", + content = NotifyTemplateUtils.getCommonShutdownFailureContent() + ) return dslContext.insertInto( this, PROJECT_ID, @@ -83,7 +101,9 @@ class PipelineSettingDao { MAX_QUEUE_SIZE, IS_TEMPLATE, MAX_PIPELINE_RES_NUM, - PIPELINE_AS_CODE_SETTINGS + PIPELINE_AS_CODE_SETTINGS, + SUCCESS_SUBSCRIPTION, + FAILURE_SUBSCRIPTION ) .values( projectId, @@ -91,21 +111,23 @@ class PipelineSettingDao { pipelineName, PipelineRunLockType.toValue(PipelineRunLockType.MULTIPLE), "", - "\${$PIPELINE_START_USER_NAME}", - "\${$PIPELINE_START_USER_NAME}", + successSubscription.users, + failSubscription.users, "", "", successNotifyTypes, failNotifyTypes, - NotifyTemplateUtils.getCommonShutdownSuccessContent(), - NotifyTemplateUtils.getCommonShutdownFailureContent(), + successSubscription.content, + failSubscription.content, DateTimeUtil.minuteToSecond(PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_DEFAULT), PIPELINE_SETTING_MAX_QUEUE_SIZE_DEFAULT, isTemplate, maxPipelineResNum, pipelineAsCodeSettings?.let { self -> JsonUtil.toJson(self, false) - } + }, + JsonUtil.toJson(listOf(successSubscription), false), + JsonUtil.toJson(listOf(failSubscription), false) ) .execute() } @@ -115,6 +137,10 @@ class PipelineSettingDao { with(TPipelineSetting.T_PIPELINE_SETTING) { // #6090 先查询存在情况再做刷新或插入 val origin = getSetting(dslContext, setting.projectId, setting.pipelineId) + val oldSuccessSubscription = setting.successSubscriptionList?.first() ?: setting.successSubscription + val oldFailSubscription = setting.failSubscriptionList?.first() ?: setting.failSubscription + val successSubscriptionList = setting.successSubscriptionList ?: listOf(setting.successSubscription) + val failSubscriptionList = setting.failSubscriptionList ?: listOf(setting.failSubscription) return if (origin == null) { dslContext.insertInto( this, @@ -148,29 +174,31 @@ class PipelineSettingDao { CONCURRENCY_GROUP, CONCURRENCY_CANCEL_IN_PROGRESS, CLEAN_VARIABLES_WHEN_RETRY, - PIPELINE_AS_CODE_SETTINGS + PIPELINE_AS_CODE_SETTINGS, + SUCCESS_SUBSCRIPTION, + FAILURE_SUBSCRIPTION ).values( setting.projectId, setting.pipelineName, setting.desc, PipelineRunLockType.toValue(setting.runLockType), setting.pipelineId, - setting.successSubscription.users, - setting.failSubscription.users, - setting.successSubscription.groups.joinToString(","), - setting.failSubscription.groups.joinToString(","), - setting.successSubscription.types.joinToString(",") { it.name }, - setting.failSubscription.types.joinToString(",") { it.name }, - setting.failSubscription.wechatGroupFlag, - setting.failSubscription.wechatGroup, - setting.failSubscription.wechatGroupMarkdownFlag, - setting.successSubscription.wechatGroupFlag, - setting.successSubscription.wechatGroup, - setting.successSubscription.wechatGroupMarkdownFlag, - setting.successSubscription.detailFlag, - setting.failSubscription.detailFlag, - setting.successSubscription.content, - setting.failSubscription.content, + oldSuccessSubscription.users, + oldFailSubscription.users, + oldSuccessSubscription.groups.joinToString(","), + oldFailSubscription.groups.joinToString(","), + oldSuccessSubscription.types.joinToString(",") { it.name }, + oldFailSubscription.types.joinToString(",") { it.name }, + oldFailSubscription.wechatGroupFlag, + oldFailSubscription.wechatGroup, + oldFailSubscription.wechatGroupMarkdownFlag, + oldSuccessSubscription.wechatGroupFlag, + oldSuccessSubscription.wechatGroup, + oldSuccessSubscription.wechatGroupMarkdownFlag, + oldSuccessSubscription.detailFlag, + oldFailSubscription.detailFlag, + oldSuccessSubscription.content, + oldFailSubscription.content, DateTimeUtil.minuteToSecond(setting.waitQueueTimeMinute), setting.maxQueueSize, isTemplate, @@ -182,29 +210,31 @@ class PipelineSettingDao { setting.cleanVariablesWhenRetry, setting.pipelineAsCodeSettings?.let { self -> JsonUtil.toJson(self, false) - } + }, + JsonUtil.toJson(successSubscriptionList, false), + JsonUtil.toJson(failSubscriptionList, false) ).execute() } else { val updateSetMoreStep = dslContext.update(this) .set(NAME, setting.pipelineName) .set(DESC, setting.desc) .set(RUN_LOCK_TYPE, PipelineRunLockType.toValue(setting.runLockType)) - .set(SUCCESS_RECEIVER, setting.successSubscription.users) - .set(FAIL_RECEIVER, setting.failSubscription.users) - .set(SUCCESS_GROUP, setting.successSubscription.groups.joinToString(",")) - .set(FAIL_GROUP, setting.failSubscription.groups.joinToString(",")) - .set(SUCCESS_TYPE, setting.successSubscription.types.joinToString(",") { it.name }) - .set(FAIL_TYPE, setting.failSubscription.types.joinToString(",") { it.name }) - .set(FAIL_WECHAT_GROUP_FLAG, setting.failSubscription.wechatGroupFlag) - .set(FAIL_WECHAT_GROUP, setting.failSubscription.wechatGroup) - .set(FAIL_WECHAT_GROUP_MARKDOWN_FLAG, setting.failSubscription.wechatGroupMarkdownFlag) - .set(SUCCESS_WECHAT_GROUP_FLAG, setting.successSubscription.wechatGroupFlag) - .set(SUCCESS_WECHAT_GROUP, setting.successSubscription.wechatGroup) - .set(SUCCESS_WECHAT_GROUP_MARKDOWN_FLAG, setting.successSubscription.wechatGroupMarkdownFlag) - .set(SUCCESS_DETAIL_FLAG, setting.successSubscription.detailFlag) - .set(FAIL_DETAIL_FLAG, setting.failSubscription.detailFlag) - .set(SUCCESS_CONTENT, setting.successSubscription.content) - .set(FAIL_CONTENT, setting.failSubscription.content) + .set(SUCCESS_RECEIVER, oldSuccessSubscription.users) + .set(FAIL_RECEIVER, oldFailSubscription.users) + .set(SUCCESS_GROUP, oldSuccessSubscription.groups.joinToString(",")) + .set(FAIL_GROUP, oldFailSubscription.groups.joinToString(",")) + .set(SUCCESS_TYPE, oldSuccessSubscription.types.joinToString(",") { it.name }) + .set(FAIL_TYPE, oldFailSubscription.types.joinToString(",") { it.name }) + .set(FAIL_WECHAT_GROUP_FLAG, oldFailSubscription.wechatGroupFlag) + .set(FAIL_WECHAT_GROUP, oldFailSubscription.wechatGroup) + .set(FAIL_WECHAT_GROUP_MARKDOWN_FLAG, oldFailSubscription.wechatGroupMarkdownFlag) + .set(SUCCESS_WECHAT_GROUP_FLAG, oldSuccessSubscription.wechatGroupFlag) + .set(SUCCESS_WECHAT_GROUP, oldSuccessSubscription.wechatGroup) + .set(SUCCESS_WECHAT_GROUP_MARKDOWN_FLAG, oldSuccessSubscription.wechatGroupMarkdownFlag) + .set(SUCCESS_DETAIL_FLAG, oldSuccessSubscription.detailFlag) + .set(FAIL_DETAIL_FLAG, oldFailSubscription.detailFlag) + .set(SUCCESS_CONTENT, oldSuccessSubscription.content) + .set(FAIL_CONTENT, oldFailSubscription.content) .set(WAIT_QUEUE_TIME_SECOND, DateTimeUtil.minuteToSecond(setting.waitQueueTimeMinute)) .set(MAX_QUEUE_SIZE, setting.maxQueueSize) .set(MAX_PIPELINE_RES_NUM, setting.maxPipelineResNum) @@ -212,6 +242,9 @@ class PipelineSettingDao { .set(CONCURRENCY_GROUP, setting.concurrencyGroup) .set(CONCURRENCY_CANCEL_IN_PROGRESS, setting.concurrencyCancelInProgress) .set(CLEAN_VARIABLES_WHEN_RETRY, setting.cleanVariablesWhenRetry) + .set(CLEAN_VARIABLES_WHEN_RETRY, setting.cleanVariablesWhenRetry) + .set(SUCCESS_SUBSCRIPTION, JsonUtil.toJson(successSubscriptionList, false)) + .set(FAILURE_SUBSCRIPTION, JsonUtil.toJson(failSubscriptionList, false)) // pipelineAsCodeSettings 默认传空不更新 setting.pipelineAsCodeSettings?.let { self -> updateSetMoreStep.set(PIPELINE_AS_CODE_SETTINGS, JsonUtil.toJson(self, false)) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index 7980c8499b4..818cbcaec55 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -27,6 +27,7 @@ package com.tencent.devops.process.engine.service +import com.fasterxml.jackson.core.type.TypeReference import com.tencent.devops.common.api.exception.DependNotFoundException import com.tencent.devops.common.api.exception.ErrorCodeException import com.tencent.devops.common.api.exception.InvalidParamException @@ -1093,32 +1094,42 @@ class PipelineRepositoryService constructor( ?.map { type -> PipelineSubscriptionType.valueOf(type) }?.toSet() ?: emptySet() val failType = t.failType?.split(",")?.filter { i -> i.isNotBlank() } ?.map { type -> PipelineSubscriptionType.valueOf(type) }?.toSet() ?: emptySet() + val oldSuccessSubscription = Subscription( + types = successType, + groups = t.successGroup?.split(",")?.toSet() ?: emptySet(), + users = t.successReceiver ?: "", + wechatGroupFlag = t.successWechatGroupFlag ?: false, + wechatGroup = t.successWechatGroup ?: "", + wechatGroupMarkdownFlag = t.successWechatGroupMarkdownFlag, + detailFlag = t.successDetailFlag, + content = t.successContent ?: "" + ) + val oldFailSubscription = Subscription( + types = failType, + groups = t.failGroup?.split(",")?.toSet() ?: emptySet(), + users = t.failReceiver ?: "", + wechatGroupFlag = t.failWechatGroupFlag ?: false, + wechatGroup = t.failWechatGroup ?: "", + wechatGroupMarkdownFlag = t.failWechatGroupMarkdownFlag ?: false, + detailFlag = t.failDetailFlag, + content = t.failContent ?: "" + ) + val successSubscriptionList = t.successSubscription?.let { + JsonUtil.to(it, object : TypeReference>() {}) + } ?: listOf(oldSuccessSubscription) + val failSubscriptionList = t.failureSubscription?.let { + JsonUtil.to(it, object : TypeReference>() {}) + } ?: listOf(oldFailSubscription) PipelineSetting( projectId = t.projectId, pipelineId = t.pipelineId, pipelineName = t.name, desc = t.desc, runLockType = PipelineRunLockType.valueOf(t.runLockType), - successSubscription = Subscription( - types = successType, - groups = t.successGroup?.split(",")?.toSet() ?: emptySet(), - users = t.successReceiver ?: "", - wechatGroupFlag = t.successWechatGroupFlag ?: false, - wechatGroup = t.successWechatGroup ?: "", - wechatGroupMarkdownFlag = t.successWechatGroupMarkdownFlag, - detailFlag = t.successDetailFlag, - content = t.successContent ?: "" - ), - failSubscription = Subscription( - types = failType, - groups = t.failGroup?.split(",")?.toSet() ?: emptySet(), - users = t.failReceiver ?: "", - wechatGroupFlag = t.failWechatGroupFlag ?: false, - wechatGroup = t.failWechatGroup ?: "", - wechatGroupMarkdownFlag = t.failWechatGroupMarkdownFlag ?: false, - detailFlag = t.failDetailFlag, - content = t.failContent ?: "" - ), + successSubscription = oldSuccessSubscription, + failSubscription = oldFailSubscription, + successSubscriptionList = successSubscriptionList, + failSubscriptionList = failSubscriptionList, labels = emptyList(), waitQueueTimeMinute = DateTimeUtil.secondToMinute(t.waitQueueTimeSecond ?: 600000), maxQueueSize = t.maxQueueSize, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt index 959c173f3b6..057031c5f0f 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt @@ -321,6 +321,8 @@ class PipelineSettingFacadeService @Autowired constructor( desc = oldSetting.desc, successSubscription = oldSetting.successSubscription, failSubscription = oldSetting.failSubscription, + successSubscriptionList = oldSetting.successSubscriptionList, + failSubscriptionList = oldSetting.failSubscriptionList, maxPipelineResNum = oldSetting.maxPipelineResNum, maxQueueSize = oldSetting.maxQueueSize, hasPermission = oldSetting.hasPermission, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt index e806b2fdf20..4ca77a97ee8 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt @@ -1627,6 +1627,8 @@ class TemplateFacadeService @Autowired constructor( runLockType = runLockType, successSubscription = successSubscription, failSubscription = failSubscription, + successSubscriptionList = successSubscriptionList, + failSubscriptionList = failSubscriptionList, labels = labels, waitQueueTimeMinute = waitQueueTimeMinute, maxQueueSize = maxQueueSize, @@ -2115,7 +2117,7 @@ class TemplateFacadeService @Autowired constructor( dslContext.transaction { t -> val context = DSL.using(t) projectCodeList.forEach { - // 判断模板名称是否已经关联过 + // TODO #8161 判断模板名称是否已经关联过,通过setting判断考虑下可否优化 val pipelineSettingRecord = pipelineSettingDao.getSetting( dslContext = context, projectId = it, From 5d02044624bd9c77294e653ae97657ab5afeed4c Mon Sep 17 00:00:00 2001 From: royalhuang Date: Wed, 5 Jul 2023 16:09:39 +0800 Subject: [PATCH 009/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0=E7=89=88=E6=9C=AC=E5=8F=B7?= =?UTF-8?q?=E8=87=AA=E5=8A=A8=E9=80=92=E5=A2=9E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/kotlin/constants/Versions.kt | 2 +- .../common/common-pipeline/build.gradle.kts | 1 + .../process/engine/pojo/PipelineResVersion.kt | 2 +- .../process/pojo/setting/PipelineSetting.kt | 2 +- .../pojo/setting/PipelineVersionSimple.kt | 2 +- .../devops/process/dao/PipelineSettingDao.kt | 22 +++- .../process/dao/PipelineSettingVersionDao.kt | 4 +- .../process/engine/dao/PipelineResDao.kt | 4 +- .../engine/dao/PipelineResVersionDao.kt | 12 +- .../service/PipelineRepositoryService.kt | 114 +++++++++++------- .../PipelineRepositoryVersionService.kt | 2 +- .../com/tencent/devops/process/TestBase.kt | 17 +++ .../service/PipelineInfoFacadeService.kt | 2 +- .../pipeline/PipelineSettingFacadeService.kt | 7 +- .../service/template/TemplateFacadeService.kt | 3 +- 15 files changed, 126 insertions(+), 70 deletions(-) diff --git a/src/backend/ci/buildSrc/src/main/kotlin/constants/Versions.kt b/src/backend/ci/buildSrc/src/main/kotlin/constants/Versions.kt index c07978a97c0..1521fca3e44 100644 --- a/src/backend/ci/buildSrc/src/main/kotlin/constants/Versions.kt +++ b/src/backend/ci/buildSrc/src/main/kotlin/constants/Versions.kt @@ -12,7 +12,7 @@ object Versions { const val JsonSchema = "2.2.6" const val Jasypt = "3.0.3" const val Swagger = "1.6.2" - const val orgJson = "20210307" + const val orgJson = "20230618" const val JsonLib = "2.4" const val CronUtils = "9.1.6" const val Thumbnailator = "0.4.8" diff --git a/src/backend/ci/core/common/common-pipeline/build.gradle.kts b/src/backend/ci/core/common/common-pipeline/build.gradle.kts index bdf64e54bdc..519a6f15264 100644 --- a/src/backend/ci/core/common/common-pipeline/build.gradle.kts +++ b/src/backend/ci/core/common/common-pipeline/build.gradle.kts @@ -34,4 +34,5 @@ dependencies { api("com.squareup.okhttp3:okhttp") api("com.cronutils:cron-utils") api("com.networknt:json-schema-validator") + api("org.json:json") } diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt index 0de581b4f75..bfab8ae9058 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt @@ -70,7 +70,7 @@ data class PipelineResVersion( @ApiModelProperty("关联构建记录总数", required = false) val referCount: Int? = null, @ApiModelProperty("编排版本号", required = false) - val modelVersion: Int? = null, + val pipelineVersion: Int? = null, @ApiModelProperty("触发器版本号", required = false) val triggerVersion: Int? = null, @ApiModelProperty("配置版本号", required = false) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSetting.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSetting.kt index 2e93aa34509..c327a6ad1a6 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSetting.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSetting.kt @@ -85,7 +85,7 @@ data class PipelineSetting( @ApiModelProperty("并发构建数量限制", required = false) val maxConRunningQueueSize: Int? = PIPELINE_SETTING_MAX_CON_QUEUE_SIZE_MAX, // MULTIPLE类型时,并发构建数量限制 @ApiModelProperty("版本", required = false) - var version: Int = 0, + var version: Int = 1, @field:BkField(patternStyle = BkStyleEnum.BUILD_NUM_RULE_STYLE, required = false) @ApiModelProperty("构建号生成规则", required = false) val buildNumRule: String? = null, // 构建号生成规则 diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineVersionSimple.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineVersionSimple.kt index a00ba31300f..a671f9b2fd3 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineVersionSimple.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineVersionSimple.kt @@ -47,7 +47,7 @@ data class PipelineVersionSimple( @ApiModelProperty("关联构建记录总数", required = false) val referCount: Int? = null, @ApiModelProperty("编排版本号", required = false) - val modelVersion: Int? = null, + val pipelineVersion: Int? = null, @ApiModelProperty("触发器版本号", required = false) val triggerVersion: Int? = null, @ApiModelProperty("配置版本号", required = false) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt index 93005f11997..60e18f63465 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt @@ -63,7 +63,8 @@ class PipelineSettingDao { successNotifyTypes: String = "", failNotifyTypes: String = "${NotifyType.EMAIL.name},${NotifyType.RTX.name}", maxPipelineResNum: Int? = PIPELINE_RES_NUM_MIN, - pipelineAsCodeSettings: PipelineAsCodeSettings? + pipelineAsCodeSettings: PipelineAsCodeSettings?, + settingVersion: Int ): Int { with(TPipelineSetting.T_PIPELINE_SETTING) { val successType = successNotifyTypes.split(",").filter { i -> i.isNotBlank() } @@ -103,7 +104,8 @@ class PipelineSettingDao { MAX_PIPELINE_RES_NUM, PIPELINE_AS_CODE_SETTINGS, SUCCESS_SUBSCRIPTION, - FAILURE_SUBSCRIPTION + FAILURE_SUBSCRIPTION, + VERSION ) .values( projectId, @@ -127,13 +129,18 @@ class PipelineSettingDao { JsonUtil.toJson(self, false) }, JsonUtil.toJson(listOf(successSubscription), false), - JsonUtil.toJson(listOf(failSubscription), false) + JsonUtil.toJson(listOf(failSubscription), false), + settingVersion ) .execute() } } - fun saveSetting(dslContext: DSLContext, setting: PipelineSetting, isTemplate: Boolean = false): Int { + fun saveSetting( + dslContext: DSLContext, + setting: PipelineSetting, + isTemplate: Boolean = false + ): Int { with(TPipelineSetting.T_PIPELINE_SETTING) { // #6090 先查询存在情况再做刷新或插入 val origin = getSetting(dslContext, setting.projectId, setting.pipelineId) @@ -176,7 +183,8 @@ class PipelineSettingDao { CLEAN_VARIABLES_WHEN_RETRY, PIPELINE_AS_CODE_SETTINGS, SUCCESS_SUBSCRIPTION, - FAILURE_SUBSCRIPTION + FAILURE_SUBSCRIPTION, + VERSION ).values( setting.projectId, setting.pipelineName, @@ -212,7 +220,8 @@ class PipelineSettingDao { JsonUtil.toJson(self, false) }, JsonUtil.toJson(successSubscriptionList, false), - JsonUtil.toJson(failSubscriptionList, false) + JsonUtil.toJson(failSubscriptionList, false), + setting.version ).execute() } else { val updateSetMoreStep = dslContext.update(this) @@ -245,6 +254,7 @@ class PipelineSettingDao { .set(CLEAN_VARIABLES_WHEN_RETRY, setting.cleanVariablesWhenRetry) .set(SUCCESS_SUBSCRIPTION, JsonUtil.toJson(successSubscriptionList, false)) .set(FAILURE_SUBSCRIPTION, JsonUtil.toJson(failSubscriptionList, false)) + .set(VERSION, setting.version) // pipelineAsCodeSettings 默认传空不更新 setting.pipelineAsCodeSettings?.let { self -> updateSetMoreStep.set(PIPELINE_AS_CODE_SETTINGS, JsonUtil.toJson(self, false)) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingVersionDao.kt index b6ea3ee4a04..91da1a2bcc1 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingVersionDao.kt @@ -46,7 +46,7 @@ class PipelineSettingVersionDao { dslContext: DSLContext, projectId: String, pipelineId: String, - version: Int = 1, + settingVersion: Int, isTemplate: Boolean = false, successNotifyTypes: String = "", failNotifyTypes: String = "${NotifyType.EMAIL.name},${NotifyType.RTX.name}", @@ -81,7 +81,7 @@ class PipelineSettingVersionDao { NotifyTemplateUtils.getCommonShutdownSuccessContent(), NotifyTemplateUtils.getCommonShutdownFailureContent(), isTemplate, - version, + settingVersion, id ) .execute() diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt index 32baf6858fb..ced9992d5bc 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt @@ -72,7 +72,7 @@ class PipelineResDao { .set(TRIGGER, triggerString) .set(CREATOR, creator) .set(CREATE_TIME, LocalDateTime.now()) - .set(MODEL_VERSION, modelVersion) + .set(PIPELINE_VERSION, version) .set(TRIGGER_VERSION, triggerVersion) .set(SETTING_VERSION, settingVersion) .onDuplicateKeyUpdate() @@ -80,7 +80,7 @@ class PipelineResDao { .set(TRIGGER, triggerString) .set(CREATOR, creator) .set(VERSION_NAME, versionName) - .set(MODEL_VERSION, modelVersion) + .set(PIPELINE_VERSION, modelVersion) .set(TRIGGER_VERSION, triggerVersion) .set(SETTING_VERSION, settingVersion) .execute() diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt index 7291a86e573..43895612e98 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt @@ -51,7 +51,7 @@ class PipelineResVersionDao { versionName: String, model: Model, trigger: TriggerContainer, - modelVersion: Int?, + pipelineVersion: Int?, triggerVersion: Int?, settingVersion: Int?, draftFlag: Boolean @@ -65,7 +65,7 @@ class PipelineResVersionDao { versionName = versionName, modelString = JsonUtil.toJson(model, formatted = false), triggerString = JsonUtil.toJson(trigger, formatted = false), - modelVersion = modelVersion, + pipelineVersion = pipelineVersion, triggerVersion = triggerVersion, settingVersion = settingVersion, draftFlag = draftFlag @@ -81,7 +81,7 @@ class PipelineResVersionDao { versionName: String = "init", modelString: String, triggerString: String?, - modelVersion: Int?, + pipelineVersion: Int?, triggerVersion: Int?, settingVersion: Int?, draftFlag: Boolean @@ -96,7 +96,7 @@ class PipelineResVersionDao { .set(TRIGGER, triggerString) .set(CREATOR, creator) .set(CREATE_TIME, LocalDateTime.now()) - .set(MODEL_VERSION, modelVersion) + .set(PIPELINE_VERSION, pipelineVersion) .set(TRIGGER_VERSION, triggerVersion) .set(SETTING_VERSION, settingVersion) .set(DRAFT_FLAG, draftFlag) @@ -105,7 +105,7 @@ class PipelineResVersionDao { .set(TRIGGER, triggerString) .set(CREATOR, creator) .set(VERSION_NAME, versionName) - .set(MODEL_VERSION, modelVersion) + .set(PIPELINE_VERSION, pipelineVersion) .set(TRIGGER_VERSION, triggerVersion) .set(SETTING_VERSION, settingVersion) .execute() @@ -187,7 +187,7 @@ class PipelineResVersionDao { versionName = it.versionName ?: "init", referFlag = it.referFlag, referCount = it.referCount, - modelVersion = it.modelVersion, + pipelineVersion = it.pipelineVersion, triggerVersion = it.triggerVersion, settingVersion = it.settingVersion, draftFlag = it.draftFlag, diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index 818cbcaec55..f52520da428 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -28,6 +28,7 @@ package com.tencent.devops.process.engine.service import com.fasterxml.jackson.core.type.TypeReference +import com.fasterxml.jackson.databind.ObjectMapper import com.tencent.devops.common.api.exception.DependNotFoundException import com.tencent.devops.common.api.exception.ErrorCodeException import com.tencent.devops.common.api.exception.InvalidParamException @@ -93,6 +94,7 @@ import com.tencent.devops.project.api.service.ServiceProjectResource import org.joda.time.LocalDateTime import org.jooq.DSLContext import org.jooq.impl.DSL +import org.json.JSONObject import org.slf4j.LoggerFactory import org.springframework.stereotype.Service import java.util.concurrent.atomic.AtomicInteger @@ -128,6 +130,7 @@ class PipelineRepositoryService constructor( private val versionConfigure: VersionConfigure, private val pipelineInfoExtService: PipelineInfoExtService, private val client: Client, + private val objectMapper: ObjectMapper, private val redisOperation: RedisOperation ) { @@ -136,13 +139,13 @@ class PipelineRepositoryService constructor( private val logger = LoggerFactory.getLogger(PipelineRepositoryService::class.java) private const val PIPELINE_SETTING_VERSION_BIZ_TAG_NAME = "PIPELINE_SETTING_VERSION" private fun getVersionName( - modelVersion: Int?, + pipelineVersion: Int?, triggerVersion: Int?, settingVersion: Int? ): String { - return if (modelVersion == null || triggerVersion == null || settingVersion == null) { + return if (pipelineVersion == null || triggerVersion == null || settingVersion == null) { "init" - } else "P$modelVersion.T$triggerVersion.$settingVersion" + } else "P$pipelineVersion.T$triggerVersion.$settingVersion" } } @@ -501,7 +504,10 @@ class PipelineRepositoryService constructor( templateId: String? = null, saveDraft: Boolean? = false ): DeployPipelineResult { - + val modelVersion = 1 + val pipelineVersion = 1 + val triggerVersion = 1 + val settingVersion = 1 val taskCount: Int = model.taskCount() val id = client.get(ServiceAllocIdResource::class).generateSegmentId("PIPELINE_INFO").data val lock = PipelineModelLock(redisOperation, pipelineId) @@ -513,7 +519,7 @@ class PipelineRepositoryService constructor( dslContext = transactionContext, pipelineId = pipelineId, projectId = projectId, - version = 1, + version = modelVersion, pipelineName = model.name, pipelineDesc = model.desc ?: model.name, userId = userId, @@ -523,36 +529,7 @@ class PipelineRepositoryService constructor( taskCount = taskCount, id = id ) - model.latestVersion = 1 - // 如果不是草稿保存,最新版本永远是新增逻辑 - if (saveDraft != true) pipelineResDao.create( - dslContext = transactionContext, - projectId = projectId, - pipelineId = pipelineId, - creator = userId, - version = 1, - model = model, - trigger = trigger, - versionName = getVersionName(1, 1, 1), - modelVersion = 1, - triggerVersion = 1, - settingVersion = 1 - ) - // 同步记录到历史版本表 - pipelineResVersionDao.create( - dslContext = transactionContext, - projectId = projectId, - pipelineId = pipelineId, - creator = userId, - version = 1, - model = model, - trigger = trigger, - versionName = getVersionName(1, 1, 1), - modelVersion = 1, - triggerVersion = 1, - settingVersion = 1, - draftFlag = saveDraft == true - ) + model.latestVersion = modelVersion if (model.instanceFromTemplate != true) { if (null == pipelineSettingDao.getSetting(transactionContext, projectId, pipelineId)) { if (templateId != null && useTemplateSettings == true) { @@ -561,6 +538,7 @@ class PipelineRepositoryService constructor( ?: throw ErrorCodeException(errorCode = ProcessMessageCode.PIPELINE_SETTING_NOT_EXISTS) setting.pipelineId = pipelineId setting.pipelineName = model.name + setting.version = settingVersion pipelineSettingDao.saveSetting(dslContext, setting) } else { // #3311 @@ -592,7 +570,8 @@ class PipelineRepositoryService constructor( } catch (ignore: Throwable) { logger.warn("[$projectId]|Failed to sync project|pipelineId=$pipelineId", ignore) null - } + }, + settingVersion = settingVersion ) pipelineSettingVersionDao.insertNewSetting( dslContext = transactionContext, @@ -600,7 +579,8 @@ class PipelineRepositoryService constructor( pipelineId = pipelineId, failNotifyTypes = notifyTypes, id = client.get(ServiceAllocIdResource::class) - .generateSegmentId(PIPELINE_SETTING_VERSION_BIZ_TAG_NAME).data + .generateSegmentId(PIPELINE_SETTING_VERSION_BIZ_TAG_NAME).data, + settingVersion = settingVersion ) } } else { @@ -613,6 +593,35 @@ class PipelineRepositoryService constructor( ) } } + // 如果不是草稿保存,最新版本永远是新增逻辑 + if (saveDraft != true) pipelineResDao.create( + dslContext = transactionContext, + projectId = projectId, + pipelineId = pipelineId, + creator = userId, + version = 1, + model = model, + trigger = trigger, + versionName = getVersionName(pipelineVersion, triggerVersion, settingVersion), + modelVersion = modelVersion, + triggerVersion = triggerVersion, + settingVersion = settingVersion + ) + // 同步记录到历史版本表 + pipelineResVersionDao.create( + dslContext = transactionContext, + projectId = projectId, + pipelineId = pipelineId, + creator = userId, + version = 1, + model = model, + trigger = trigger, + versionName = getVersionName(modelVersion, triggerVersion, settingVersion), + pipelineVersion = modelVersion, + triggerVersion = triggerVersion, + settingVersion = settingVersion, + draftFlag = saveDraft == true + ) // 初始化流水线构建统计表 pipelineBuildSummaryDao.create(dslContext, projectId, pipelineId, buildNo) pipelineModelTaskDao.batchSave(transactionContext, modelTasks) @@ -702,9 +711,24 @@ class PipelineRepositoryService constructor( val latestResRecord = pipelineResDao.getLatestVersionRecord( transactionContext, projectId, pipelineId ) - val modelVersion = 1 - val triggerVersion = 1 - val settingVersion = 1 + var pipelineVersion = latestResRecord?.pipelineVersion ?: version + var triggerVersion = latestResRecord?.triggerVersion ?: version + var settingVersion = latestResRecord?.settingVersion ?: version + latestResRecord?.let { + val originModel = try { + objectMapper.readValue(it.model, Model::class.java) + } catch (ignored: Exception) { + logger.error("parse process($pipelineId) model fail", ignored) + null + } ?: return@let + val originTriggerJson = JSONObject(originModel.stages.first()) + val originPipelineJson = JSONObject(originModel.stages.slice(1 until originModel.stages.size)) + val triggerJson = JSONObject(model.stages.first()) + val pipelineJson = JSONObject(model.stages.slice(1 until model.stages.size)) + if (!originTriggerJson.similar(triggerJson)) triggerVersion++ + if (!originPipelineJson.similar(pipelineJson)) pipelineVersion++ + } + if (saveDraft != true) pipelineResDao.create( dslContext = transactionContext, projectId = projectId, @@ -713,8 +737,8 @@ class PipelineRepositoryService constructor( version = version, model = model, trigger = triggerContainer, - versionName = getVersionName(modelVersion, triggerVersion, settingVersion), - modelVersion = modelVersion, + versionName = getVersionName(pipelineVersion, triggerVersion, settingVersion), + modelVersion = pipelineVersion, triggerVersion = triggerVersion, settingVersion = settingVersion ) @@ -726,8 +750,8 @@ class PipelineRepositoryService constructor( version = version, model = model, trigger = triggerContainer, - versionName = getVersionName(modelVersion, triggerVersion, settingVersion), - modelVersion = modelVersion, + versionName = getVersionName(pipelineVersion, triggerVersion, settingVersion), + pipelineVersion = pipelineVersion, triggerVersion = triggerVersion, settingVersion = settingVersion, draftFlag = saveDraft == true @@ -763,7 +787,7 @@ class PipelineRepositoryService constructor( version = version - 1, modelString = lastVersionModelStr, triggerString = triggerStr, - modelVersion = null, + pipelineVersion = null, triggerVersion = null, settingVersion = null, draftFlag = false diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt index 5656119d33c..d2cd40d92f4 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt @@ -146,7 +146,7 @@ class PipelineRepositoryVersionService( templateId = pipelineInfo.templateId, version = it.version, versionName = it.versionName, - modelVersion = it.modelVersion, + pipelineVersion = it.pipelineVersion, triggerVersion = it.triggerVersion, settingVersion = it.settingVersion, draftFlag = it.draftFlag, diff --git a/src/backend/ci/core/process/biz-base/src/test/kotlin/com/tencent/devops/process/TestBase.kt b/src/backend/ci/core/process/biz-base/src/test/kotlin/com/tencent/devops/process/TestBase.kt index 40c1a101bb3..8cc552ce599 100644 --- a/src/backend/ci/core/process/biz-base/src/test/kotlin/com/tencent/devops/process/TestBase.kt +++ b/src/backend/ci/core/process/biz-base/src/test/kotlin/com/tencent/devops/process/TestBase.kt @@ -53,7 +53,10 @@ import com.tencent.devops.process.engine.common.Timeout import com.tencent.devops.process.engine.pojo.PipelineBuildContainer import com.tencent.devops.process.engine.pojo.PipelineBuildContainerControlOption import com.tencent.devops.process.engine.pojo.PipelineBuildTask +import org.json.JSONObject +import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test import java.time.LocalDateTime open class TestBase : BkCiAbstractTest() { @@ -83,6 +86,20 @@ open class TestBase : BkCiAbstractTest() { variables.clear() } + @Test + fun diffModel() { + val model1 = genModel(3, 2, 4, true) + val model2 = genModel(3, 2, 5, true) + val model3 = genModel(3, 2, 5, true) + val j1 = JSONObject(model1) + val j2 = JSONObject(model2) + val j3 = JSONObject(model3) + Assertions.assertFalse(j1.similar(j2)) + Assertions.assertFalse(j3.similar(j2)) + val model4 = genModel(0, 2, 5, false) + println(model4.stages.slice(1 until model4.stages.size)) + } + fun genModel(stageSize: Int, jobSize: Int, elementSize: Int, needFinally: Boolean = false): Model { val stages = genStages(stageSize, jobSize, elementSize, needFinally) return Model(name = "DefaultModelCheckPluginTest", desc = "unit test", stages = stages) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index f57df3c0ff4..0e66d8f7201 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -791,7 +791,7 @@ class PipelineInfoFacadeService @Autowired constructor( setting.projectId = projectId } setting.pipelineId = pipelineResult.pipelineId // fix 用户端可能不传入pipelineId的问题,或者传错的问题 - pipelineSettingFacadeService.saveSetting( + val settingVersion = pipelineSettingFacadeService.saveSetting( userId = userId, setting = setting, checkPermission = false, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt index 057031c5f0f..f3a2ec40ea4 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt @@ -81,6 +81,9 @@ class PipelineSettingFacadeService @Autowired constructor( private val pipelineEventDispatcher: PipelineEventDispatcher ) { + /** + * 修改配置时需要返回具体的版本号用于传递 + */ fun saveSetting( userId: String, setting: PipelineSetting, @@ -90,7 +93,7 @@ class PipelineSettingFacadeService @Autowired constructor( dispatchPipelineUpdateEvent: Boolean = true, updateLabels: Boolean = true, saveDraft: Boolean? = false - ): String { + ): Int { // TODO #8161 增加配置的版本管理 if (checkPermission) { val language = I18nUtil.getLanguage(userId) @@ -164,7 +167,7 @@ class PipelineSettingFacadeService @Autowired constructor( ) ) } - return setting.pipelineId + return setting.version } fun userGetSetting( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt index 4ca77a97ee8..ca8db332764 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt @@ -2076,7 +2076,8 @@ class TemplateFacadeService @Autowired constructor( } catch (ignore: Throwable) { logger.warn("[$projectId]|Failed to sync project|templateId=$templateId", ignore) null - } + }, + settingVersion = 1 ) } From d132f61965c72b7213cd9aff0038876574cf8379 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Wed, 5 Jul 2023 16:32:56 +0800 Subject: [PATCH 010/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20setting=E8=A1=A8=E7=89=88=E6=9C=AC=E5=8F=B7=E8=A7=A3?= =?UTF-8?q?=E7=BB=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/process/dao/PipelineSettingDao.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt index 60e18f63465..28dd9dcf135 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt @@ -105,7 +105,7 @@ class PipelineSettingDao { PIPELINE_AS_CODE_SETTINGS, SUCCESS_SUBSCRIPTION, FAILURE_SUBSCRIPTION, - VERSION + SETTING_VERSION ) .values( projectId, @@ -184,7 +184,7 @@ class PipelineSettingDao { PIPELINE_AS_CODE_SETTINGS, SUCCESS_SUBSCRIPTION, FAILURE_SUBSCRIPTION, - VERSION + SETTING_VERSION ).values( setting.projectId, setting.pipelineName, @@ -254,7 +254,7 @@ class PipelineSettingDao { .set(CLEAN_VARIABLES_WHEN_RETRY, setting.cleanVariablesWhenRetry) .set(SUCCESS_SUBSCRIPTION, JsonUtil.toJson(successSubscriptionList, false)) .set(FAILURE_SUBSCRIPTION, JsonUtil.toJson(failSubscriptionList, false)) - .set(VERSION, setting.version) + .set(SETTING_VERSION, setting.version) // pipelineAsCodeSettings 默认传空不更新 setting.pipelineAsCodeSettings?.let { self -> updateSetMoreStep.set(PIPELINE_AS_CODE_SETTINGS, JsonUtil.toJson(self, false)) From 074e9266637913ea79a0889409c29c64ab3c5931 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 6 Jul 2023 11:21:54 +0800 Subject: [PATCH 011/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20setting=E8=A1=A8=E7=89=88=E6=9C=AC=E5=8F=B7=E8=A7=A3?= =?UTF-8?q?=E7=BB=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../engine/service/PipelineRepositoryService.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index f52520da428..950923e8e1f 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -36,6 +36,7 @@ import com.tencent.devops.common.api.pojo.PipelineAsCodeSettings import com.tencent.devops.common.api.util.DateTimeUtil import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.api.util.MessageUtil +import com.tencent.devops.common.api.util.Watcher import com.tencent.devops.common.client.Client import com.tencent.devops.common.event.dispatcher.pipeline.PipelineEventDispatcher import com.tencent.devops.common.event.pojo.pipeline.PipelineModelAnalysisEvent @@ -53,6 +54,7 @@ import com.tencent.devops.common.pipeline.pojo.element.SubPipelineCallElement import com.tencent.devops.common.pipeline.pojo.element.trigger.ManualTriggerElement import com.tencent.devops.common.pipeline.utils.MatrixContextUtils import com.tencent.devops.common.redis.RedisOperation +import com.tencent.devops.common.service.utils.LogUtils import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.constant.ProcessMessageCode import com.tencent.devops.process.constant.ProcessMessageCode.BK_FIRST_STAGE_ENV_NOT_EMPTY @@ -668,10 +670,12 @@ class PipelineRepositoryService constructor( val triggerContainer = model.stages[0].containers[0] as TriggerContainer var version = 0 val lock = PipelineModelLock(redisOperation, pipelineId) + val watcher = Watcher(id = "updatePipeline#$pipelineId#$saveDraft") try { lock.lock() dslContext.transaction { configuration -> val transactionContext = DSL.using(configuration) + watcher.start("updatePipelineInfo") version = if (updateLastModifyUser != null && updateLastModifyUser == false) { pipelineInfoDao.update( dslContext = transactionContext, @@ -707,7 +711,7 @@ class PipelineRepositoryService constructor( } model.latestVersion = version // 如果不是草稿保存,最新版本永远是新增逻辑 - // TODO #8161 根据差异对比进行小版本号计算 + watcher.start("getOriginModel") val latestResRecord = pipelineResDao.getLatestVersionRecord( transactionContext, projectId, pipelineId ) @@ -721,14 +725,16 @@ class PipelineRepositoryService constructor( logger.error("parse process($pipelineId) model fail", ignored) null } ?: return@let + watcher.start("getModelJsonObject") val originTriggerJson = JSONObject(originModel.stages.first()) val originPipelineJson = JSONObject(originModel.stages.slice(1 until originModel.stages.size)) val triggerJson = JSONObject(model.stages.first()) val pipelineJson = JSONObject(model.stages.slice(1 until model.stages.size)) + watcher.start("getSimilarResult") if (!originTriggerJson.similar(triggerJson)) triggerVersion++ if (!originPipelineJson.similar(pipelineJson)) pipelineVersion++ } - + watcher.start("updatePipelineResource") if (saveDraft != true) pipelineResDao.create( dslContext = transactionContext, projectId = projectId, @@ -757,6 +763,7 @@ class PipelineRepositoryService constructor( draftFlag = saveDraft == true ) // 针对新增version表做的数据迁移 + watcher.start("updatePipelineResourceVersion") if (version > 1 && pipelineResVersionDao.getVersionModelString( dslContext = transactionContext, projectId = projectId, @@ -794,6 +801,7 @@ class PipelineRepositoryService constructor( ) } } + watcher.start("deleteEarlyVersion") pipelineModelTaskDao.deletePipelineTasks( dslContext = transactionContext, projectId = projectId, @@ -817,6 +825,8 @@ class PipelineRepositoryService constructor( pipelineModelTaskDao.batchSave(transactionContext, modelTasks) } } finally { + watcher.stop() + LogUtils.printCostTimeWE(watcher) lock.unlock() } From 66a2f98bc8888addf5cd06072eb474413348971d Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 6 Jul 2023 12:13:19 +0800 Subject: [PATCH 012/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20setting=E8=A1=A8=E7=89=88=E6=9C=AC=E5=8F=B7=E8=A7=A3?= =?UTF-8?q?=E7=BB=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/process/engine/dao/PipelineResDao.kt | 6 +++--- .../process/engine/service/PipelineRepositoryService.kt | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt index ced9992d5bc..1c3dc0ecd84 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt @@ -55,7 +55,7 @@ class PipelineResDao { versionName: String, model: Model, trigger: TriggerContainer, - modelVersion: Int, + pipelineVersion: Int, triggerVersion: Int, settingVersion: Int ) { @@ -72,7 +72,7 @@ class PipelineResDao { .set(TRIGGER, triggerString) .set(CREATOR, creator) .set(CREATE_TIME, LocalDateTime.now()) - .set(PIPELINE_VERSION, version) + .set(PIPELINE_VERSION, pipelineVersion) .set(TRIGGER_VERSION, triggerVersion) .set(SETTING_VERSION, settingVersion) .onDuplicateKeyUpdate() @@ -80,7 +80,7 @@ class PipelineResDao { .set(TRIGGER, triggerString) .set(CREATOR, creator) .set(VERSION_NAME, versionName) - .set(PIPELINE_VERSION, modelVersion) + .set(PIPELINE_VERSION, pipelineVersion) .set(TRIGGER_VERSION, triggerVersion) .set(SETTING_VERSION, settingVersion) .execute() diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index 950923e8e1f..ba8f78f64a0 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -605,7 +605,7 @@ class PipelineRepositoryService constructor( model = model, trigger = trigger, versionName = getVersionName(pipelineVersion, triggerVersion, settingVersion), - modelVersion = modelVersion, + pipelineVersion = modelVersion, triggerVersion = triggerVersion, settingVersion = settingVersion ) @@ -744,7 +744,7 @@ class PipelineRepositoryService constructor( model = model, trigger = triggerContainer, versionName = getVersionName(pipelineVersion, triggerVersion, settingVersion), - modelVersion = pipelineVersion, + pipelineVersion = pipelineVersion, triggerVersion = triggerVersion, settingVersion = settingVersion ) From 9ea80073491f34f1e09058ff36c7630481c31fd5 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 6 Jul 2023 17:41:33 +0800 Subject: [PATCH 013/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20setting=E8=A1=A8=E7=89=88=E6=9C=AC=E5=8F=B7=E8=A7=A3?= =?UTF-8?q?=E7=BB=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/api/user/UserPipelineResource.kt | 19 +++++ .../pojo/pipeline/PipelineResourceVersion.kt | 66 ++++++++++++++++ .../setting/PipelineResourceAndSetting.kt | 40 ++++++++++ .../process/engine/dao/PipelineResDao.kt | 37 ++++++++- .../engine/dao/PipelineResVersionDao.kt | 52 +++++++++++-- .../service/PipelineRepositoryService.kt | 39 +++++++--- .../process/api/UserPipelineResourceImpl.kt | 25 +++++++ .../service/PipelineInfoFacadeService.kt | 75 ++++++++++++++++++- 8 files changed, 327 insertions(+), 26 deletions(-) create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineResourceAndSetting.kt diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt index 2a59e7029b1..fbbdf32627e 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt @@ -51,6 +51,7 @@ import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import com.tencent.devops.process.pojo.pipeline.BatchDeletePipeline import com.tencent.devops.process.pojo.pipeline.PipelineCount import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting +import com.tencent.devops.process.pojo.setting.PipelineResourceAndSetting import com.tencent.devops.process.pojo.setting.PipelineSetting import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation @@ -266,6 +267,24 @@ interface UserPipelineResource { includeDraft: Boolean? = false ): Result + @ApiOperation("获取流水线编排和设置") + @GET + @Path("/projects/{projectId}/pipelines/{pipelineId}/") + fun getPipelineResourceAndSetting( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String, + @QueryParam("draft") + @DefaultValue("false") + includeDraft: Boolean? = false + ): Result + @ApiOperation("获取流水线编排版本") @GET @Path("/{projectId}/{pipelineId}/{version}") diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt new file mode 100644 index 00000000000..8ff96ada9a5 --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt @@ -0,0 +1,66 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.pojo.pipeline + +import com.tencent.devops.common.pipeline.Model +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty +import java.time.LocalDateTime + +@Suppress("LongParameterList", "LongMethod") +@ApiModel("流水线版本-详细内容") +data class PipelineResourceVersion( + @ApiModelProperty("项目ID", required = true) + val projectId: String, + @ApiModelProperty("流水线ID", required = true) + val pipelineId: String, + @ApiModelProperty("记录版本号", required = true) + val version: Int, + @ApiModelProperty("编排内容", required = true) + val model: Model, + @ApiModelProperty("创建者", required = true) + val creator: String, + @ApiModelProperty("版本名称", required = true) + val versionName: String, + @ApiModelProperty("创建者", required = true) + val createTime: LocalDateTime, + @ApiModelProperty("编排版本号", required = false) + val pipelineVersion: Int?, + @ApiModelProperty("触发器版本号", required = false) + val triggerVersion: Int?, + @ApiModelProperty("设置版本号", required = false) + val settingVersion: Int?, + @ApiModelProperty("是否还有构建记录引用该版本标识", required = false) + val referFlag: Boolean? = null, + @ApiModelProperty("关联构建记录总数", required = false) + val referCount: Int? = null, + @ApiModelProperty("草稿版本标识", required = false) + val draftFlag: Boolean? = false, + @ApiModelProperty("分支版本标识", required = false) + val refs: String? = null, +) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineResourceAndSetting.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineResourceAndSetting.kt new file mode 100644 index 00000000000..03d076a3b50 --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineResourceAndSetting.kt @@ -0,0 +1,40 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.pojo.setting + +import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion +import io.swagger.annotations.ApiModelProperty +import javax.validation.Valid + +data class PipelineResourceAndSetting( + @ApiModelProperty("流水线模型", required = true) + val pipelineResource: PipelineResourceVersion, + @ApiModelProperty("流水线设置", required = false) + @field:Valid + val setting: PipelineSetting +) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt index 1c3dc0ecd84..e25e23f1aa0 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt @@ -32,6 +32,7 @@ import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.container.TriggerContainer import com.tencent.devops.model.process.Tables.T_PIPELINE_RESOURCE import com.tencent.devops.model.process.tables.records.TPipelineResourceRecord +import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion import com.tencent.devops.process.pojo.setting.PipelineModelVersion import org.jooq.Condition import org.jooq.DSLContext @@ -69,7 +70,6 @@ class PipelineResDao { .set(VERSION, version) .set(VERSION_NAME, versionName) .set(MODEL, modelString) - .set(TRIGGER, triggerString) .set(CREATOR, creator) .set(CREATE_TIME, LocalDateTime.now()) .set(PIPELINE_VERSION, pipelineVersion) @@ -77,7 +77,6 @@ class PipelineResDao { .set(SETTING_VERSION, settingVersion) .onDuplicateKeyUpdate() .set(MODEL, modelString) - .set(TRIGGER, triggerString) .set(CREATOR, creator) .set(VERSION_NAME, versionName) .set(PIPELINE_VERSION, pipelineVersion) @@ -99,6 +98,37 @@ class PipelineResDao { } } + fun getLatestVersionResource( + dslContext: DSLContext, + projectId: String, + pipelineId: String + ): PipelineResourceVersion? { + with(T_PIPELINE_RESOURCE) { + val record = dslContext.selectFrom(this) + .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) + .fetchAny() ?: return null + return PipelineResourceVersion( + projectId = record.projectId, + pipelineId = record.pipelineId, + version = record.version, + model = record.model?.let { str -> + try { + JsonUtil.to(str, Model::class.java) + } catch (ignore: Exception) { + logger.warn("get process($pipelineId) model fail", ignore) + null + } + } ?: return null, + creator = record.creator, + versionName = record.versionName, + createTime = record.createTime, + pipelineVersion = record.pipelineVersion, + triggerVersion = record.triggerVersion, + settingVersion = record.settingVersion + ) + } + } + fun getLatestVersionModelString( dslContext: DSLContext, projectId: String, @@ -114,8 +144,7 @@ class PipelineResDao { dslContext: DSLContext, projectId: String, pipelineId: String, - version: Int?, - includeDraft: Boolean? = false + version: Int? ): String? { return with(T_PIPELINE_RESOURCE) { diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt index 43895612e98..f5ee5b3d0da 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt @@ -32,13 +32,14 @@ import com.tencent.devops.common.api.util.timestampmilli import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.container.TriggerContainer import com.tencent.devops.model.process.Tables.T_PIPELINE_RESOURCE_VERSION +import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion import com.tencent.devops.process.pojo.setting.PipelineVersionSimple import org.jooq.DSLContext import org.jooq.impl.DSL import org.springframework.stereotype.Repository import java.time.LocalDateTime -@Suppress("Unused", "LongParameterList") +@Suppress("Unused", "LongParameterList", "ReturnCount") @Repository class PipelineResVersionDao { @@ -64,7 +65,6 @@ class PipelineResVersionDao { version = version, versionName = versionName, modelString = JsonUtil.toJson(model, formatted = false), - triggerString = JsonUtil.toJson(trigger, formatted = false), pipelineVersion = pipelineVersion, triggerVersion = triggerVersion, settingVersion = settingVersion, @@ -80,7 +80,6 @@ class PipelineResVersionDao { version: Int, versionName: String = "init", modelString: String, - triggerString: String?, pipelineVersion: Int?, triggerVersion: Int?, settingVersion: Int?, @@ -93,7 +92,6 @@ class PipelineResVersionDao { .set(VERSION, version) .set(VERSION_NAME, versionName) .set(MODEL, modelString) - .set(TRIGGER, triggerString) .set(CREATOR, creator) .set(CREATE_TIME, LocalDateTime.now()) .set(PIPELINE_VERSION, pipelineVersion) @@ -102,7 +100,6 @@ class PipelineResVersionDao { .set(DRAFT_FLAG, draftFlag) .onDuplicateKeyUpdate() .set(MODEL, modelString) - .set(TRIGGER, triggerString) .set(CREATOR, creator) .set(VERSION_NAME, versionName) .set(PIPELINE_VERSION, pipelineVersion) @@ -135,6 +132,49 @@ class PipelineResVersionDao { } } + fun getVersionResource( + dslContext: DSLContext, + projectId: String, + pipelineId: String, + version: Int?, + includeDraft: Boolean? = null + ): PipelineResourceVersion? { + with(T_PIPELINE_RESOURCE_VERSION) { + val where = dslContext.selectFrom(this) + .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) + if (version != null) { + where.and(VERSION.eq(version)) + } else { + // 非新的逻辑请求则保持旧逻辑 + if (includeDraft != true) where.and(DRAFT_FLAG.ne(true)) + where.orderBy(VERSION.desc()).limit(1) + } + val record = where.fetchAny() ?: return null + return PipelineResourceVersion( + projectId = record.projectId, + pipelineId = record.pipelineId, + version = record.version, + model = record.model?.let { str -> + try { + JsonUtil.to(str, Model::class.java) + } catch (ignore: Exception) { + null + } + } ?: return null, + creator = record.creator, + versionName = record.versionName, + createTime = record.createTime, + pipelineVersion = record.pipelineVersion, + triggerVersion = record.triggerVersion, + settingVersion = record.settingVersion, + referFlag = record.referFlag, + referCount = record.referCount, + draftFlag = record.draftFlag, + refs = record.refs + ) + } + } + fun deleteEarlyVersion( dslContext: DSLContext, projectId: String, @@ -192,7 +232,7 @@ class PipelineResVersionDao { settingVersion = it.settingVersion, draftFlag = it.draftFlag, debugBuildId = it.debugBuildId, - pacRefs = it.pacRefs + pacRefs = it.refs ) ) } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index ba8f78f64a0..a85a21fbde6 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -85,6 +85,7 @@ import com.tencent.devops.process.pojo.PipelineName import com.tencent.devops.process.pojo.PipelineSortType import com.tencent.devops.process.pojo.pipeline.DeletePipelineResult import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult +import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion import com.tencent.devops.process.pojo.pipeline.PipelineSubscriptionType import com.tencent.devops.process.pojo.setting.PipelineModelVersion import com.tencent.devops.process.pojo.setting.PipelineRunLockType @@ -779,13 +780,6 @@ class PipelineRepositoryService constructor( version = version - 1 ) if (!lastVersionModelStr.isNullOrEmpty()) { - val triggerStr = try { - val trigger = str2model(lastVersionModelStr, pipelineId) - ?.stages?.get(0)?.containers?.get(0) as TriggerContainer - JsonUtil.toJson(trigger, false) - } catch (ignore: Throwable) { - null - } pipelineResVersionDao.create( dslContext = transactionContext, projectId = projectId, @@ -793,7 +787,6 @@ class PipelineRepositoryService constructor( creator = userId, version = version - 1, modelString = lastVersionModelStr, - triggerString = triggerStr, pipelineVersion = null, triggerVersion = null, settingVersion = null, @@ -894,8 +887,7 @@ class PipelineRepositoryService constructor( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, - version = null, - includeDraft = includeDraft + version = null ) ?: return null } else { modelString = pipelineResVersionDao.getVersionModelString( @@ -918,13 +910,36 @@ class PipelineRepositoryService constructor( return str2model(modelString, pipelineId) } + fun getPipelineResourceVersion( + projectId: String, + pipelineId: String, + version: Int? = null, + includeDraft: Boolean? = false + ): PipelineResourceVersion? { + return if (version == null) { // 取最新版,直接从旧版本表读 + pipelineResDao.getLatestVersionResource( + dslContext = dslContext, + projectId = projectId, + pipelineId = pipelineId + ) ?: return null + } else { + pipelineResVersionDao.getVersionResource( + dslContext = dslContext, + projectId = projectId, + pipelineId = pipelineId, + version = version, + includeDraft = includeDraft + ) + } + } + private fun str2model( modelString: String, pipelineId: String ) = try { JsonUtil.to(modelString, Model::class.java) - } catch (exception: Exception) { - logger.warn("get process($pipelineId) model fail", exception) + } catch (ignore: Exception) { + logger.warn("get process($pipelineId) model fail", ignore) null } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index 66505241b30..27aa7368276 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -69,6 +69,7 @@ import com.tencent.devops.process.pojo.pipeline.BatchDeletePipeline import com.tencent.devops.process.pojo.pipeline.PipelineCount import com.tencent.devops.process.pojo.pipeline.enums.PipelineRuleBusCodeEnum import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting +import com.tencent.devops.process.pojo.setting.PipelineResourceAndSetting import com.tencent.devops.process.pojo.setting.PipelineSetting import com.tencent.devops.process.service.PipelineInfoFacadeService import com.tencent.devops.process.service.PipelineListFacadeService @@ -360,6 +361,30 @@ class UserPipelineResourceImpl @Autowired constructor( return Result(pipeline) } + override fun getPipelineResourceAndSetting( + userId: String, + projectId: String, + pipelineId: String, + includeDraft: Boolean? + ): Result { + checkParam(userId, projectId) + val resource = pipelineInfoFacadeService.getPipelineResourceVersion( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + includeDraft = includeDraft, + channelCode = ChannelCode.BS + ) + val setting = pipelineSettingFacadeService.userGetSetting( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + version = resource.settingVersion ?: resource.version + ) + pipelineRecentUseService.record(userId, projectId, pipelineId) + return Result(PipelineResourceAndSetting(resource, setting)) + } + override fun getVersion(userId: String, projectId: String, pipelineId: String, version: Int): Result { checkParam(userId, projectId) return Result( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index 0e66d8f7201..6b023e86de6 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -61,6 +61,7 @@ import com.tencent.devops.process.constant.ProcessMessageCode.USER_NEED_PIPELINE import com.tencent.devops.process.engine.compatibility.BuildPropertyCompatibilityTools import com.tencent.devops.process.engine.dao.PipelineInfoDao import com.tencent.devops.process.engine.dao.template.TemplateDao +import com.tencent.devops.process.engine.pojo.PipelineInfo import com.tencent.devops.process.engine.service.PipelineRepositoryService import com.tencent.devops.process.engine.utils.PipelineUtils import com.tencent.devops.process.jmx.api.ProcessJmxApi @@ -70,6 +71,7 @@ import com.tencent.devops.process.pojo.PipelineCopy import com.tencent.devops.process.pojo.classify.PipelineViewBulkAdd import com.tencent.devops.process.pojo.pipeline.DeletePipelineResult import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult +import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting import com.tencent.devops.process.pojo.setting.PipelineSetting import com.tencent.devops.process.pojo.template.TemplateType @@ -802,7 +804,7 @@ class PipelineInfoFacadeService @Autowired constructor( return pipelineResult } - fun getPipeline( + fun getPipelineResourceVersion( userId: String, projectId: String, pipelineId: String, @@ -810,7 +812,7 @@ class PipelineInfoFacadeService @Autowired constructor( version: Int? = null, checkPermission: Boolean = true, includeDraft: Boolean? = false - ): Model { + ): PipelineResourceVersion { if (checkPermission) { val permission = AuthPermission.VIEW pipelinePermissionService.validPipelinePermission( @@ -845,17 +847,82 @@ class PipelineInfoFacadeService @Autowired constructor( ) } - val model = pipelineRepositoryService.getModel( + val resource = pipelineRepositoryService.getPipelineResourceVersion( projectId = projectId, pipelineId = pipelineId, version = version, includeDraft = includeDraft + ) ?: throw ErrorCodeException( + statusCode = Response.Status.NOT_FOUND.statusCode, + errorCode = ProcessMessageCode.ERROR_PIPELINE_MODEL_NOT_EXISTS ) + val fixedModel = getFixedModel(resource.model, projectId, pipelineId, userId, pipelineInfo) + return resource.copy(model = fixedModel) + } + + fun getPipeline( + userId: String, + projectId: String, + pipelineId: String, + channelCode: ChannelCode, + version: Int? = null, + checkPermission: Boolean = true, + includeDraft: Boolean? = false + ): Model { + if (checkPermission) { + val permission = AuthPermission.VIEW + pipelinePermissionService.validPipelinePermission( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + permission = permission, + message = MessageUtil.getMessageByLocale( + USER_NOT_PERMISSIONS_OPERATE_PIPELINE, + I18nUtil.getLanguage(userId), + arrayOf( + userId, + projectId, + permission.getI18n(I18nUtil.getLanguage(userId)), + pipelineId + ) + ) + ) + } + + val pipelineInfo = pipelineRepositoryService.getPipelineInfo(projectId, pipelineId) ?: throw ErrorCodeException( statusCode = Response.Status.NOT_FOUND.statusCode, - errorCode = ProcessMessageCode.ERROR_PIPELINE_MODEL_NOT_EXISTS + errorCode = ProcessMessageCode.ERROR_PIPELINE_NOT_EXISTS ) + if (pipelineInfo.channelCode != channelCode) { + throw ErrorCodeException( + statusCode = Response.Status.NOT_FOUND.statusCode, + errorCode = ProcessMessageCode.ERROR_PIPELINE_CHANNEL_CODE, + params = arrayOf(pipelineInfo.channelCode.name) + ) + } + + val model = pipelineRepositoryService.getModel( + projectId = projectId, + pipelineId = pipelineId, + version = version, + includeDraft = includeDraft + ) ?: throw ErrorCodeException( + statusCode = Response.Status.NOT_FOUND.statusCode, + errorCode = ProcessMessageCode.ERROR_PIPELINE_MODEL_NOT_EXISTS + ) + + return getFixedModel(model, projectId, pipelineId, userId, pipelineInfo) + } + + private fun getFixedModel( + model: Model, + projectId: String, + pipelineId: String, + userId: String, + pipelineInfo: PipelineInfo + ): Model { try { val triggerContainer = model.stages[0].containers[0] as TriggerContainer val buildNo = triggerContainer.buildNo From 9eb7918cb0ae9cd564d02a178c3893d48c22c2d5 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 6 Jul 2023 17:42:47 +0800 Subject: [PATCH 014/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20setting=E8=A1=A8=E7=89=88=E6=9C=AC=E5=8F=B7=E8=A7=A3?= =?UTF-8?q?=E7=BB=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/process/api/user/UserPipelineResource.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt index fbbdf32627e..c127e76d8e7 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt @@ -269,7 +269,7 @@ interface UserPipelineResource { @ApiOperation("获取流水线编排和设置") @GET - @Path("/projects/{projectId}/pipelines/{pipelineId}/") + @Path("/projects/{projectId}/pipelines/{pipelineId}/resource") fun getPipelineResourceAndSetting( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) From ab0e2ceb78729a9ca626445b762ec8a044426240 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 6 Jul 2023 21:19:03 +0800 Subject: [PATCH 015/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20setting=E8=A1=A8=E7=89=88=E6=9C=AC=E5=8F=B7=E8=A7=A3?= =?UTF-8?q?=E7=BB=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pojo/pipeline/PipelineResourceVersion.kt | 2 +- .../pojo/setting/PipelineSettingVersion.kt | 4 + .../devops/process/dao/PipelineSettingDao.kt | 114 ++++++++++++++--- .../process/dao/PipelineSettingVersionDao.kt | 119 +++++++++++++----- .../service/PipelineRepositoryService.kt | 82 ++---------- .../engine/service/PipelineSettingService.kt | 6 +- .../process/service/PipelineAsCodeService.kt | 9 +- .../service/pipeline/PipelineStatusService.kt | 2 +- .../api/ServicePipelineResourceImpl.kt | 2 + .../process/api/UserPipelineResourceImpl.kt | 8 +- .../api/UserPipelineSettingResourceImpl.kt | 9 +- .../api/op/OpPipelineSettingResourceImpl.kt | 9 +- .../service/PipelineInfoFacadeService.kt | 27 ++-- .../service/PipelineSettingVersionService.kt | 38 +----- .../pipeline/PipelineSettingFacadeService.kt | 33 +++-- .../service/template/TemplateFacadeService.kt | 17 ++- 16 files changed, 288 insertions(+), 193 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt index 8ff96ada9a5..7c1c108ccff 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt @@ -62,5 +62,5 @@ data class PipelineResourceVersion( @ApiModelProperty("草稿版本标识", required = false) val draftFlag: Boolean? = false, @ApiModelProperty("分支版本标识", required = false) - val refs: String? = null, + val refs: String? = null ) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSettingVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSettingVersion.kt index 3467340f535..223a5b03656 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSettingVersion.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSettingVersion.kt @@ -40,6 +40,10 @@ data class PipelineSettingVersion( var successSubscription: Subscription = Subscription(), @ApiModelProperty("订阅失败", required = false) var failSubscription: Subscription = Subscription(), + @ApiModelProperty("订阅成功相关", required = false) + var successSubscriptionList: List? = listOf(Subscription()), + @ApiModelProperty("订阅失败相关", required = false) + var failSubscriptionList: List? = listOf(Subscription()), @ApiModelProperty("版本", required = false) var version: Int = 0 ) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt index 28dd9dcf135..d16aa1d1d4c 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt @@ -27,6 +27,7 @@ package com.tencent.devops.process.dao +import com.fasterxml.jackson.core.type.TypeReference import com.tencent.devops.common.api.pojo.PipelineAsCodeSettings import com.tencent.devops.common.api.util.DateTimeUtil import com.tencent.devops.common.api.util.JsonUtil @@ -46,6 +47,7 @@ import org.jooq.Condition import org.jooq.DSLContext import org.jooq.Record1 import org.jooq.Record4 +import org.jooq.RecordMapper import org.jooq.Result import org.springframework.stereotype.Repository @@ -105,7 +107,7 @@ class PipelineSettingDao { PIPELINE_AS_CODE_SETTINGS, SUCCESS_SUBSCRIPTION, FAILURE_SUBSCRIPTION, - SETTING_VERSION + VERSION ) .values( projectId, @@ -184,7 +186,7 @@ class PipelineSettingDao { PIPELINE_AS_CODE_SETTINGS, SUCCESS_SUBSCRIPTION, FAILURE_SUBSCRIPTION, - SETTING_VERSION + VERSION ).values( setting.projectId, setting.pipelineName, @@ -254,7 +256,7 @@ class PipelineSettingDao { .set(CLEAN_VARIABLES_WHEN_RETRY, setting.cleanVariablesWhenRetry) .set(SUCCESS_SUBSCRIPTION, JsonUtil.toJson(successSubscriptionList, false)) .set(FAILURE_SUBSCRIPTION, JsonUtil.toJson(failSubscriptionList, false)) - .set(SETTING_VERSION, setting.version) + .set(VERSION, setting.version) // pipelineAsCodeSettings 默认传空不更新 setting.pipelineAsCodeSettings?.let { self -> updateSetMoreStep.set(PIPELINE_AS_CODE_SETTINGS, JsonUtil.toJson(self, false)) @@ -270,11 +272,30 @@ class PipelineSettingDao { } } - fun getSetting(dslContext: DSLContext, projectId: String, pipelineId: String): TPipelineSettingRecord? { + fun getSetting( + dslContext: DSLContext, + projectId: String, + pipelineId: String + ): PipelineSetting? { with(TPipelineSetting.T_PIPELINE_SETTING) { return dslContext.selectFrom(this) .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) - .fetchOne() + .fetchOne(mapper) + } + } + + fun getPipelineAsCodeSettings( + dslContext: DSLContext, + projectId: String, + pipelineId: String + ): PipelineAsCodeSettings? { + with(TPipelineSetting.T_PIPELINE_SETTING) { + return dslContext.select(PIPELINE_AS_CODE_SETTINGS) + .from(this) + .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) + .fetchOne()?.component1()?.let { self -> + JsonUtil.to(self, PipelineAsCodeSettings::class.java) + } } } @@ -282,7 +303,7 @@ class PipelineSettingDao { dslContext: DSLContext, pipelineIds: Set, projectId: String? = null - ): Result { + ): List { with(TPipelineSetting.T_PIPELINE_SETTING) { val conditions = mutableListOf() conditions.add(PIPELINE_ID.`in`(pipelineIds)) @@ -291,7 +312,7 @@ class PipelineSettingDao { } return dslContext.selectFrom(this) .where(conditions) - .fetch() + .fetch(mapper) } } @@ -327,18 +348,17 @@ class PipelineSettingDao { name: String, pipelineId: String? = null, isTemplate: Boolean = false - ): Result { + ): List { with(TPipelineSetting.T_PIPELINE_SETTING) { - val conditions = - mutableListOf( - PROJECT_ID.eq(projectId), - NAME.eq(name), - IS_TEMPLATE.eq(isTemplate) - ) + val conditions = mutableListOf( + PROJECT_ID.eq(projectId), + NAME.eq(name), + IS_TEMPLATE.eq(isTemplate) + ) if (!pipelineId.isNullOrBlank()) conditions.add(PIPELINE_ID.eq(pipelineId)) return dslContext.selectFrom(this) .where(conditions) - .fetch() + .fetch(mapper) } } @@ -424,4 +444,68 @@ class PipelineSettingDao { return update.execute() } } + + class PipelineSettingJooqMapper : RecordMapper { + override fun map(record: TPipelineSettingRecord?): PipelineSetting? { + return record?.let { t -> + val successType = t.successType?.split(",")?.filter { i -> i.isNotBlank() } + ?.map { type -> PipelineSubscriptionType.valueOf(type) }?.toSet() ?: emptySet() + val failType = t.failType?.split(",")?.filter { i -> i.isNotBlank() } + ?.map { type -> PipelineSubscriptionType.valueOf(type) }?.toSet() ?: emptySet() + val oldSuccessSubscription = Subscription( + types = successType, + groups = t.successGroup?.split(",")?.toSet() ?: emptySet(), + users = t.successReceiver ?: "", + wechatGroupFlag = t.successWechatGroupFlag ?: false, + wechatGroup = t.successWechatGroup ?: "", + wechatGroupMarkdownFlag = t.successWechatGroupMarkdownFlag, + detailFlag = t.successDetailFlag, + content = t.successContent ?: "" + ) + val oldFailSubscription = Subscription( + types = failType, + groups = t.failGroup?.split(",")?.toSet() ?: emptySet(), + users = t.failReceiver ?: "", + wechatGroupFlag = t.failWechatGroupFlag ?: false, + wechatGroup = t.failWechatGroup ?: "", + wechatGroupMarkdownFlag = t.failWechatGroupMarkdownFlag ?: false, + detailFlag = t.failDetailFlag, + content = t.failContent ?: "" + ) + val successSubscriptionList = t.successSubscription?.let { + JsonUtil.to(it, object : TypeReference>() {}) + } ?: listOf(oldSuccessSubscription) + val failSubscriptionList = t.failureSubscription?.let { + JsonUtil.to(it, object : TypeReference>() {}) + } ?: listOf(oldFailSubscription) + PipelineSetting( + projectId = t.projectId, + pipelineId = t.pipelineId, + pipelineName = t.name, + desc = t.desc, + runLockType = PipelineRunLockType.valueOf(t.runLockType), + successSubscription = oldSuccessSubscription, + failSubscription = oldFailSubscription, + successSubscriptionList = successSubscriptionList, + failSubscriptionList = failSubscriptionList, + labels = emptyList(), + waitQueueTimeMinute = DateTimeUtil.secondToMinute(t.waitQueueTimeSecond ?: 600000), + maxQueueSize = t.maxQueueSize, + maxPipelineResNum = t.maxPipelineResNum, + maxConRunningQueueSize = t.maxConRunningQueueSize, + buildNumRule = t.buildNumRule, + concurrencyCancelInProgress = t.concurrencyCancelInProgress, + concurrencyGroup = t.concurrencyGroup, + cleanVariablesWhenRetry = t.cleanVariablesWhenRetry, + pipelineAsCodeSettings = t.pipelineAsCodeSettings?.let { self -> + JsonUtil.to(self, PipelineAsCodeSettings::class.java) + } + ) + } + } + } + + companion object { + private val mapper = PipelineSettingJooqMapper() + } } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingVersionDao.kt index 91da1a2bcc1..a7cc0c66e39 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingVersionDao.kt @@ -27,14 +27,19 @@ package com.tencent.devops.process.dao +import com.fasterxml.jackson.core.type.TypeReference +import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.notify.enums.NotifyType import com.tencent.devops.model.process.tables.TPipelineSettingVersion import com.tencent.devops.model.process.tables.records.TPipelineSettingVersionRecord +import com.tencent.devops.process.pojo.pipeline.PipelineSubscriptionType import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.process.pojo.setting.PipelineSettingVersion +import com.tencent.devops.process.pojo.setting.Subscription import com.tencent.devops.process.util.NotifyTemplateUtils import com.tencent.devops.process.utils.PIPELINE_START_USER_NAME import org.jooq.DSLContext -import org.jooq.Result +import org.jooq.RecordMapper import org.springframework.stereotype.Repository @Suppress("LongParameterList") @@ -95,6 +100,8 @@ class PipelineSettingVersionDao { isTemplate: Boolean = false, id: Long? = null ): Int { + val successSubscriptionList = setting.successSubscriptionList ?: listOf(setting.successSubscription) + val failSubscriptionList = setting.failSubscriptionList ?: listOf(setting.failSubscription) with(TPipelineSettingVersion.T_PIPELINE_SETTING_VERSION) { return dslContext.insertInto( this, @@ -116,56 +123,61 @@ class PipelineSettingVersionDao { FAIL_CONTENT, IS_TEMPLATE, VERSION, - ID - ) - .values( - setting.projectId, - setting.pipelineId, - setting.successSubscription.users, - setting.failSubscription.users, - setting.successSubscription.groups.joinToString(","), - setting.failSubscription.groups.joinToString(","), - setting.successSubscription.types.joinToString(",") { it.name }, - setting.failSubscription.types.joinToString(",") { it.name }, - setting.failSubscription.wechatGroupFlag, - setting.failSubscription.wechatGroup, - setting.successSubscription.wechatGroupFlag, - setting.successSubscription.wechatGroup, - setting.successSubscription.detailFlag, - setting.failSubscription.detailFlag, - setting.successSubscription.content, - setting.failSubscription.content, - isTemplate, - version, - id - ) + ID, + SUCCESS_SUBSCRIPTION, + FAILURE_SUBSCRIPTION + ).values( + setting.projectId, + setting.pipelineId, + setting.successSubscription.users, + setting.failSubscription.users, + setting.successSubscription.groups.joinToString(","), + setting.failSubscription.groups.joinToString(","), + setting.successSubscription.types.joinToString(",") { it.name }, + setting.failSubscription.types.joinToString(",") { it.name }, + setting.failSubscription.wechatGroupFlag, + setting.failSubscription.wechatGroup, + setting.successSubscription.wechatGroupFlag, + setting.successSubscription.wechatGroup, + setting.successSubscription.detailFlag, + setting.failSubscription.detailFlag, + setting.successSubscription.content, + setting.failSubscription.content, + isTemplate, + version, + id, + JsonUtil.toJson(successSubscriptionList, false), + JsonUtil.toJson(failSubscriptionList, false) + ).onDuplicateKeyUpdate() + .set(SUCCESS_SUBSCRIPTION, JsonUtil.toJson(successSubscriptionList, false)) + .set(FAILURE_SUBSCRIPTION, JsonUtil.toJson(failSubscriptionList, false)) .execute() } } - fun getSetting( + fun getSettingVersion( dslContext: DSLContext, projectId: String, pipelineId: String, version: Int - ): TPipelineSettingVersionRecord? { + ): PipelineSettingVersion? { with(TPipelineSettingVersion.T_PIPELINE_SETTING_VERSION) { return dslContext.selectFrom(this) .where(PIPELINE_ID.eq(pipelineId)) .and(VERSION.eq(version)) .and(PROJECT_ID.eq(projectId)) - .fetchOne() + .fetchOne(mapper) } } fun getSettingByPipelineIds( dslContext: DSLContext, pipelineIds: List - ): Result { + ): List { with(TPipelineSettingVersion.T_PIPELINE_SETTING_VERSION) { return dslContext.selectFrom(this) .where(PIPELINE_ID.`in`(pipelineIds)) - .fetch() + .fetch(mapper) } } @@ -207,4 +219,53 @@ class PipelineSettingVersionDao { .execute() } } + + class PipelineSettingVersionJooqMapper : RecordMapper { + override fun map(record: TPipelineSettingVersionRecord?): PipelineSettingVersion? { + return record?.let { t -> + val successType = t.successType?.split(",")?.filter { i -> i.isNotBlank() } + ?.map { type -> PipelineSubscriptionType.valueOf(type) }?.toSet() ?: emptySet() + val failType = t.failType?.split(",")?.filter { i -> i.isNotBlank() } + ?.map { type -> PipelineSubscriptionType.valueOf(type) }?.toSet() ?: emptySet() + val oldSuccessSubscription = Subscription( + types = successType, + groups = t.successGroup?.split(",")?.toSet() ?: emptySet(), + users = t.successReceiver ?: "", + wechatGroupFlag = t.successWechatGroupFlag ?: false, + wechatGroup = t.successWechatGroup ?: "", + wechatGroupMarkdownFlag = t.successWechatGroupMarkdownFlag, + detailFlag = t.successDetailFlag, + content = t.successContent ?: "" + ) + val oldFailSubscription = Subscription( + types = failType, + groups = t.failGroup?.split(",")?.toSet() ?: emptySet(), + users = t.failReceiver ?: "", + wechatGroupFlag = t.failWechatGroupFlag ?: false, + wechatGroup = t.failWechatGroup ?: "", + wechatGroupMarkdownFlag = t.failWechatGroupMarkdownFlag ?: false, + detailFlag = t.failDetailFlag, + content = t.failContent ?: "" + ) + val successSubscriptionList = t.successSubscription?.let { + JsonUtil.to(it, object : TypeReference>() {}) + } ?: listOf(oldSuccessSubscription) + val failSubscriptionList = t.failureSubscription?.let { + JsonUtil.to(it, object : TypeReference>() {}) + } ?: listOf(oldFailSubscription) + PipelineSettingVersion( + projectId = t.projectId, + pipelineId = t.pipelineId, + successSubscription = oldSuccessSubscription, + failSubscription = oldFailSubscription, + successSubscriptionList = successSubscriptionList, + failSubscriptionList = failSubscriptionList + ) + } + } + } + + companion object { + private val mapper = PipelineSettingVersionJooqMapper() + } } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index a85a21fbde6..788eee5101d 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -27,13 +27,10 @@ package com.tencent.devops.process.engine.service -import com.fasterxml.jackson.core.type.TypeReference import com.fasterxml.jackson.databind.ObjectMapper import com.tencent.devops.common.api.exception.DependNotFoundException import com.tencent.devops.common.api.exception.ErrorCodeException import com.tencent.devops.common.api.exception.InvalidParamException -import com.tencent.devops.common.api.pojo.PipelineAsCodeSettings -import com.tencent.devops.common.api.util.DateTimeUtil import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.api.util.Watcher @@ -86,11 +83,8 @@ import com.tencent.devops.process.pojo.PipelineSortType import com.tencent.devops.process.pojo.pipeline.DeletePipelineResult import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion -import com.tencent.devops.process.pojo.pipeline.PipelineSubscriptionType import com.tencent.devops.process.pojo.setting.PipelineModelVersion -import com.tencent.devops.process.pojo.setting.PipelineRunLockType import com.tencent.devops.process.pojo.setting.PipelineSetting -import com.tencent.devops.process.pojo.setting.Subscription import com.tencent.devops.process.utils.PIPELINE_MATRIX_CON_RUNNING_SIZE_MAX import com.tencent.devops.project.api.service.ServiceAllocIdResource import com.tencent.devops.project.api.service.ServiceProjectResource @@ -162,6 +156,7 @@ class PipelineRepositoryService constructor( useTemplateSettings: Boolean? = false, templateId: String? = null, updateLastModifyUser: Boolean? = true, + savedSetting: PipelineSetting? = null, saveDraft: Boolean? = false ): DeployPipelineResult { @@ -192,7 +187,8 @@ class PipelineRepositoryService constructor( } return if (!create) { - val pipelineSetting = pipelineSettingDao.getSetting(dslContext, projectId, pipelineId) + val pipelineSetting = savedSetting + ?: pipelineSettingDao.getSetting(dslContext, projectId, pipelineId) update( projectId = projectId, pipelineId = pipelineId, @@ -203,7 +199,7 @@ class PipelineRepositoryService constructor( buildNo = buildNo, modelTasks = modelTasks, channelCode = channelCode, - maxPipelineResNum = pipelineSetting?.maxPipelineResNum, + setting = pipelineSetting, updateLastModifyUser = updateLastModifyUser, saveDraft = saveDraft ) @@ -663,7 +659,7 @@ class PipelineRepositoryService constructor( buildNo: BuildNo?, modelTasks: Collection, channelCode: ChannelCode, - maxPipelineResNum: Int? = null, + setting: PipelineSetting? = null, updateLastModifyUser: Boolean? = true, saveDraft: Boolean? = false ): DeployPipelineResult { @@ -718,7 +714,7 @@ class PipelineRepositoryService constructor( ) var pipelineVersion = latestResRecord?.pipelineVersion ?: version var triggerVersion = latestResRecord?.triggerVersion ?: version - var settingVersion = latestResRecord?.settingVersion ?: version + val settingVersion = setting?.version ?: latestResRecord?.settingVersion ?: version latestResRecord?.let { val originModel = try { objectMapper.readValue(it.model, Model::class.java) @@ -806,13 +802,13 @@ class PipelineRepositoryService constructor( pipelineId = pipelineId, beforeVersion = version ) - if (maxPipelineResNum != null) { + setting?.maxPipelineResNum?.let { pipelineResVersionDao.deleteEarlyVersion( dslContext = transactionContext, projectId = projectId, pipelineId = pipelineId, currentVersion = version, - maxPipelineResNum = maxPipelineResNum + maxPipelineResNum = it ) } pipelineModelTaskDao.batchSave(transactionContext, modelTasks) @@ -1135,64 +1131,8 @@ class PipelineRepositoryService constructor( return pipelineBuildSummaryDao.get(dslContext, projectId, pipelineId)?.buildNo } - @Suppress("ComplexMethod", "MagicNumber") fun getSetting(projectId: String, pipelineId: String): PipelineSetting? { - val t = pipelineSettingDao.getSetting(dslContext, projectId, pipelineId) - return if (t != null) { - val successType = t.successType?.split(",")?.filter { i -> i.isNotBlank() } - ?.map { type -> PipelineSubscriptionType.valueOf(type) }?.toSet() ?: emptySet() - val failType = t.failType?.split(",")?.filter { i -> i.isNotBlank() } - ?.map { type -> PipelineSubscriptionType.valueOf(type) }?.toSet() ?: emptySet() - val oldSuccessSubscription = Subscription( - types = successType, - groups = t.successGroup?.split(",")?.toSet() ?: emptySet(), - users = t.successReceiver ?: "", - wechatGroupFlag = t.successWechatGroupFlag ?: false, - wechatGroup = t.successWechatGroup ?: "", - wechatGroupMarkdownFlag = t.successWechatGroupMarkdownFlag, - detailFlag = t.successDetailFlag, - content = t.successContent ?: "" - ) - val oldFailSubscription = Subscription( - types = failType, - groups = t.failGroup?.split(",")?.toSet() ?: emptySet(), - users = t.failReceiver ?: "", - wechatGroupFlag = t.failWechatGroupFlag ?: false, - wechatGroup = t.failWechatGroup ?: "", - wechatGroupMarkdownFlag = t.failWechatGroupMarkdownFlag ?: false, - detailFlag = t.failDetailFlag, - content = t.failContent ?: "" - ) - val successSubscriptionList = t.successSubscription?.let { - JsonUtil.to(it, object : TypeReference>() {}) - } ?: listOf(oldSuccessSubscription) - val failSubscriptionList = t.failureSubscription?.let { - JsonUtil.to(it, object : TypeReference>() {}) - } ?: listOf(oldFailSubscription) - PipelineSetting( - projectId = t.projectId, - pipelineId = t.pipelineId, - pipelineName = t.name, - desc = t.desc, - runLockType = PipelineRunLockType.valueOf(t.runLockType), - successSubscription = oldSuccessSubscription, - failSubscription = oldFailSubscription, - successSubscriptionList = successSubscriptionList, - failSubscriptionList = failSubscriptionList, - labels = emptyList(), - waitQueueTimeMinute = DateTimeUtil.secondToMinute(t.waitQueueTimeSecond ?: 600000), - maxQueueSize = t.maxQueueSize, - maxPipelineResNum = t.maxPipelineResNum, - maxConRunningQueueSize = t.maxConRunningQueueSize, - buildNumRule = t.buildNumRule, - concurrencyCancelInProgress = t.concurrencyCancelInProgress, - concurrencyGroup = t.concurrencyGroup, - cleanVariablesWhenRetry = t.cleanVariablesWhenRetry, - pipelineAsCodeSettings = t.pipelineAsCodeSettings?.let { self -> - JsonUtil.to(self, PipelineAsCodeSettings::class.java) - } - ) - } else null + return pipelineSettingDao.getSetting(dslContext, projectId, pipelineId) } fun saveSetting( @@ -1223,8 +1163,8 @@ class PipelineRepositoryService constructor( projectId = setting.projectId, pipelineId = setting.pipelineId ) - if (old?.name != null) { - oldName = old.name + if (old?.pipelineName != null) { + oldName = old.pipelineName } pipelineInfoDao.update( dslContext = context, diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineSettingService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineSettingService.kt index 6c5d957ff48..0d3e99f42ac 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineSettingService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineSettingService.kt @@ -60,9 +60,9 @@ class PipelineSettingService @Autowired constructor( setting == null -> { TimeUnit.HOURS.toMillis(1) } - setting.runLockType == PipelineRunLockType.toValue(PipelineRunLockType.SINGLE) || - setting.runLockType == PipelineRunLockType.toValue(PipelineRunLockType.GROUP_LOCK) -> { - TimeUnit.SECONDS.toMillis(setting.waitQueueTimeSecond.toLong()) + setting.runLockType == PipelineRunLockType.SINGLE || + setting.runLockType == PipelineRunLockType.GROUP_LOCK -> { + TimeUnit.MINUTES.toMillis(setting.waitQueueTimeMinute.toLong()) } else -> { TimeUnit.HOURS.toMillis(1) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineAsCodeService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineAsCodeService.kt index 9dedb031adc..adc8f3466c0 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineAsCodeService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineAsCodeService.kt @@ -28,7 +28,6 @@ package com.tencent.devops.process.service import com.github.benmanes.caffeine.cache.Caffeine -import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.process.dao.PipelineSettingDao import com.tencent.devops.common.api.pojo.PipelineAsCodeSettings import org.jooq.DSLContext @@ -71,10 +70,6 @@ class PipelineAsCodeService @Autowired constructor( pipelineId: String ) = asCodeEnabledCache.get(getPipelineCacheKey(projectId, pipelineId)) - fun getPipelineAsCodeSettings(projectId: String, pipelineId: String): PipelineAsCodeSettings? { - return pipelineSettingDao.getSetting(dslContext, projectId, pipelineId) - ?.pipelineAsCodeSettings?.let { self -> - JsonUtil.to(self, PipelineAsCodeSettings::class.java) - } - } + fun getPipelineAsCodeSettings(projectId: String, pipelineId: String): PipelineAsCodeSettings? = + pipelineSettingDao.getPipelineAsCodeSettings(dslContext, projectId, pipelineId) } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineStatusService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineStatusService.kt index 687ef92c1d8..c89720a432b 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineStatusService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineStatusService.kt @@ -95,7 +95,7 @@ class PipelineStatusService( latestBuildStartTime = (pipelineBuildSummary.latestStartTime)?.timestampmilli() ?: 0, latestBuildStatus = pipelineBuildStatus, latestBuildTaskName = pipelineBuildSummary.latestTaskName, - lock = PipelineRunLockType.checkLock(pipelineSetting.runLockType), + lock = PipelineRunLockType.checkLock(pipelineSetting.runLockType.ordinal), runningBuildCount = pipelineBuildSummary.runningCount ?: 0, lastBuildFinishCount = lastBuildFinishCount, lastBuildTotalCount = lastBuildTotalCount, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt index 4e84ac61f48..0a50b7fc4d5 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt @@ -332,6 +332,8 @@ class ServicePipelineResourceImpl @Autowired constructor( setting.checkParam() pipelineSettingFacadeService.saveSetting( userId = userId, + projectId = projectId, + pipelineId = pipelineId, setting = setting.copy(projectId, pipelineId), checkPermission = ChannelCode.isNeedAuth(channelCode ?: ChannelCode.BS), updateLastModifyUser = updateLastModifyUser diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index 27aa7368276..5183254b1dc 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -316,7 +316,13 @@ class UserPipelineResourceImpl @Autowired constructor( setting: PipelineSetting ): Result { checkParam(userId, projectId) - pipelineSettingFacadeService.saveSetting(userId = userId, setting = setting, checkPermission = true) + pipelineSettingFacadeService.saveSetting( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + setting = setting, + checkPermission = true + ) auditService.createAudit( Audit( resourceType = AuthResourceType.PIPELINE_DEFAULT.value, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineSettingResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineSettingResourceImpl.kt index 669d89d7b7a..9bffa61d47c 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineSettingResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineSettingResourceImpl.kt @@ -40,7 +40,14 @@ class UserPipelineSettingResourceImpl @Autowired constructor( private val pipelineSettingFacadeService: PipelineSettingFacadeService ) : UserPipelineSettingResource { override fun saveSetting(userId: String, setting: PipelineSetting): Result { - return Result(pipelineSettingFacadeService.saveSetting(userId, setting)) + return Result( + pipelineSettingFacadeService.saveSetting( + userId = userId, + projectId = setting.projectId, + pipelineId = setting.pipelineId, + setting = setting + ).pipelineId + ) } override fun getSetting( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/op/OpPipelineSettingResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/op/OpPipelineSettingResourceImpl.kt index 2d83d4027a5..6fb0f83108f 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/op/OpPipelineSettingResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/op/OpPipelineSettingResourceImpl.kt @@ -60,7 +60,14 @@ class OpPipelineSettingResourceImpl @Autowired constructor( private val logger = LoggerFactory.getLogger(OpPipelineSettingResourceImpl::class.java) override fun updateSetting(userId: String, setting: PipelineSetting): Result { - return Result(pipelineSettingFacadeService.saveSetting(userId = userId, setting = setting)) + return Result( + pipelineSettingFacadeService.saveSetting( + userId = userId, + projectId = setting.projectId, + pipelineId = setting.pipelineId, + setting = setting + ).pipelineId + ) } override fun getSetting(userId: String, projectId: String, pipelineId: String): Result { diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index 6b023e86de6..2ab2d99d45c 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -210,6 +210,8 @@ class PipelineInfoFacadeService @Autowired constructor( // setting pipeline需替换成新流水线的 pipelineSettingFacadeService.saveSetting( userId = userId, + projectId = projectId, + pipelineId = newSetting.pipelineId, setting = newSetting, checkPermission = true, dispatchPipelineUpdateEvent = false @@ -620,6 +622,8 @@ class PipelineInfoFacadeService @Autowired constructor( // 复制setting到新流水线 pipelineSettingFacadeService.saveSetting( userId = userId, + projectId = projectId, + pipelineId = pipelineId, setting = newSetting, dispatchPipelineUpdateEvent = false, updateLabels = false @@ -657,6 +661,7 @@ class PipelineInfoFacadeService @Autowired constructor( checkPermission: Boolean = true, checkTemplate: Boolean = true, updateLastModifyUser: Boolean? = true, + savedSetting: PipelineSetting? = null, saveDraft: Boolean? = false ): DeployPipelineResult { if (checkTemplate && templateService.isTemplatePipeline(projectId, pipelineId)) { @@ -737,6 +742,7 @@ class PipelineInfoFacadeService @Autowired constructor( channelCode = channelCode, create = false, updateLastModifyUser = updateLastModifyUser, + savedSetting = savedSetting, saveDraft = saveDraft ) if (checkPermission) { @@ -762,6 +768,8 @@ class PipelineInfoFacadeService @Autowired constructor( setting.pipelineName = name pipelineSettingFacadeService.saveSetting( userId = userId, + projectId = projectId, + pipelineId = pipelineId, setting = setting, checkPermission = true, dispatchPipelineUpdateEvent = true @@ -779,6 +787,15 @@ class PipelineInfoFacadeService @Autowired constructor( checkTemplate: Boolean = true, saveDraft: Boolean? = false ): DeployPipelineResult { + val savedSetting = pipelineSettingFacadeService.saveSetting( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + setting = setting, + checkPermission = false, + dispatchPipelineUpdateEvent = false, + saveDraft = saveDraft + ) val pipelineResult = editPipeline( userId = userId, projectId = projectId, @@ -787,20 +804,14 @@ class PipelineInfoFacadeService @Autowired constructor( channelCode = channelCode, checkPermission = checkPermission, checkTemplate = checkTemplate, + savedSetting = savedSetting, saveDraft = saveDraft ) if (setting.projectId.isBlank()) { setting.projectId = projectId } setting.pipelineId = pipelineResult.pipelineId // fix 用户端可能不传入pipelineId的问题,或者传错的问题 - val settingVersion = pipelineSettingFacadeService.saveSetting( - userId = userId, - setting = setting, - checkPermission = false, - version = pipelineResult.version, - dispatchPipelineUpdateEvent = false, - saveDraft = saveDraft - ) + return pipelineResult } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineSettingVersionService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineSettingVersionService.kt index e695f228a52..661dea4c2cb 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineSettingVersionService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineSettingVersionService.kt @@ -28,11 +28,8 @@ package com.tencent.devops.process.service import com.tencent.devops.common.pipeline.enums.ChannelCode -import com.tencent.devops.model.process.tables.TPipelineSettingVersion import com.tencent.devops.process.dao.PipelineSettingVersionDao -import com.tencent.devops.process.pojo.pipeline.PipelineSubscriptionType import com.tencent.devops.process.pojo.setting.PipelineSettingVersion -import com.tencent.devops.process.pojo.setting.Subscription import org.jooq.DSLContext import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service @@ -50,42 +47,11 @@ class PipelineSettingVersionService @Autowired constructor( version: Int, channelCode: ChannelCode = ChannelCode.BS ): PipelineSettingVersion { - val it = pipelineSettingVersionDao.getSetting( + return pipelineSettingVersionDao.getSettingVersion( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, version = version - ) - val setting = PipelineSettingVersion(projectId = projectId, pipelineId = pipelineId, version = version) - if (it != null) { - with(TPipelineSettingVersion.T_PIPELINE_SETTING_VERSION) { - val successType = it.get(SUCCESS_TYPE).split(",").filter { i -> i.isNotBlank() } - .map { type -> PipelineSubscriptionType.valueOf(type) }.toSet() - val failType = it.get(FAIL_TYPE).split(",").filter { i -> i.isNotBlank() } - .map { type -> PipelineSubscriptionType.valueOf(type) }.toSet() - - setting.successSubscription = Subscription( - types = successType, - groups = it.get(SUCCESS_GROUP).split(",").toSet(), - users = it.get(SUCCESS_RECEIVER), - wechatGroupFlag = it.get(SUCCESS_WECHAT_GROUP_FLAG), - wechatGroup = it.get(SUCCESS_WECHAT_GROUP), - wechatGroupMarkdownFlag = it.get(SUCCESS_WECHAT_GROUP_MARKDOWN_FLAG), - detailFlag = it.get(SUCCESS_DETAIL_FLAG), - content = it.get(SUCCESS_CONTENT) ?: "" - ) - setting.failSubscription = Subscription( - types = failType, - groups = it.get(FAIL_GROUP).split(",").toSet(), - users = it.get(FAIL_RECEIVER), - wechatGroupFlag = it.get(FAIL_WECHAT_GROUP_FLAG), - wechatGroup = it.get(FAIL_WECHAT_GROUP), - wechatGroupMarkdownFlag = it.get(FAIL_WECHAT_GROUP_MARKDOWN_FLAG), - detailFlag = it.get(FAIL_DETAIL_FLAG), - content = it.get(FAIL_CONTENT) ?: "" - ) - } - } - return setting + ) ?: PipelineSettingVersion(projectId = projectId, pipelineId = pipelineId, version = version) } } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt index f3a2ec40ea4..9d23bb86676 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt @@ -61,6 +61,7 @@ import com.tencent.devops.process.pojo.setting.UpdatePipelineModelRequest import com.tencent.devops.process.service.PipelineSettingVersionService import com.tencent.devops.process.service.label.PipelineGroupService import com.tencent.devops.process.service.view.PipelineViewGroupService +import org.json.JSONObject import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service @@ -86,39 +87,51 @@ class PipelineSettingFacadeService @Autowired constructor( */ fun saveSetting( userId: String, + projectId: String, + pipelineId: String, setting: PipelineSetting, checkPermission: Boolean = true, - version: Int = 0, updateLastModifyUser: Boolean? = true, dispatchPipelineUpdateEvent: Boolean = true, updateLabels: Boolean = true, saveDraft: Boolean? = false - ): Int { - // TODO #8161 增加配置的版本管理 + ): PipelineSetting { if (checkPermission) { val language = I18nUtil.getLanguage(userId) val permission = AuthPermission.EDIT checkEditPermission( userId = userId, - projectId = setting.projectId, - pipelineId = setting.pipelineId, + projectId = projectId, + pipelineId = pipelineId, message = MessageUtil.getMessageByLocale( CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, language, arrayOf( userId, - setting.projectId, + projectId, permission.getI18n(language), - setting.pipelineId + pipelineId ) ) ) } + val settingVersion = pipelineRepositoryService.getSetting( + projectId = projectId, + pipelineId = pipelineId + )?.let { origin -> + val originJson = JSONObject(origin) + val currentJson = JSONObject(setting) + if (currentJson.similar(originJson)) { + origin.version + } else { + origin.version + 1 + } + } ?: 1 val pipelineName = pipelineRepositoryService.saveSetting( userId = userId, setting = setting, - version = version, + version = settingVersion, updateLastModifyUser = updateLastModifyUser ) @@ -162,12 +175,12 @@ class PipelineSettingFacadeService @Autowired constructor( source = "update_pipeline", projectId = setting.projectId, pipelineId = setting.pipelineId, - version = version, + version = settingVersion, userId = userId ) ) } - return setting.version + return setting.copy(version = settingVersion) } fun userGetSetting( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt index ca8db332764..e8b6d99fcf3 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt @@ -62,7 +62,6 @@ import com.tencent.devops.common.pipeline.utils.RepositoryConfigUtils import com.tencent.devops.common.redis.RedisOperation import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.model.process.tables.TTemplate -import com.tencent.devops.model.process.tables.records.TPipelineSettingRecord import com.tencent.devops.model.process.tables.records.TTemplateInstanceItemRecord import com.tencent.devops.model.process.tables.records.TTemplateRecord import com.tencent.devops.process.constant.ProcessMessageCode @@ -657,7 +656,7 @@ class TemplateFacadeService @Autowired constructor( val model: Model = objectMapper.readValue(modelStr) val setting = settings[templateId] - val templateName = setting?.name ?: model.name + val templateName = setting?.pipelineName ?: model.name // 根据keywords搜索过滤 if (!keywords.isNullOrBlank() && !templateName.contains(keywords)) return@forEach @@ -889,7 +888,7 @@ class TemplateFacadeService @Autowired constructor( val categoryStr = record[tTemplate.CATEGORY] val key = if (type == TemplateType.CONSTRAINT.name) srcTemplateId else templateId result[key] = OptionalTemplate( - name = setting?.name ?: model.name, + name = setting?.pipelineName ?: model.name, templateId = templateId, projectId = templateRecord[tTemplate.PROJECT_ID], version = version, @@ -960,7 +959,7 @@ class TemplateFacadeService @Autowired constructor( template.creator ) val model: Model = objectMapper.readValue(template.template) - model.name = setting.name + model.name = setting.pipelineName model.desc = setting.desc val groups = pipelineGroupService.getGroups(userId, projectId, templateId) val labels = ArrayList() @@ -996,7 +995,7 @@ class TemplateFacadeService @Autowired constructor( versions = versions, currentVersion = currentVersion, latestVersion = latestVersion, - templateName = setting.name, + templateName = setting.pipelineName, description = setting.desc ?: "", creator = if (isConstrainedFlag) latestTemplate.creator else template.creator, template = templateResult, @@ -1863,7 +1862,7 @@ class TemplateFacadeService @Autowired constructor( versionName = it[KEY_VERSION_NAME] as String, version = templatePipelineVersion, pipelineId = pipelineId, - pipelineName = pipelineSetting[0].name, + pipelineName = pipelineSetting[0].pipelineName, updateTime = (it[KEY_UPDATED_TIME] as LocalDateTime).timestampmilli(), hasPermission = hasPermissionList.contains(pipelineId), status = templatePipelineStatus @@ -1996,10 +1995,10 @@ class TemplateFacadeService @Autowired constructor( } } - private fun getPipelineName(records: Result, pipelineId: String): String? { + private fun getPipelineName(records: List, pipelineId: String): String? { records.forEach { if (it.pipelineId == pipelineId) { - return it.name + return it.pipelineName } } return null @@ -2125,7 +2124,7 @@ class TemplateFacadeService @Autowired constructor( name = templateName, isTemplate = true ) - if (pipelineSettingRecord.size > 0) { + if (pipelineSettingRecord.isNotEmpty()) { return@forEach } val templateId = UUIDUtil.generate() From cfcb76090ea7bb26deb8a08555563fe2abd8f51a Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 6 Jul 2023 21:27:40 +0800 Subject: [PATCH 016/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20setting=E8=A1=A8=E7=89=88=E6=9C=AC=E5=8F=B7=E8=A7=A3?= =?UTF-8?q?=E7=BB=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/dao/PipelineSettingDao.kt | 234 +++++++++--------- 1 file changed, 113 insertions(+), 121 deletions(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt index d16aa1d1d4c..20578229de8 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt @@ -142,133 +142,125 @@ class PipelineSettingDao { dslContext: DSLContext, setting: PipelineSetting, isTemplate: Boolean = false - ): Int { + ) { with(TPipelineSetting.T_PIPELINE_SETTING) { // #6090 先查询存在情况再做刷新或插入 - val origin = getSetting(dslContext, setting.projectId, setting.pipelineId) - val oldSuccessSubscription = setting.successSubscriptionList?.first() ?: setting.successSubscription - val oldFailSubscription = setting.failSubscriptionList?.first() ?: setting.failSubscription val successSubscriptionList = setting.successSubscriptionList ?: listOf(setting.successSubscription) val failSubscriptionList = setting.failSubscriptionList ?: listOf(setting.failSubscription) - return if (origin == null) { - dslContext.insertInto( - this, - PROJECT_ID, - NAME, - DESC, - RUN_LOCK_TYPE, - PIPELINE_ID, - SUCCESS_RECEIVER, - FAIL_RECEIVER, - SUCCESS_GROUP, - FAIL_GROUP, - SUCCESS_TYPE, - FAIL_TYPE, - FAIL_WECHAT_GROUP_FLAG, - FAIL_WECHAT_GROUP, - FAIL_WECHAT_GROUP_MARKDOWN_FLAG, - SUCCESS_WECHAT_GROUP_FLAG, - SUCCESS_WECHAT_GROUP, - SUCCESS_WECHAT_GROUP_MARKDOWN_FLAG, - SUCCESS_DETAIL_FLAG, - FAIL_DETAIL_FLAG, - SUCCESS_CONTENT, - FAIL_CONTENT, - WAIT_QUEUE_TIME_SECOND, - MAX_QUEUE_SIZE, - IS_TEMPLATE, - MAX_PIPELINE_RES_NUM, - MAX_CON_RUNNING_QUEUE_SIZE, - BUILD_NUM_RULE, - CONCURRENCY_GROUP, - CONCURRENCY_CANCEL_IN_PROGRESS, - CLEAN_VARIABLES_WHEN_RETRY, - PIPELINE_AS_CODE_SETTINGS, - SUCCESS_SUBSCRIPTION, - FAILURE_SUBSCRIPTION, - VERSION - ).values( - setting.projectId, - setting.pipelineName, - setting.desc, - PipelineRunLockType.toValue(setting.runLockType), - setting.pipelineId, - oldSuccessSubscription.users, - oldFailSubscription.users, - oldSuccessSubscription.groups.joinToString(","), - oldFailSubscription.groups.joinToString(","), - oldSuccessSubscription.types.joinToString(",") { it.name }, - oldFailSubscription.types.joinToString(",") { it.name }, - oldFailSubscription.wechatGroupFlag, - oldFailSubscription.wechatGroup, - oldFailSubscription.wechatGroupMarkdownFlag, - oldSuccessSubscription.wechatGroupFlag, - oldSuccessSubscription.wechatGroup, - oldSuccessSubscription.wechatGroupMarkdownFlag, - oldSuccessSubscription.detailFlag, - oldFailSubscription.detailFlag, - oldSuccessSubscription.content, - oldFailSubscription.content, - DateTimeUtil.minuteToSecond(setting.waitQueueTimeMinute), - setting.maxQueueSize, - isTemplate, - setting.maxPipelineResNum, - setting.maxConRunningQueueSize, - setting.buildNumRule, - setting.concurrencyGroup, - setting.concurrencyCancelInProgress, - setting.cleanVariablesWhenRetry, - setting.pipelineAsCodeSettings?.let { self -> - JsonUtil.toJson(self, false) - }, - JsonUtil.toJson(successSubscriptionList, false), - JsonUtil.toJson(failSubscriptionList, false), - setting.version - ).execute() - } else { - val updateSetMoreStep = dslContext.update(this) - .set(NAME, setting.pipelineName) - .set(DESC, setting.desc) - .set(RUN_LOCK_TYPE, PipelineRunLockType.toValue(setting.runLockType)) - .set(SUCCESS_RECEIVER, oldSuccessSubscription.users) - .set(FAIL_RECEIVER, oldFailSubscription.users) - .set(SUCCESS_GROUP, oldSuccessSubscription.groups.joinToString(",")) - .set(FAIL_GROUP, oldFailSubscription.groups.joinToString(",")) - .set(SUCCESS_TYPE, oldSuccessSubscription.types.joinToString(",") { it.name }) - .set(FAIL_TYPE, oldFailSubscription.types.joinToString(",") { it.name }) - .set(FAIL_WECHAT_GROUP_FLAG, oldFailSubscription.wechatGroupFlag) - .set(FAIL_WECHAT_GROUP, oldFailSubscription.wechatGroup) - .set(FAIL_WECHAT_GROUP_MARKDOWN_FLAG, oldFailSubscription.wechatGroupMarkdownFlag) - .set(SUCCESS_WECHAT_GROUP_FLAG, oldSuccessSubscription.wechatGroupFlag) - .set(SUCCESS_WECHAT_GROUP, oldSuccessSubscription.wechatGroup) - .set(SUCCESS_WECHAT_GROUP_MARKDOWN_FLAG, oldSuccessSubscription.wechatGroupMarkdownFlag) - .set(SUCCESS_DETAIL_FLAG, oldSuccessSubscription.detailFlag) - .set(FAIL_DETAIL_FLAG, oldFailSubscription.detailFlag) - .set(SUCCESS_CONTENT, oldSuccessSubscription.content) - .set(FAIL_CONTENT, oldFailSubscription.content) - .set(WAIT_QUEUE_TIME_SECOND, DateTimeUtil.minuteToSecond(setting.waitQueueTimeMinute)) - .set(MAX_QUEUE_SIZE, setting.maxQueueSize) - .set(MAX_PIPELINE_RES_NUM, setting.maxPipelineResNum) - .set(BUILD_NUM_RULE, setting.buildNumRule) - .set(CONCURRENCY_GROUP, setting.concurrencyGroup) - .set(CONCURRENCY_CANCEL_IN_PROGRESS, setting.concurrencyCancelInProgress) - .set(CLEAN_VARIABLES_WHEN_RETRY, setting.cleanVariablesWhenRetry) - .set(CLEAN_VARIABLES_WHEN_RETRY, setting.cleanVariablesWhenRetry) - .set(SUCCESS_SUBSCRIPTION, JsonUtil.toJson(successSubscriptionList, false)) - .set(FAILURE_SUBSCRIPTION, JsonUtil.toJson(failSubscriptionList, false)) - .set(VERSION, setting.version) - // pipelineAsCodeSettings 默认传空不更新 + val insert = dslContext.insertInto( + this, + PROJECT_ID, + NAME, + DESC, + RUN_LOCK_TYPE, + PIPELINE_ID, + SUCCESS_RECEIVER, + FAIL_RECEIVER, + SUCCESS_GROUP, + FAIL_GROUP, + SUCCESS_TYPE, + FAIL_TYPE, + FAIL_WECHAT_GROUP_FLAG, + FAIL_WECHAT_GROUP, + FAIL_WECHAT_GROUP_MARKDOWN_FLAG, + SUCCESS_WECHAT_GROUP_FLAG, + SUCCESS_WECHAT_GROUP, + SUCCESS_WECHAT_GROUP_MARKDOWN_FLAG, + SUCCESS_DETAIL_FLAG, + FAIL_DETAIL_FLAG, + SUCCESS_CONTENT, + FAIL_CONTENT, + WAIT_QUEUE_TIME_SECOND, + MAX_QUEUE_SIZE, + IS_TEMPLATE, + MAX_PIPELINE_RES_NUM, + MAX_CON_RUNNING_QUEUE_SIZE, + BUILD_NUM_RULE, + CONCURRENCY_GROUP, + CONCURRENCY_CANCEL_IN_PROGRESS, + CLEAN_VARIABLES_WHEN_RETRY, + PIPELINE_AS_CODE_SETTINGS, + SUCCESS_SUBSCRIPTION, + FAILURE_SUBSCRIPTION, + VERSION + ).values( + setting.projectId, + setting.pipelineName, + setting.desc, + PipelineRunLockType.toValue(setting.runLockType), + setting.pipelineId, + setting.successSubscription.users, + setting.failSubscription.users, + setting.successSubscription.groups.joinToString(","), + setting.failSubscription.groups.joinToString(","), + setting.successSubscription.types.joinToString(",") { it.name }, + setting.failSubscription.types.joinToString(",") { it.name }, + setting.failSubscription.wechatGroupFlag, + setting.failSubscription.wechatGroup, + setting.failSubscription.wechatGroupMarkdownFlag, + setting.successSubscription.wechatGroupFlag, + setting.successSubscription.wechatGroup, + setting.successSubscription.wechatGroupMarkdownFlag, + setting.successSubscription.detailFlag, + setting.failSubscription.detailFlag, + setting.successSubscription.content, + setting.failSubscription.content, + DateTimeUtil.minuteToSecond(setting.waitQueueTimeMinute), + setting.maxQueueSize, + isTemplate, + setting.maxPipelineResNum, + setting.maxConRunningQueueSize, + setting.buildNumRule, + setting.concurrencyGroup, + setting.concurrencyCancelInProgress, + setting.cleanVariablesWhenRetry, setting.pipelineAsCodeSettings?.let { self -> - updateSetMoreStep.set(PIPELINE_AS_CODE_SETTINGS, JsonUtil.toJson(self, false)) - } - // maxConRunningQueueSize 默认传空不更新 - if (setting.maxConRunningQueueSize != null) { - updateSetMoreStep.set(MAX_CON_RUNNING_QUEUE_SIZE, setting.maxConRunningQueueSize) - } - updateSetMoreStep - .where(PIPELINE_ID.eq(setting.pipelineId).and(PROJECT_ID.eq(setting.projectId))) - .execute() + JsonUtil.toJson(self, false) + }, + JsonUtil.toJson(successSubscriptionList, false), + JsonUtil.toJson(failSubscriptionList, false), + setting.version + ).onDuplicateKeyUpdate() + .set(NAME, setting.pipelineName) + .set(DESC, setting.desc) + .set(RUN_LOCK_TYPE, PipelineRunLockType.toValue(setting.runLockType)) + .set(SUCCESS_RECEIVER, setting.successSubscription.users) + .set(FAIL_RECEIVER, setting.failSubscription.users) + .set(SUCCESS_GROUP, setting.successSubscription.groups.joinToString(",")) + .set(FAIL_GROUP, setting.failSubscription.groups.joinToString(",")) + .set(SUCCESS_TYPE, setting.successSubscription.types.joinToString(",") { it.name }) + .set(FAIL_TYPE, setting.failSubscription.types.joinToString(",") { it.name }) + .set(FAIL_WECHAT_GROUP_FLAG, setting.failSubscription.wechatGroupFlag) + .set(FAIL_WECHAT_GROUP, setting.failSubscription.wechatGroup) + .set(FAIL_WECHAT_GROUP_MARKDOWN_FLAG, setting.failSubscription.wechatGroupMarkdownFlag) + .set(SUCCESS_WECHAT_GROUP_FLAG, setting.successSubscription.wechatGroupFlag) + .set(SUCCESS_WECHAT_GROUP, setting.successSubscription.wechatGroup) + .set(SUCCESS_WECHAT_GROUP_MARKDOWN_FLAG, setting.successSubscription.wechatGroupMarkdownFlag) + .set(SUCCESS_DETAIL_FLAG, setting.successSubscription.detailFlag) + .set(FAIL_DETAIL_FLAG, setting.failSubscription.detailFlag) + .set(SUCCESS_CONTENT, setting.successSubscription.content) + .set(FAIL_CONTENT, setting.failSubscription.content) + .set(WAIT_QUEUE_TIME_SECOND, DateTimeUtil.minuteToSecond(setting.waitQueueTimeMinute)) + .set(MAX_QUEUE_SIZE, setting.maxQueueSize) + .set(MAX_PIPELINE_RES_NUM, setting.maxPipelineResNum) + .set(BUILD_NUM_RULE, setting.buildNumRule) + .set(CONCURRENCY_GROUP, setting.concurrencyGroup) + .set(CONCURRENCY_CANCEL_IN_PROGRESS, setting.concurrencyCancelInProgress) + .set(CLEAN_VARIABLES_WHEN_RETRY, setting.cleanVariablesWhenRetry) + .set(CLEAN_VARIABLES_WHEN_RETRY, setting.cleanVariablesWhenRetry) + .set(SUCCESS_SUBSCRIPTION, JsonUtil.toJson(successSubscriptionList, false)) + .set(FAILURE_SUBSCRIPTION, JsonUtil.toJson(failSubscriptionList, false)) + .set(VERSION, setting.version) + // pipelineAsCodeSettings 默认传空不更新 + setting.pipelineAsCodeSettings?.let { self -> + insert.set(PIPELINE_AS_CODE_SETTINGS, JsonUtil.toJson(self, false)) + } + // maxConRunningQueueSize 默认传空不更新 + if (setting.maxConRunningQueueSize != null) { + insert.set(MAX_CON_RUNNING_QUEUE_SIZE, setting.maxConRunningQueueSize) } + insert.where(PIPELINE_ID.eq(setting.pipelineId).and(PROJECT_ID.eq(setting.projectId))) + .execute() } } From c61a2cfb745e7355a718168a5202efbe064de804 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 6 Jul 2023 21:34:40 +0800 Subject: [PATCH 017/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20setting=E8=A1=A8=E7=89=88=E6=9C=AC=E5=8F=B7=E8=A7=A3?= =?UTF-8?q?=E7=BB=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/process/dao/PipelineSettingDao.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt index 20578229de8..09a2ec17504 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt @@ -142,7 +142,7 @@ class PipelineSettingDao { dslContext: DSLContext, setting: PipelineSetting, isTemplate: Boolean = false - ) { + ): Int { with(TPipelineSetting.T_PIPELINE_SETTING) { // #6090 先查询存在情况再做刷新或插入 val successSubscriptionList = setting.successSubscriptionList ?: listOf(setting.successSubscription) @@ -259,7 +259,7 @@ class PipelineSettingDao { if (setting.maxConRunningQueueSize != null) { insert.set(MAX_CON_RUNNING_QUEUE_SIZE, setting.maxConRunningQueueSize) } - insert.where(PIPELINE_ID.eq(setting.pipelineId).and(PROJECT_ID.eq(setting.projectId))) + return insert.where(PIPELINE_ID.eq(setting.pipelineId).and(PROJECT_ID.eq(setting.projectId))) .execute() } } From a9972386ca10f7ee703f23b9cf328e5a00634950 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Fri, 7 Jul 2023 16:18:50 +0800 Subject: [PATCH 018/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20setting=E8=A1=A8=E7=89=88=E6=9C=AC=E5=8F=B7=E8=A7=A3?= =?UTF-8?q?=E7=BB=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/pojo/pipeline/PipelineResourceVersion.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt index 7c1c108ccff..248d4fa803b 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt @@ -46,7 +46,7 @@ data class PipelineResourceVersion( @ApiModelProperty("创建者", required = true) val creator: String, @ApiModelProperty("版本名称", required = true) - val versionName: String, + val versionName: String = "init", @ApiModelProperty("创建者", required = true) val createTime: LocalDateTime, @ApiModelProperty("编排版本号", required = false) From 29f78b2aafddd46521f70e14ee595ebb3ecf0dd8 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Fri, 7 Jul 2023 17:05:04 +0800 Subject: [PATCH 019/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20setting=E8=A1=A8=E7=89=88=E6=9C=AC=E5=8F=B7=E8=A7=A3?= =?UTF-8?q?=E7=BB=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/pojo/PipelineDetail.kt | 45 +++++++++++++++++++ .../pojo/pipeline/PipelineResourceVersion.kt | 4 +- .../setting/PipelineResourceAndSetting.kt | 3 ++ .../process/engine/dao/PipelineResDao.kt | 4 +- .../engine/dao/PipelineResVersionDao.kt | 3 +- .../service/PipelineRepositoryService.kt | 7 --- .../process/api/UserPipelineResourceImpl.kt | 18 +++++++- 7 files changed, 69 insertions(+), 15 deletions(-) create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetail.kt diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetail.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetail.kt new file mode 100644 index 00000000000..04b3cf8df5d --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetail.kt @@ -0,0 +1,45 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.pojo + +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty + +@ApiModel("流水线名称与Id") +data class PipelineDetail( + @ApiModelProperty("流水线Id") + val pipelineId: String, + @ApiModelProperty("流水线名称") + val pipelineName: String, + @ApiModelProperty("是否收藏") + val hasCollect: Boolean, + @ApiModelProperty("是否可以手动触发") + val canManualStartup: Int, + @ApiModelProperty("是否有编辑权限") + val hasPermission: Boolean +) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt index 248d4fa803b..243f60d7e2b 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt @@ -46,8 +46,8 @@ data class PipelineResourceVersion( @ApiModelProperty("创建者", required = true) val creator: String, @ApiModelProperty("版本名称", required = true) - val versionName: String = "init", - @ApiModelProperty("创建者", required = true) + val versionName: String? = "init", + @ApiModelProperty("版本创建时间", required = true) val createTime: LocalDateTime, @ApiModelProperty("编排版本号", required = false) val pipelineVersion: Int?, diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineResourceAndSetting.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineResourceAndSetting.kt index 03d076a3b50..6767b0abdce 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineResourceAndSetting.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineResourceAndSetting.kt @@ -27,11 +27,14 @@ package com.tencent.devops.process.pojo.setting +import com.tencent.devops.process.pojo.PipelineDetail import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion import io.swagger.annotations.ApiModelProperty import javax.validation.Valid data class PipelineResourceAndSetting( + @ApiModelProperty("流水线模型", required = true) + val pipelineInfo: PipelineDetail?, @ApiModelProperty("流水线模型", required = true) val pipelineResource: PipelineResourceVersion, @ApiModelProperty("流水线设置", required = false) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt index e25e23f1aa0..8c56b6204cf 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt @@ -43,7 +43,7 @@ import org.slf4j.LoggerFactory import org.springframework.stereotype.Repository import java.time.LocalDateTime -@Suppress("TooManyFunctions", "LongParameterList") +@Suppress("TooManyFunctions", "LongParameterList", "ReturnCount") @Repository class PipelineResDao { @@ -55,7 +55,6 @@ class PipelineResDao { version: Int, versionName: String, model: Model, - trigger: TriggerContainer, pipelineVersion: Int, triggerVersion: Int, settingVersion: Int @@ -63,7 +62,6 @@ class PipelineResDao { logger.info("Create the pipeline model pipelineId=$pipelineId, version=$version") with(T_PIPELINE_RESOURCE) { val modelString = JsonUtil.toJson(model, formatted = false) - val triggerString = JsonUtil.toJson(trigger, formatted = false) dslContext.insertInto(this) .set(PROJECT_ID, projectId) .set(PIPELINE_ID, pipelineId) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt index f5ee5b3d0da..9eae8e2891e 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt @@ -39,7 +39,7 @@ import org.jooq.impl.DSL import org.springframework.stereotype.Repository import java.time.LocalDateTime -@Suppress("Unused", "LongParameterList", "ReturnCount") +@Suppress("Unused", "LongParameterList", "ReturnCount", "TooManyFunctions") @Repository class PipelineResVersionDao { @@ -51,7 +51,6 @@ class PipelineResVersionDao { version: Int, versionName: String, model: Model, - trigger: TriggerContainer, pipelineVersion: Int?, triggerVersion: Int?, settingVersion: Int?, diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index 788eee5101d..dadf8c88273 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -216,7 +216,6 @@ class PipelineRepositoryService constructor( modelTasks = modelTasks, useTemplateSettings = useTemplateSettings, templateId = templateId, - trigger = triggerContainer, saveDraft = saveDraft ) } @@ -492,7 +491,6 @@ class PipelineRepositoryService constructor( projectId: String, pipelineId: String, model: Model, - trigger: TriggerContainer, userId: String, channelCode: ChannelCode, canManualStartup: Boolean, @@ -600,7 +598,6 @@ class PipelineRepositoryService constructor( creator = userId, version = 1, model = model, - trigger = trigger, versionName = getVersionName(pipelineVersion, triggerVersion, settingVersion), pipelineVersion = modelVersion, triggerVersion = triggerVersion, @@ -614,7 +611,6 @@ class PipelineRepositoryService constructor( creator = userId, version = 1, model = model, - trigger = trigger, versionName = getVersionName(modelVersion, triggerVersion, settingVersion), pipelineVersion = modelVersion, triggerVersion = triggerVersion, @@ -664,7 +660,6 @@ class PipelineRepositoryService constructor( saveDraft: Boolean? = false ): DeployPipelineResult { val taskCount: Int = model.taskCount() - val triggerContainer = model.stages[0].containers[0] as TriggerContainer var version = 0 val lock = PipelineModelLock(redisOperation, pipelineId) val watcher = Watcher(id = "updatePipeline#$pipelineId#$saveDraft") @@ -739,7 +734,6 @@ class PipelineRepositoryService constructor( creator = userId, version = version, model = model, - trigger = triggerContainer, versionName = getVersionName(pipelineVersion, triggerVersion, settingVersion), pipelineVersion = pipelineVersion, triggerVersion = triggerVersion, @@ -752,7 +746,6 @@ class PipelineRepositoryService constructor( creator = userId, version = version, model = model, - trigger = triggerContainer, versionName = getVersionName(pipelineVersion, triggerVersion, settingVersion), pipelineVersion = pipelineVersion, triggerVersion = triggerVersion, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index 5183254b1dc..d310bf86fa8 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -55,6 +55,7 @@ import com.tencent.devops.process.pojo.Permission import com.tencent.devops.process.pojo.Pipeline import com.tencent.devops.process.pojo.PipelineCollation import com.tencent.devops.process.pojo.PipelineCopy +import com.tencent.devops.process.pojo.PipelineDetail import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineName import com.tencent.devops.process.pojo.PipelineRemoteToken @@ -374,6 +375,7 @@ class UserPipelineResourceImpl @Autowired constructor( includeDraft: Boolean? ): Result { checkParam(userId, projectId) + val detailInfo = pipelineListFacadeService.getPipelineDetail(userId, projectId, pipelineId) val resource = pipelineInfoFacadeService.getPipelineResourceVersion( userId = userId, projectId = projectId, @@ -388,7 +390,21 @@ class UserPipelineResourceImpl @Autowired constructor( version = resource.settingVersion ?: resource.version ) pipelineRecentUseService.record(userId, projectId, pipelineId) - return Result(PipelineResourceAndSetting(resource, setting)) + return Result( + PipelineResourceAndSetting( + pipelineInfo = detailInfo?.let { + PipelineDetail( + pipelineId = it.pipelineId, + pipelineName = it.pipelineName, + hasCollect = it.hasCollect, + canManualStartup = it.canManualStartup, + hasPermission = it.hasPermission + ) + }, + pipelineResource = resource, + setting = setting + ) + ) } override fun getVersion(userId: String, projectId: String, pipelineId: String, version: Int): Result { From d7f5a93c93b384af90cd9ea4f43b14448a93d34f Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 11 Jul 2023 10:37:59 +0800 Subject: [PATCH 020/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20setting=E8=A1=A8=E7=89=88=E6=9C=AC=E5=8F=B7=E8=A7=A3?= =?UTF-8?q?=E7=BB=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/process/dao/PipelineSettingDao.kt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt index 09a2ec17504..5bfa9801592 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt @@ -214,9 +214,7 @@ class PipelineSettingDao { setting.concurrencyGroup, setting.concurrencyCancelInProgress, setting.cleanVariablesWhenRetry, - setting.pipelineAsCodeSettings?.let { self -> - JsonUtil.toJson(self, false) - }, + setting.pipelineAsCodeSettings?.let { self -> JsonUtil.toJson(self, false) }, JsonUtil.toJson(successSubscriptionList, false), JsonUtil.toJson(failSubscriptionList, false), setting.version @@ -259,8 +257,7 @@ class PipelineSettingDao { if (setting.maxConRunningQueueSize != null) { insert.set(MAX_CON_RUNNING_QUEUE_SIZE, setting.maxConRunningQueueSize) } - return insert.where(PIPELINE_ID.eq(setting.pipelineId).and(PROJECT_ID.eq(setting.projectId))) - .execute() + return insert.execute() } } From 841ad9384a1ef780416bcbd1d31fb3b5d09e7a1c Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 11 Jul 2023 17:18:10 +0800 Subject: [PATCH 021/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20setting=E8=A1=A8=E7=89=88=E6=9C=AC=E5=8F=B7=E8=A7=A3?= =?UTF-8?q?=E7=BB=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/service/pipeline/PipelineSettingFacadeService.kt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt index 9d23bb86676..fe8f9b37e03 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt @@ -62,6 +62,7 @@ import com.tencent.devops.process.service.PipelineSettingVersionService import com.tencent.devops.process.service.label.PipelineGroupService import com.tencent.devops.process.service.view.PipelineViewGroupService import org.json.JSONObject +import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service @@ -82,6 +83,8 @@ class PipelineSettingFacadeService @Autowired constructor( private val pipelineEventDispatcher: PipelineEventDispatcher ) { + private val logger = LoggerFactory.getLogger(PipelineSettingFacadeService::class.java) + /** * 修改配置时需要返回具体的版本号用于传递 */ @@ -119,6 +122,7 @@ class PipelineSettingFacadeService @Autowired constructor( projectId = projectId, pipelineId = pipelineId )?.let { origin -> + logger.info("[$projectId]|$pipelineId|saveSetting|origin=\n\n$origin\n\nsetting=\n\n$setting") val originJson = JSONObject(origin) val currentJson = JSONObject(setting) if (currentJson.similar(originJson)) { @@ -127,6 +131,7 @@ class PipelineSettingFacadeService @Autowired constructor( origin.version + 1 } } ?: 1 + logger.info("[$projectId]|$pipelineId|saveSetting|settingVersion=$settingVersion|") val pipelineName = pipelineRepositoryService.saveSetting( userId = userId, From c10ed6d14801dd46b32b40a146130433b05a6356 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Wed, 12 Jul 2023 17:21:07 +0800 Subject: [PATCH 022/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E4=BC=98=E5=8C=96Setting=E5=85=B3=E8=81=94=E5=85=B3?= =?UTF-8?q?=E7=B3=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/engine/dao/PipelineResDao.kt | 16 ++++++++++++ .../engine/dao/PipelineResVersionDao.kt | 15 +++++++++++ .../service/PipelineRepositoryService.kt | 25 +++++++++++++++++++ .../api/ServicePipelineResourceImpl.kt | 8 +++++- .../process/api/UserPipelineResourceImpl.kt | 8 +++++- .../api/UserPipelineSettingResourceImpl.kt | 24 ++++++++++++------ .../service/PipelineInfoFacadeService.kt | 22 +++++++++++++++- 7 files changed, 107 insertions(+), 11 deletions(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt index 8c56b6204cf..a3be2152743 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt @@ -222,6 +222,22 @@ class PipelineResDao { } } + fun updateSettingVersion( + dslContext: DSLContext, + userId: String, + projectId: String, + pipelineId: String, + settingVersion: Int + ): Int? { + with(T_PIPELINE_RESOURCE) { + return dslContext.update(this) + .set(SETTING_VERSION, settingVersion) + .where(PROJECT_ID.eq(projectId).and(PIPELINE_ID.eq(pipelineId))) + .returning(VERSION) + .fetchOne()?.version + } + } + /** * 获取最新的modelString * diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt index 9eae8e2891e..d78ae2234c8 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt @@ -293,4 +293,19 @@ class PipelineResVersionDao { baseStep.where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId)).and(VERSION.eq(version))).execute() } } + + fun updateSettingVersion( + dslContext: DSLContext, + projectId: String, + pipelineId: String, + version: Int, + settingVersion: Int + ): Int { + with(T_PIPELINE_RESOURCE_VERSION) { + return dslContext.update(this) + .set(SETTING_VERSION, settingVersion) + .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId)).and(VERSION.eq(version))) + .execute() + } + } } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index dadf8c88273..7890240737d 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -1365,4 +1365,29 @@ class PipelineRepositoryService constructor( maxConRunningQueueSize = maxConRunningQueueSize ) } + + fun updateSettingVersion( + userId: String, + projectId: String, + pipelineId: String, + settingVersion: Int + ) { + val version = pipelineResDao.updateSettingVersion( + dslContext = dslContext, + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + settingVersion = settingVersion + ) + // 同步刷新流水线版本历史中关联的设置版本号 + if (version != null) { + pipelineResVersionDao.updateSettingVersion( + dslContext = dslContext, + projectId = projectId, + pipelineId = pipelineId, + version = version, + settingVersion = settingVersion + ) + } + } } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt index 0a50b7fc4d5..919efc9d576 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt @@ -330,7 +330,7 @@ class ServicePipelineResourceImpl @Autowired constructor( checkProjectId(projectId) checkPipelineId(pipelineId) setting.checkParam() - pipelineSettingFacadeService.saveSetting( + val savedSetting = pipelineSettingFacadeService.saveSetting( userId = userId, projectId = projectId, pipelineId = pipelineId, @@ -338,6 +338,12 @@ class ServicePipelineResourceImpl @Autowired constructor( checkPermission = ChannelCode.isNeedAuth(channelCode ?: ChannelCode.BS), updateLastModifyUser = updateLastModifyUser ) + pipelineInfoFacadeService.updatePipelineSettingVersion( + userId = userId, + projectId = setting.projectId, + pipelineId = setting.pipelineId, + settingVersion = savedSetting.version + ) auditService.createAudit( Audit( resourceType = AuthResourceType.PIPELINE_DEFAULT.value, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index d310bf86fa8..77bd501c8d3 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -317,13 +317,19 @@ class UserPipelineResourceImpl @Autowired constructor( setting: PipelineSetting ): Result { checkParam(userId, projectId) - pipelineSettingFacadeService.saveSetting( + val savedSetting = pipelineSettingFacadeService.saveSetting( userId = userId, projectId = projectId, pipelineId = pipelineId, setting = setting, checkPermission = true ) + pipelineInfoFacadeService.updatePipelineSettingVersion( + userId = userId, + projectId = setting.projectId, + pipelineId = setting.pipelineId, + settingVersion = savedSetting.version + ) auditService.createAudit( Audit( resourceType = AuthResourceType.PIPELINE_DEFAULT.value, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineSettingResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineSettingResourceImpl.kt index 9bffa61d47c..79ea08794b2 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineSettingResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineSettingResourceImpl.kt @@ -32,22 +32,30 @@ import com.tencent.devops.common.web.RestResource import com.tencent.devops.process.api.user.UserPipelineSettingResource import com.tencent.devops.process.pojo.setting.PipelineCommonSetting import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.process.service.PipelineInfoFacadeService import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService import org.springframework.beans.factory.annotation.Autowired @RestResource class UserPipelineSettingResourceImpl @Autowired constructor( - private val pipelineSettingFacadeService: PipelineSettingFacadeService + private val pipelineSettingFacadeService: PipelineSettingFacadeService, + private val pipelineInfoFacadeService: PipelineInfoFacadeService ) : UserPipelineSettingResource { + override fun saveSetting(userId: String, setting: PipelineSetting): Result { - return Result( - pipelineSettingFacadeService.saveSetting( - userId = userId, - projectId = setting.projectId, - pipelineId = setting.pipelineId, - setting = setting - ).pipelineId + val savedSetting = pipelineSettingFacadeService.saveSetting( + userId = userId, + projectId = setting.projectId, + pipelineId = setting.pipelineId, + setting = setting + ) + pipelineInfoFacadeService.updatePipelineSettingVersion( + userId = userId, + projectId = setting.projectId, + pipelineId = setting.pipelineId, + settingVersion = savedSetting.version ) + return Result(savedSetting.pipelineId) } override fun getSetting( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index 2ab2d99d45c..620a74720c4 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -766,7 +766,7 @@ class PipelineInfoFacadeService @Autowired constructor( ) { val setting = pipelineSettingFacadeService.userGetSetting(userId, projectId, pipelineId, channelCode) setting.pipelineName = name - pipelineSettingFacadeService.saveSetting( + val savedSetting = pipelineSettingFacadeService.saveSetting( userId = userId, projectId = projectId, pipelineId = pipelineId, @@ -774,6 +774,26 @@ class PipelineInfoFacadeService @Autowired constructor( checkPermission = true, dispatchPipelineUpdateEvent = true ) + updatePipelineSettingVersion( + userId = userId, + projectId = setting.projectId, + pipelineId = setting.pipelineId, + settingVersion = savedSetting.version + ) + } + + fun updatePipelineSettingVersion( + userId: String, + projectId: String, + pipelineId: String, + settingVersion: Int + ) { + pipelineRepositoryService.updateSettingVersion( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + settingVersion = settingVersion + ) } fun saveAll( From 760b61a403d9bffe9de28dfe299b5b1c9f10a1b7 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Wed, 12 Jul 2023 17:21:39 +0800 Subject: [PATCH 023/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E4=BC=98=E5=8C=96Setting=E5=85=B3=E8=81=94=E5=85=B3?= =?UTF-8?q?=E7=B3=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/process/engine/dao/PipelineResDao.kt | 1 - .../tencent/devops/process/engine/dao/PipelineResVersionDao.kt | 1 - 2 files changed, 2 deletions(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt index a3be2152743..c00b0ce709e 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt @@ -29,7 +29,6 @@ package com.tencent.devops.process.engine.dao import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.pipeline.Model -import com.tencent.devops.common.pipeline.container.TriggerContainer import com.tencent.devops.model.process.Tables.T_PIPELINE_RESOURCE import com.tencent.devops.model.process.tables.records.TPipelineResourceRecord import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt index d78ae2234c8..8a879c1c837 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt @@ -30,7 +30,6 @@ package com.tencent.devops.process.engine.dao import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.api.util.timestampmilli import com.tencent.devops.common.pipeline.Model -import com.tencent.devops.common.pipeline.container.TriggerContainer import com.tencent.devops.model.process.Tables.T_PIPELINE_RESOURCE_VERSION import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion import com.tencent.devops.process.pojo.setting.PipelineVersionSimple From 6f49b2f0596e2e17250e19a64e4503a1f4fc52dd Mon Sep 17 00:00:00 2001 From: royalhuang Date: Fri, 14 Jul 2023 15:26:02 +0800 Subject: [PATCH 024/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=BB=B4=E6=8A=A4=E8=BF=87=E7=A8=8B=E4=B8=AD=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97=20#8197=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=89=80=E6=9C=89=E6=9E=9A=E4=B8=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/enums/OperationLogType.kt | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/enums/OperationLogType.kt diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/enums/OperationLogType.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/enums/OperationLogType.kt new file mode 100644 index 00000000000..9c41904e351 --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/enums/OperationLogType.kt @@ -0,0 +1,41 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.enums + +enum class OperationLogType(val description: String = "") { + CREATE_PIPELINE_AND_DRAFT("创建流水线首次保存草稿:「创建了草稿」"), + CREATE_DRAFT_VERSION("编辑流水线生成草稿:「从 P1.T2.0 创建了草稿」"), + UPDATE_DRAFT_VERSION("修改草稿保存后:「修改了草稿」"), + CREATE_BRANCH_VERSION("新增分支版本:「新增版本 P1.T2.0」"), + UPDATE_BRANCH_VERSION("修改分支版本:「修改版本 P1.T2.0」"), + RELEASE_MASTER_VERSION("正式版本完成时:「发布版本 P1.T2.0」"), + UNABLE_PIPELINE("禁用流水线时:「禁用了流水线」"), + ADD_PIPELINE_OWNER("添加流水线成员时:「添加 xxx,yyy 为执行者」"), + ADD_PIPELINE_TO_GROUP("将流水线添加到流水线组时:「添加到流水线组 a」"), + MOVE_PIPELINE_OUT_OF_GROUP("将流水线移出流水线组时:「从流水线组 a 中移出」"); +} From 64d086ceb3e713c7c654ef0b7b2ccbc2eebc3253 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Sun, 16 Jul 2023 17:44:21 +0800 Subject: [PATCH 025/852] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=BB=BA/?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=97=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=B0=83=E8=AF=95=E6=B5=81=E6=B0=B4=E7=BA=BF=20#8164?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=E8=B0=83=E8=AF=95=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/user/UserPipelineDebugResource.kt | 193 ++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineDebugResource.kt diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineDebugResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineDebugResource.kt new file mode 100644 index 00000000000..0eb50f636c7 --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineDebugResource.kt @@ -0,0 +1,193 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.api.user + +import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID +import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE +import com.tencent.devops.common.api.pojo.BuildHistoryPage +import com.tencent.devops.common.api.pojo.Result +import com.tencent.devops.common.pipeline.enums.BuildStatus +import com.tencent.devops.common.pipeline.enums.StartType +import com.tencent.devops.common.pipeline.pojo.BuildParameters +import com.tencent.devops.process.pojo.BuildHistory +import com.tencent.devops.process.pojo.BuildId +import com.tencent.devops.process.pojo.BuildManualStartupInfo +import io.swagger.annotations.Api +import io.swagger.annotations.ApiOperation +import io.swagger.annotations.ApiParam +import javax.ws.rs.Consumes +import javax.ws.rs.GET +import javax.ws.rs.HeaderParam +import javax.ws.rs.POST +import javax.ws.rs.Path +import javax.ws.rs.PathParam +import javax.ws.rs.Produces +import javax.ws.rs.QueryParam +import javax.ws.rs.core.MediaType + +@Api(tags = ["USER_PIPELINE_DEBUG"], description = "用户-流水线调试构建") +@Path("/user/debug") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Suppress("ALL") +interface UserPipelineDebugResource { + + @ApiOperation("调试-获取流水线手动启动参数") + @GET + @Path("/projects/{projectId}/pipelines/{pipelineId}/debugStartupInfo") + fun debugStartupInfo( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String + ): Result + + @ApiOperation("调试-获取流水线构建参数") + @GET + @Path("/projects/{projectId}/pipelines/{pipelineId}/builds/{buildId}/parameters") + fun getDebugBuildParameters( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String, + @ApiParam("构建ID", required = true) + @PathParam("buildId") + buildId: String + ): Result> + + @ApiOperation("启动流水线调试") + @POST + @Path("/projects/{projectId}/pipelines/{pipelineId}/start") + fun debugStartup( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String, + @ApiParam("启动参数", required = true) + values: Map, + @ApiParam("手动指定构建版本参数", required = false) + @QueryParam("buildNo") + buildNo: Int? = null, + @ApiParam("触发审核人列表", required = false) + @QueryParam("triggerReviewers") + triggerReviewers: List? = null + ): Result + + @ApiOperation("获取流水线调试构建历史") + @GET + @Path("/projects/{projectId}/pipelines/{pipelineId}/history") + fun getDebugHistoryBuild( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String, + @ApiParam("第几页", required = false, defaultValue = "1") + @QueryParam("page") + page: Int?, + @ApiParam("每页多少条", required = false, defaultValue = "20") + @QueryParam("pageSize") + pageSize: Int?, + @ApiParam("代码库别名", required = false) + @QueryParam("materialAlias") + materialAlias: List?, + @ApiParam("代码库URL", required = false) + @QueryParam("materialUrl") + materialUrl: String?, + @ApiParam("分支", required = false) + @QueryParam("materialBranch") + materialBranch: List?, + @ApiParam("commitId", required = false) + @QueryParam("materialCommitId") + materialCommitId: String?, + @ApiParam("commitMessage", required = false) + @QueryParam("materialCommitMessage") + materialCommitMessage: String?, + @ApiParam("状态", required = false) + @QueryParam("status") + status: List?, + @ApiParam("触发方式", required = false) + @QueryParam("trigger") + trigger: List?, + @ApiParam("排队于-开始时间(时间戳形式)", required = false) + @QueryParam("queueTimeStartTime") + queueTimeStartTime: Long?, + @ApiParam("排队于-结束时间(时间戳形式)", required = false) + @QueryParam("queueTimeEndTime") + queueTimeEndTime: Long?, + @ApiParam("开始于-开始时间(时间戳形式)", required = false) + @QueryParam("startTimeStartTime") + startTimeStartTime: Long?, + @ApiParam("开始于-结束时间(时间戳形式)", required = false) + @QueryParam("startTimeEndTime") + startTimeEndTime: Long?, + @ApiParam("结束于-开始时间(时间戳形式)", required = false) + @QueryParam("endTimeStartTime") + endTimeStartTime: Long?, + @ApiParam("结束于-结束时间(时间戳形式)", required = false) + @QueryParam("endTimeEndTime") + endTimeEndTime: Long?, + @ApiParam("耗时最小值", required = false) + @QueryParam("totalTimeMin") + totalTimeMin: Long?, + @ApiParam("耗时最大值", required = false) + @QueryParam("totalTimeMax") + totalTimeMax: Long?, + @ApiParam("备注", required = false) + @QueryParam("remark") + remark: String?, + @ApiParam("构件号起始", required = false) + @QueryParam("buildNoStart") + buildNoStart: Int?, + @ApiParam("构件号结束", required = false) + @QueryParam("buildNoEnd") + buildNoEnd: Int?, + @ApiParam("构建信息", required = false) + @QueryParam("buildMsg") + buildMsg: String? + ): Result> +} From 73cedf06a5a89df3c816464816d7a4c46cfc923f Mon Sep 17 00:00:00 2001 From: royalhuang Date: Fri, 21 Jul 2023 11:49:02 +0800 Subject: [PATCH 026/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/pipeline/enums/VersionStatus.kt | 33 +++++++++++++++ .../process/engine/pojo/PipelineResVersion.kt | 5 ++- .../pojo/pipeline/PipelineResourceVersion.kt | 3 +- .../pojo/setting/PipelineVersionSimple.kt | 5 ++- .../engine/dao/PipelineResVersionDao.kt | 42 ++++++++++--------- .../service/PipelineRepositoryService.kt | 7 ++-- .../PipelineRepositoryVersionService.kt | 3 +- 7 files changed, 69 insertions(+), 29 deletions(-) create mode 100644 src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/enums/VersionStatus.kt diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/enums/VersionStatus.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/enums/VersionStatus.kt new file mode 100644 index 00000000000..c7a7f3fbddd --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/enums/VersionStatus.kt @@ -0,0 +1,33 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.common.pipeline.enums + +enum class VersionStatus(val statusName: String) { + RELEASED("已发布"), + COMMITTING("提交中"); +} diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt index bfab8ae9058..ee59dd18268 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt @@ -28,6 +28,7 @@ package com.tencent.devops.process.engine.pojo import com.tencent.devops.common.pipeline.enums.ChannelCode +import com.tencent.devops.common.pipeline.enums.VersionStatus import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -75,8 +76,8 @@ data class PipelineResVersion( val triggerVersion: Int? = null, @ApiModelProperty("配置版本号", required = false) val settingVersion: Int? = null, - @ApiModelProperty("标识是否为草稿", required = false) - val draftFlag: Boolean? = null, + @ApiModelProperty("草稿版本标识", required = false) + val status: VersionStatus? = VersionStatus.RELEASED, @ApiModelProperty("调试构建ID", required = false) val debugBuildId: String? = null, @ApiModelProperty("来源代码库标识(分支名)", required = false) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt index 243f60d7e2b..02847850c21 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt @@ -28,6 +28,7 @@ package com.tencent.devops.process.pojo.pipeline import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.common.pipeline.enums.VersionStatus import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty import java.time.LocalDateTime @@ -60,7 +61,7 @@ data class PipelineResourceVersion( @ApiModelProperty("关联构建记录总数", required = false) val referCount: Int? = null, @ApiModelProperty("草稿版本标识", required = false) - val draftFlag: Boolean? = false, + val status: VersionStatus? = VersionStatus.RELEASED, @ApiModelProperty("分支版本标识", required = false) val refs: String? = null ) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineVersionSimple.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineVersionSimple.kt index a671f9b2fd3..8b1faf127e1 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineVersionSimple.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineVersionSimple.kt @@ -27,6 +27,7 @@ package com.tencent.devops.process.pojo.setting +import com.tencent.devops.common.pipeline.enums.VersionStatus import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -52,8 +53,8 @@ data class PipelineVersionSimple( val triggerVersion: Int? = null, @ApiModelProperty("配置版本号", required = false) val settingVersion: Int? = null, - @ApiModelProperty("标识是否为草稿", required = false) - val draftFlag: Boolean? = null, + @ApiModelProperty("草稿版本标识", required = false) + val status: VersionStatus? = VersionStatus.RELEASED, @ApiModelProperty("调试构建ID", required = false) val debugBuildId: String? = null, @ApiModelProperty("来源代码库标识(分支名)", required = false) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt index 8a879c1c837..0d6468a60f8 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt @@ -30,6 +30,7 @@ package com.tencent.devops.process.engine.dao import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.api.util.timestampmilli import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.common.pipeline.enums.VersionStatus import com.tencent.devops.model.process.Tables.T_PIPELINE_RESOURCE_VERSION import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion import com.tencent.devops.process.pojo.setting.PipelineVersionSimple @@ -53,7 +54,7 @@ class PipelineResVersionDao { pipelineVersion: Int?, triggerVersion: Int?, settingVersion: Int?, - draftFlag: Boolean + status: VersionStatus? ) { create( dslContext = dslContext, @@ -66,7 +67,7 @@ class PipelineResVersionDao { pipelineVersion = pipelineVersion, triggerVersion = triggerVersion, settingVersion = settingVersion, - draftFlag = draftFlag + status = status ) } @@ -81,7 +82,7 @@ class PipelineResVersionDao { pipelineVersion: Int?, triggerVersion: Int?, settingVersion: Int?, - draftFlag: Boolean + status: VersionStatus? ) { with(T_PIPELINE_RESOURCE_VERSION) { dslContext.insertInto(this) @@ -95,7 +96,7 @@ class PipelineResVersionDao { .set(PIPELINE_VERSION, pipelineVersion) .set(TRIGGER_VERSION, triggerVersion) .set(SETTING_VERSION, settingVersion) - .set(DRAFT_FLAG, draftFlag) + .set(STATUS, status?.name) .onDuplicateKeyUpdate() .set(MODEL, modelString) .set(CREATOR, creator) @@ -103,6 +104,7 @@ class PipelineResVersionDao { .set(PIPELINE_VERSION, pipelineVersion) .set(TRIGGER_VERSION, triggerVersion) .set(SETTING_VERSION, settingVersion) + .set(STATUS, status?.name) .execute() } } @@ -123,7 +125,7 @@ class PipelineResVersionDao { where.and(VERSION.eq(version)) } else { // 非新的逻辑请求则保持旧逻辑 - if (includeDraft != true) where.and(DRAFT_FLAG.ne(true)) + if (includeDraft != true) where.and(STATUS.ne(VersionStatus.COMMITTING.name)) where.orderBy(VERSION.desc()).limit(1) } where.fetchAny(0, String::class.java) @@ -144,7 +146,7 @@ class PipelineResVersionDao { where.and(VERSION.eq(version)) } else { // 非新的逻辑请求则保持旧逻辑 - if (includeDraft != true) where.and(DRAFT_FLAG.ne(true)) + if (includeDraft != true) where.and(STATUS.ne(VersionStatus.COMMITTING.name)) where.orderBy(VERSION.desc()).limit(1) } val record = where.fetchAny() ?: return null @@ -167,7 +169,7 @@ class PipelineResVersionDao { settingVersion = record.settingVersion, referFlag = record.referFlag, referCount = record.referCount, - draftFlag = record.draftFlag, + status = record.status?.let { VersionStatus.valueOf(it) }, refs = record.refs ) } @@ -215,22 +217,22 @@ class PipelineResVersionDao { .limit(limit).offset(offset) .fetch() - result.forEach { + result.forEach { record -> list.add( PipelineVersionSimple( pipelineId = pipelineId, - creator = it.creator ?: "unknown", - createTime = it.createTime?.timestampmilli() ?: 0, - version = it.version ?: 1, - versionName = it.versionName ?: "init", - referFlag = it.referFlag, - referCount = it.referCount, - pipelineVersion = it.pipelineVersion, - triggerVersion = it.triggerVersion, - settingVersion = it.settingVersion, - draftFlag = it.draftFlag, - debugBuildId = it.debugBuildId, - pacRefs = it.refs + creator = record.creator ?: "unknown", + createTime = record.createTime?.timestampmilli() ?: 0, + version = record.version ?: 1, + versionName = record.versionName ?: "init", + referFlag = record.referFlag, + referCount = record.referCount, + pipelineVersion = record.pipelineVersion, + triggerVersion = record.triggerVersion, + settingVersion = record.settingVersion, + status = record.status?.let { VersionStatus.valueOf(it) }, + debugBuildId = record.debugBuildId, + pacRefs = record.refs ) ) } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index 7890240737d..fc4cd9ef38e 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -43,6 +43,7 @@ import com.tencent.devops.common.pipeline.container.Stage import com.tencent.devops.common.pipeline.container.TriggerContainer import com.tencent.devops.common.pipeline.container.VMBuildContainer import com.tencent.devops.common.pipeline.enums.ChannelCode +import com.tencent.devops.common.pipeline.enums.VersionStatus import com.tencent.devops.common.pipeline.extend.ModelCheckPlugin import com.tencent.devops.common.pipeline.option.MatrixControlOption import com.tencent.devops.common.pipeline.pojo.BuildNo @@ -615,7 +616,7 @@ class PipelineRepositoryService constructor( pipelineVersion = modelVersion, triggerVersion = triggerVersion, settingVersion = settingVersion, - draftFlag = saveDraft == true + status = if (saveDraft == true) VersionStatus.COMMITTING else VersionStatus.RELEASED ) // 初始化流水线构建统计表 pipelineBuildSummaryDao.create(dslContext, projectId, pipelineId, buildNo) @@ -750,7 +751,7 @@ class PipelineRepositoryService constructor( pipelineVersion = pipelineVersion, triggerVersion = triggerVersion, settingVersion = settingVersion, - draftFlag = saveDraft == true + status = if (saveDraft == true) VersionStatus.COMMITTING else VersionStatus.RELEASED ) // 针对新增version表做的数据迁移 watcher.start("updatePipelineResourceVersion") @@ -779,7 +780,7 @@ class PipelineRepositoryService constructor( pipelineVersion = null, triggerVersion = null, settingVersion = null, - draftFlag = false + status = VersionStatus.RELEASED ) } } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt index d2cd40d92f4..533b5472333 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt @@ -28,6 +28,7 @@ package com.tencent.devops.process.engine.service import com.tencent.devops.common.api.exception.ErrorCodeException +import com.tencent.devops.common.pipeline.enums.VersionStatus import com.tencent.devops.common.redis.RedisOperation import com.tencent.devops.process.constant.ProcessMessageCode import com.tencent.devops.process.dao.PipelineSettingVersionDao @@ -149,7 +150,7 @@ class PipelineRepositoryVersionService( pipelineVersion = it.pipelineVersion, triggerVersion = it.triggerVersion, settingVersion = it.settingVersion, - draftFlag = it.draftFlag, + status = it.status, debugBuildId = it.debugBuildId, pacRefs = it.pacRefs ) From 55841c11ec0607df69e1f1ba24c293d484129750 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Sun, 23 Jul 2023 17:50:24 +0800 Subject: [PATCH 027/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/user/UserPipelineVersionResource.kt | 144 ++++++++++++ .../engine/dao/PipelineResVersionDao.kt | 57 ++++- .../PipelineRepositoryVersionService.kt | 42 +++- .../process/api/UserPipelineResourceImpl.kt | 1 - .../api/UserPipelineVersionResourceImpl.kt | 220 ++++++++++++++++++ .../service/PipelineVersionFacadeService.kt | 42 +++- .../service/PipelineInfoFacadeService.kt | 3 +- 7 files changed, 493 insertions(+), 16 deletions(-) create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt new file mode 100644 index 00000000000..860e398369c --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -0,0 +1,144 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.api.user + +import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID +import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE +import com.tencent.devops.common.api.pojo.Page +import com.tencent.devops.common.api.pojo.Result +import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.process.engine.pojo.PipelineResVersion +import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage +import com.tencent.devops.process.pojo.setting.PipelineSetting +import io.swagger.annotations.Api +import io.swagger.annotations.ApiOperation +import io.swagger.annotations.ApiParam +import javax.validation.Valid +import javax.ws.rs.Consumes +import javax.ws.rs.GET +import javax.ws.rs.HeaderParam +import javax.ws.rs.POST +import javax.ws.rs.Path +import javax.ws.rs.PathParam +import javax.ws.rs.Produces +import javax.ws.rs.QueryParam +import javax.ws.rs.core.MediaType + +@Api(tags = ["USER_PIPELINE_VERSION"], description = "用户-流水线资源") +@Path("/user/version") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Suppress("LongParameterList") +interface UserPipelineVersionResource { + + @ApiOperation("保存流水线编排") + @POST + @Path("/projects/{projectId}/pipelines/{pipelineId}/savePipeline") + fun savePipeline( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String, + @ApiParam(value = "流水线模型与设置", required = true) + @Valid + model: Model, + @ApiParam("变更说明", required = false) + @QueryParam("description") + description: String? = null + ): Result + + @ApiOperation("保存流水线设置") + @POST + @Path("/projects/{projectId}/pipelines/{pipelineId}/saveSetting") + fun saveSetting( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String, + @ApiParam(value = "流水线设置", required = true) + setting: PipelineSetting + ): Result + + @ApiOperation("获取流水线编创建人列表(分页)") + @GET + @Path("/projects/{projectId}/pipelines/{pipelineId}/creatorList") + fun creatorList( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String, + @ApiParam("第几页", required = false, defaultValue = "1") + @QueryParam("page") + page: Int?, + @ApiParam("每页多少条", required = false, defaultValue = "20") + @QueryParam("pageSize") + pageSize: Int? + ): Result> + + @ApiOperation("流水线编排版本列表(搜索、分页)") + @GET + @Path("/projects/{projectId}/pipelines/{pipelineId}/versions") + fun versionList( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String, + @ApiParam("过滤创建人", required = false) + @QueryParam("creator") + creator: String? = null, + @ApiParam("模糊查询变更说明", required = false) + @QueryParam("description") + description: String? = null, + @ApiParam("第几页", required = false, defaultValue = "1") + @QueryParam("page") + page: Int?, + @ApiParam("每页多少条", required = false, defaultValue = "20") + @QueryParam("pageSize") + pageSize: Int? + ): Result> +} diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt index 0d6468a60f8..024d4640d9c 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt @@ -207,16 +207,18 @@ class PipelineResVersionDao { projectId: String, pipelineId: String, offset: Int, - limit: Int + limit: Int, + creator: String?, + description: String? ): List { val list = mutableListOf() with(T_PIPELINE_RESOURCE_VERSION) { - val result = dslContext.selectFrom(this) + val query = dslContext.selectFrom(this) .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) - .orderBy(VERSION.desc()) - .limit(limit).offset(offset) - .fetch() - + creator?.let { query.and(CREATOR.eq(creator)) } + description?.let { query.and(DESCRIPTION.like("%$description%")) } + val result = query + .orderBy(VERSION.desc()).limit(limit).offset(offset).fetch() result.forEach { record -> list.add( PipelineVersionSimple( @@ -240,12 +242,49 @@ class PipelineResVersionDao { return list } - fun count(dslContext: DSLContext, projectId: String, pipelineId: String): Int { + fun getVersionCreatorInPage( + dslContext: DSLContext, + projectId: String, + pipelineId: String, + offset: Int, + limit: Int + ): List { + with(T_PIPELINE_RESOURCE_VERSION) { + return dslContext.selectDistinct(CREATOR) + .from(this) + .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) + .limit(limit).offset(offset) + .fetch().map { it.component1() } + } + } + + fun count( + dslContext: DSLContext, + projectId: String, + pipelineId: String, + creator: String?, + description: String? + ): Int { + with(T_PIPELINE_RESOURCE_VERSION) { + val query = dslContext.select(DSL.count(PIPELINE_ID)) + .from(this) + .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) + creator?.let { query.and(CREATOR.eq(creator)) } + description?.let { query.and(DESCRIPTION.like("%$description%")) } + return query.fetchOne(0, Int::class.java)!! + } + } + + fun countVersionCreator( + dslContext: DSLContext, + projectId: String, + pipelineId: String + ): Int { with(T_PIPELINE_RESOURCE_VERSION) { - return dslContext.select(DSL.count(PIPELINE_ID)) + val query = dslContext.selectDistinct(CREATOR) .from(this) .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) - .fetchOne(0, Int::class.java)!! + return query.fetchCount() } } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt index 533b5472333..7d471f8e06f 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt @@ -28,7 +28,6 @@ package com.tencent.devops.process.engine.service import com.tencent.devops.common.api.exception.ErrorCodeException -import com.tencent.devops.common.pipeline.enums.VersionStatus import com.tencent.devops.common.redis.RedisOperation import com.tencent.devops.process.constant.ProcessMessageCode import com.tencent.devops.process.dao.PipelineSettingVersionDao @@ -42,6 +41,7 @@ import org.jooq.impl.DSL import org.springframework.stereotype.Service @Service +@Suppress("LongParameterList") class PipelineRepositoryVersionService( private val dslContext: DSLContext, private val pipelineResVersionDao: PipelineResVersionDao, @@ -113,17 +113,27 @@ class PipelineRepositoryVersionService( projectId: String, pipelineId: String, offset: Int, - limit: Int + limit: Int, + creator: String?, + description: String? ): Pair> { if (pipelineInfo == null) { return Pair(0, emptyList()) } - val count = pipelineResVersionDao.count(dslContext, projectId, pipelineId) + val count = pipelineResVersionDao.count( + dslContext = dslContext, + projectId = projectId, + pipelineId = pipelineId, + creator = creator, + description = description + ) val result = pipelineResVersionDao.listPipelineVersion( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, + creator = creator, + description = description, offset = offset, limit = limit ) @@ -158,4 +168,30 @@ class PipelineRepositoryVersionService( } return count to list } + + fun getVersionCreatorInPage( + pipelineInfo: PipelineInfo?, + projectId: String, + pipelineId: String, + offset: Int, + limit: Int + ): Pair> { + if (pipelineInfo == null) { + return Pair(0, emptyList()) + } + + val count = pipelineResVersionDao.countVersionCreator( + dslContext = dslContext, + projectId = projectId, + pipelineId = pipelineId + ) + val result = pipelineResVersionDao.getVersionCreatorInPage( + dslContext = dslContext, + projectId = projectId, + pipelineId = pipelineId, + offset = offset, + limit = limit + ) + return count to result + } } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index 77bd501c8d3..af8e30356a0 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -725,7 +725,6 @@ class UserPipelineResourceImpl @Autowired constructor( checkParam(userId, projectId) return Result( pipelineVersionFacadeService.listPipelineVersion( - userId = userId, projectId = projectId, pipelineId = pipelineId, page = page, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt new file mode 100644 index 00000000000..cc0e5f8a5f7 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -0,0 +1,220 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.api + +import com.tencent.devops.common.api.constant.CommonMessageCode +import com.tencent.devops.common.api.exception.ParamBlankException +import com.tencent.devops.common.api.pojo.Page +import com.tencent.devops.common.api.pojo.Result +import com.tencent.devops.common.api.util.MessageUtil +import com.tencent.devops.common.auth.api.AuthPermission +import com.tencent.devops.common.auth.api.AuthResourceType +import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.common.pipeline.enums.ChannelCode +import com.tencent.devops.common.web.RestResource +import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.process.api.user.UserPipelineVersionResource +import com.tencent.devops.process.audit.service.AuditService +import com.tencent.devops.process.engine.pojo.PipelineResVersion +import com.tencent.devops.process.engine.service.PipelineVersionFacadeService +import com.tencent.devops.process.engine.service.rule.PipelineRuleService +import com.tencent.devops.process.permission.PipelinePermissionService +import com.tencent.devops.process.pojo.audit.Audit +import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage +import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.process.service.PipelineInfoFacadeService +import com.tencent.devops.process.service.PipelineListFacadeService +import com.tencent.devops.process.service.PipelineRemoteAuthService +import com.tencent.devops.process.service.StageTagService +import com.tencent.devops.process.service.label.PipelineGroupService +import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService +import org.springframework.beans.factory.annotation.Autowired + +@RestResource +class UserPipelineVersionResourceImpl @Autowired constructor( + private val pipelineListFacadeService: PipelineListFacadeService, + private val pipelineSettingFacadeService: PipelineSettingFacadeService, + private val pipelineGroupService: PipelineGroupService, + private val pipelineRemoteAuthService: PipelineRemoteAuthService, + private val pipelinePermissionService: PipelinePermissionService, + private val stageTagService: StageTagService, + private val pipelineInfoFacadeService: PipelineInfoFacadeService, + private val auditService: AuditService, + private val pipelineVersionFacadeService: PipelineVersionFacadeService, + private val pipelineRuleService: PipelineRuleService +) : UserPipelineVersionResource { + + override fun savePipeline( + userId: String, + projectId: String, + pipelineId: String, + model: Model, + description: String? + ): Result { + checkParam(userId, projectId) + val pipelineResult = pipelineInfoFacadeService.editPipeline( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + model = model, + channelCode = ChannelCode.BS, + checkPermission = true, + checkTemplate = true, + saveDraft = true, + description = description + ) + auditService.createAudit( + Audit( + resourceType = AuthResourceType.PIPELINE_DEFAULT.value, + resourceId = pipelineId, + resourceName = model.name, + userId = userId, + action = "edit", + actionContent = "Save Ver.${pipelineResult.version}", + projectId = projectId + ) + ) + return Result(true) + } + + override fun saveSetting( + userId: String, + projectId: String, + pipelineId: String, + setting: PipelineSetting + ): Result { + checkParam(userId, projectId) + val savedSetting = pipelineSettingFacadeService.saveSetting( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + setting = setting, + checkPermission = true + ) + pipelineInfoFacadeService.updatePipelineSettingVersion( + userId = userId, + projectId = setting.projectId, + pipelineId = setting.pipelineId, + settingVersion = savedSetting.version + ) + auditService.createAudit( + Audit( + resourceType = AuthResourceType.PIPELINE_DEFAULT.value, + resourceId = pipelineId, + resourceName = setting.pipelineName, + userId = userId, + action = "edit", + actionContent = "Update Setting", + projectId = projectId + ) + ) + return Result(true) + } + + override fun creatorList( + userId: String, + projectId: String, + pipelineId: String, + page: Int?, + pageSize: Int? + ): Result> { + checkParam(userId, projectId) + val permission = AuthPermission.VIEW + pipelinePermissionService.validPipelinePermission( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + permission = permission, + message = MessageUtil.getMessageByLocale( + CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, + I18nUtil.getLanguage(userId), + arrayOf( + userId, + projectId, + permission.getI18n(I18nUtil.getLanguage(userId)), + pipelineId + ) + ) + ) + val result = pipelineVersionFacadeService.getVersionCreatorInPage( + projectId = projectId, + pipelineId = pipelineId, + page = page, + pageSize = pageSize + ) + return Result(result) + } + + override fun versionList( + userId: String, + projectId: String, + pipelineId: String, + creator: String?, + description: String?, + page: Int?, + pageSize: Int? + ): Result> { + checkParam(userId, projectId) + val permission = AuthPermission.VIEW + pipelinePermissionService.validPipelinePermission( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + permission = permission, + message = MessageUtil.getMessageByLocale( + CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, + I18nUtil.getLanguage(userId), + arrayOf( + userId, + projectId, + permission.getI18n(I18nUtil.getLanguage(userId)), + pipelineId + ) + ) + ) + return Result( + pipelineVersionFacadeService.listPipelineVersion( + projectId = projectId, + pipelineId = pipelineId, + creator = creator, + description = description, + page = page, + pageSize = pageSize + ) + ) + } + + private fun checkParam(userId: String, projectId: String) { + if (userId.isBlank()) { + throw ParamBlankException("Invalid userId") + } + if (projectId.isBlank()) { + throw ParamBlankException("Invalid projectId") + } + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt index 0c6ecf6b734..f500ef4da18 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt @@ -29,6 +29,7 @@ package com.tencent.devops.process.engine.service import com.tencent.devops.common.api.constant.CommonMessageCode import com.tencent.devops.common.api.model.SQLLimit +import com.tencent.devops.common.api.pojo.Page import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.api.util.PageUtil import com.tencent.devops.common.auth.api.AuthPermission @@ -40,6 +41,7 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service @Service +@Suppress("LongParameterList") class PipelineVersionFacadeService @Autowired constructor( private val pipelineRepositoryService: PipelineRepositoryService, private val pipelineRepositoryVersionService: PipelineRepositoryVersionService, @@ -83,11 +85,12 @@ class PipelineVersionFacadeService @Autowired constructor( } fun listPipelineVersion( - userId: String, projectId: String, pipelineId: String, page: Int?, - pageSize: Int? + pageSize: Int?, + creator: String? = null, + description: String? = null ): PipelineViewPipelinePage { val pageNotNull = page ?: 0 val pageSizeNotNull = pageSize ?: -1 @@ -102,6 +105,8 @@ class PipelineVersionFacadeService @Autowired constructor( pipelineInfo = pipelineInfo, projectId = projectId, pipelineId = pipelineId, + creator = creator, + description = description, offset = offset, limit = limit ) @@ -113,4 +118,37 @@ class PipelineVersionFacadeService @Autowired constructor( records = pipelines ) } + + fun getVersionCreatorInPage( + projectId: String, + pipelineId: String, + page: Int?, + pageSize: Int?, + creator: String? = null, + description: String? = null + ): Page { + val pageNotNull = page ?: 0 + val pageSizeNotNull = pageSize ?: -1 + var slqLimit: SQLLimit? = null + if (pageSizeNotNull != -1) slqLimit = PageUtil.convertPageSizeToSQLLimit(pageNotNull, pageSizeNotNull) + + val offset = slqLimit?.offset ?: 0 + val limit = slqLimit?.limit ?: -1 + // 数据量不多,直接全拉 + val pipelineInfo = pipelineRepositoryService.getPipelineInfo(projectId, pipelineId) + val (size, pipelines) = pipelineRepositoryVersionService.getVersionCreatorInPage( + pipelineInfo = pipelineInfo, + projectId = projectId, + pipelineId = pipelineId, + offset = offset, + limit = limit + ) + + return Page( + page = pageNotNull, + pageSize = pageSizeNotNull, + count = size.toLong(), + records = pipelines + ) + } } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index 620a74720c4..89f99c90909 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -662,7 +662,8 @@ class PipelineInfoFacadeService @Autowired constructor( checkTemplate: Boolean = true, updateLastModifyUser: Boolean? = true, savedSetting: PipelineSetting? = null, - saveDraft: Boolean? = false + saveDraft: Boolean? = false, + description: String? = null ): DeployPipelineResult { if (checkTemplate && templateService.isTemplatePipeline(projectId, pipelineId)) { throw ErrorCodeException( From 28c46209a2e7cd130685532d231b37d4861d4f2d Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 24 Jul 2023 15:22:22 +0800 Subject: [PATCH 028/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0=E7=89=88=E6=9C=AC=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/api/user/UserPipelineVersionResource.kt | 4 ++-- .../process/api/UserPipelineVersionResourceImpl.kt | 12 +----------- 2 files changed, 3 insertions(+), 13 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 860e398369c..b83de1218d4 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -56,9 +56,9 @@ import javax.ws.rs.core.MediaType @Suppress("LongParameterList") interface UserPipelineVersionResource { - @ApiOperation("保存流水线编排") + @ApiOperation("保存流水线编排草稿") @POST - @Path("/projects/{projectId}/pipelines/{pipelineId}/savePipeline") + @Path("/projects/{projectId}/pipelines/{pipelineId}/saveDraft") fun savePipeline( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index cc0e5f8a5f7..43ac4fb8061 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -42,31 +42,21 @@ import com.tencent.devops.process.api.user.UserPipelineVersionResource import com.tencent.devops.process.audit.service.AuditService import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.engine.service.PipelineVersionFacadeService -import com.tencent.devops.process.engine.service.rule.PipelineRuleService import com.tencent.devops.process.permission.PipelinePermissionService import com.tencent.devops.process.pojo.audit.Audit import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import com.tencent.devops.process.pojo.setting.PipelineSetting import com.tencent.devops.process.service.PipelineInfoFacadeService -import com.tencent.devops.process.service.PipelineListFacadeService -import com.tencent.devops.process.service.PipelineRemoteAuthService -import com.tencent.devops.process.service.StageTagService -import com.tencent.devops.process.service.label.PipelineGroupService import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService import org.springframework.beans.factory.annotation.Autowired @RestResource class UserPipelineVersionResourceImpl @Autowired constructor( - private val pipelineListFacadeService: PipelineListFacadeService, private val pipelineSettingFacadeService: PipelineSettingFacadeService, - private val pipelineGroupService: PipelineGroupService, - private val pipelineRemoteAuthService: PipelineRemoteAuthService, private val pipelinePermissionService: PipelinePermissionService, - private val stageTagService: StageTagService, private val pipelineInfoFacadeService: PipelineInfoFacadeService, private val auditService: AuditService, - private val pipelineVersionFacadeService: PipelineVersionFacadeService, - private val pipelineRuleService: PipelineRuleService + private val pipelineVersionFacadeService: PipelineVersionFacadeService ) : UserPipelineVersionResource { override fun savePipeline( From c266132dbbcd3c635c0eb9b8c6e625bc28d3fbf7 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 25 Jul 2023 19:59:11 +0800 Subject: [PATCH 029/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0=E7=89=88=E6=9C=AC=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../engine/dao/PipelineResVersionDao.kt | 11 ++++++--- .../service/PipelineRepositoryService.kt | 24 ++++++++++++------- .../service/PipelineAtomReplaceCronService.kt | 1 + .../PipelineAtomRollBackCronService.kt | 1 + .../service/PipelineInfoFacadeService.kt | 6 +++-- 5 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt index 024d4640d9c..b0570e20d48 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt @@ -54,7 +54,8 @@ class PipelineResVersionDao { pipelineVersion: Int?, triggerVersion: Int?, settingVersion: Int?, - status: VersionStatus? + status: VersionStatus?, + description: String? ) { create( dslContext = dslContext, @@ -67,7 +68,8 @@ class PipelineResVersionDao { pipelineVersion = pipelineVersion, triggerVersion = triggerVersion, settingVersion = settingVersion, - status = status + status = status, + description = description ) } @@ -82,7 +84,8 @@ class PipelineResVersionDao { pipelineVersion: Int?, triggerVersion: Int?, settingVersion: Int?, - status: VersionStatus? + status: VersionStatus?, + description: String? ) { with(T_PIPELINE_RESOURCE_VERSION) { dslContext.insertInto(this) @@ -97,6 +100,7 @@ class PipelineResVersionDao { .set(TRIGGER_VERSION, triggerVersion) .set(SETTING_VERSION, settingVersion) .set(STATUS, status?.name) + .set(DESCRIPTION, description) .onDuplicateKeyUpdate() .set(MODEL, modelString) .set(CREATOR, creator) @@ -105,6 +109,7 @@ class PipelineResVersionDao { .set(TRIGGER_VERSION, triggerVersion) .set(SETTING_VERSION, settingVersion) .set(STATUS, status?.name) + .set(DESCRIPTION, description) .execute() } } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index fc4cd9ef38e..1a93545de67 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -158,7 +158,8 @@ class PipelineRepositoryService constructor( templateId: String? = null, updateLastModifyUser: Boolean? = true, savedSetting: PipelineSetting? = null, - saveDraft: Boolean? = false + saveDraft: Boolean? = false, + description: String? ): DeployPipelineResult { // 生成流水线ID,新流水线以p-开头,以区分以前旧数据 @@ -202,7 +203,8 @@ class PipelineRepositoryService constructor( channelCode = channelCode, setting = pipelineSetting, updateLastModifyUser = updateLastModifyUser, - saveDraft = saveDraft + saveDraft = saveDraft, + description = description ) } else { create( @@ -217,7 +219,8 @@ class PipelineRepositoryService constructor( modelTasks = modelTasks, useTemplateSettings = useTemplateSettings, templateId = templateId, - saveDraft = saveDraft + saveDraft = saveDraft, + description = description ) } } @@ -500,7 +503,8 @@ class PipelineRepositoryService constructor( modelTasks: Collection, useTemplateSettings: Boolean? = false, templateId: String? = null, - saveDraft: Boolean? = false + saveDraft: Boolean? = false, + description: String? ): DeployPipelineResult { val modelVersion = 1 val pipelineVersion = 1 @@ -616,7 +620,8 @@ class PipelineRepositoryService constructor( pipelineVersion = modelVersion, triggerVersion = triggerVersion, settingVersion = settingVersion, - status = if (saveDraft == true) VersionStatus.COMMITTING else VersionStatus.RELEASED + status = if (saveDraft == true) VersionStatus.COMMITTING else VersionStatus.RELEASED, + description = description ) // 初始化流水线构建统计表 pipelineBuildSummaryDao.create(dslContext, projectId, pipelineId, buildNo) @@ -658,7 +663,8 @@ class PipelineRepositoryService constructor( channelCode: ChannelCode, setting: PipelineSetting? = null, updateLastModifyUser: Boolean? = true, - saveDraft: Boolean? = false + saveDraft: Boolean? = false, + description: String? ): DeployPipelineResult { val taskCount: Int = model.taskCount() var version = 0 @@ -751,7 +757,8 @@ class PipelineRepositoryService constructor( pipelineVersion = pipelineVersion, triggerVersion = triggerVersion, settingVersion = settingVersion, - status = if (saveDraft == true) VersionStatus.COMMITTING else VersionStatus.RELEASED + status = if (saveDraft == true) VersionStatus.COMMITTING else VersionStatus.RELEASED, + description = description ) // 针对新增version表做的数据迁移 watcher.start("updatePipelineResourceVersion") @@ -780,7 +787,8 @@ class PipelineRepositoryService constructor( pipelineVersion = null, triggerVersion = null, settingVersion = null, - status = VersionStatus.RELEASED + status = VersionStatus.RELEASED, + description = description ) } } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomReplaceCronService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomReplaceCronService.kt index 9376f1121cd..cf49fe274bd 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomReplaceCronService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomReplaceCronService.kt @@ -609,6 +609,7 @@ class PipelineAtomReplaceCronService @Autowired constructor( signPipelineId = pipelineId, userId = creator, channelCode = channelCode, + description = null, create = false ).version pipelineAtomReplaceHistoryDao.createAtomReplaceHistory( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomRollBackCronService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomRollBackCronService.kt index aede3c73214..0823e222fa7 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomRollBackCronService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomRollBackCronService.kt @@ -254,6 +254,7 @@ class PipelineAtomRollBackCronService @Autowired constructor( signPipelineId = pipelineId, userId = pipelineInfo.lastModifyUser, channelCode = pipelineInfo.channelCode, + description = null, create = false ) pipelineAtomReplaceHistoryDao.updateAtomReplaceHistory( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index 89f99c90909..8a5dcf9847c 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -369,7 +369,8 @@ class PipelineInfoFacadeService @Autowired constructor( channelCode = channelCode, create = true, useTemplateSettings = useTemplateSettings, - templateId = model.templateId + templateId = model.templateId, + description = null ).pipelineId watcher.stop() @@ -744,7 +745,8 @@ class PipelineInfoFacadeService @Autowired constructor( create = false, updateLastModifyUser = updateLastModifyUser, savedSetting = savedSetting, - saveDraft = saveDraft + saveDraft = saveDraft, + description = description ) if (checkPermission) { pipelinePermissionService.modifyResource(projectId, pipelineId, model.name) From 1984d5eda780147050952678bf484b4659f35c9e Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 25 Jul 2023 20:36:24 +0800 Subject: [PATCH 030/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=BB=B4=E6=8A=A4=E8=BF=87=E7=A8=8B=E4=B8=AD=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/tencent/devops/process/enums/OperationLogType.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/enums/OperationLogType.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/enums/OperationLogType.kt index 9c41904e351..dd6225d7e8b 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/enums/OperationLogType.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/enums/OperationLogType.kt @@ -27,7 +27,7 @@ package com.tencent.devops.process.enums -enum class OperationLogType(val description: String = "") { +enum class OperationLogType(val description: String) { CREATE_PIPELINE_AND_DRAFT("创建流水线首次保存草稿:「创建了草稿」"), CREATE_DRAFT_VERSION("编辑流水线生成草稿:「从 P1.T2.0 创建了草稿」"), UPDATE_DRAFT_VERSION("修改草稿保存后:「修改了草稿」"), From 1d75be36ba0689b97dfcfff12aed048d440ec564 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Wed, 26 Jul 2023 11:50:19 +0800 Subject: [PATCH 031/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0=E7=89=88=E6=9C=AC=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/engine/service/PipelineRepositoryService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index 1a93545de67..509cc442747 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -159,7 +159,7 @@ class PipelineRepositoryService constructor( updateLastModifyUser: Boolean? = true, savedSetting: PipelineSetting? = null, saveDraft: Boolean? = false, - description: String? + description: String? = null ): DeployPipelineResult { // 生成流水线ID,新流水线以p-开头,以区分以前旧数据 From 9deb39750411c505dfd10b8e0203b57acfbc727e Mon Sep 17 00:00:00 2001 From: royalhuang Date: Wed, 26 Jul 2023 17:18:32 +0800 Subject: [PATCH 032/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0=E7=89=88=E6=9C=AC=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/api/UserPipelineVersionResourceImpl.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index 43ac4fb8061..16d042b3eb2 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -191,8 +191,8 @@ class UserPipelineVersionResourceImpl @Autowired constructor( pipelineVersionFacadeService.listPipelineVersion( projectId = projectId, pipelineId = pipelineId, - creator = creator, - description = description, + creator = creator?.takeIf { it.isNotBlank() }, + description = description?.takeIf { it.isNotBlank() }, page = page, pageSize = pageSize ) From 380d6b3c54ad18d83f9c2b95e4a6d38eaeb21b84 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Wed, 26 Jul 2023 17:19:27 +0800 Subject: [PATCH 033/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0=E7=89=88=E6=9C=AC=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/engine/service/PipelineVersionFacadeService.kt | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt index f500ef4da18..9e19610b955 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt @@ -123,9 +123,7 @@ class PipelineVersionFacadeService @Autowired constructor( projectId: String, pipelineId: String, page: Int?, - pageSize: Int?, - creator: String? = null, - description: String? = null + pageSize: Int? ): Page { val pageNotNull = page ?: 0 val pageSizeNotNull = pageSize ?: -1 From e5c27818c6548a611ad5583cdf16deb76a8bd9f9 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 27 Jul 2023 16:43:32 +0800 Subject: [PATCH 034/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E8=A1=A5=E5=85=85=E8=BF=94=E5=9B=9E=E6=95=B0?= =?UTF-8?q?=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/pojo/PipelineDetail.kt | 14 ++++++++++++-- .../devops/process/pojo/PipelineDetailInfo.kt | 18 ++++++++++++++---- .../process/api/UserPipelineResourceImpl.kt | 10 ++++++++-- .../service/PipelineListFacadeService.kt | 14 +++++++++----- .../pipeline/PipelineSettingFacadeService.kt | 18 +++++++++++++----- 5 files changed, 56 insertions(+), 18 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetail.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetail.kt index 04b3cf8df5d..4e29e3c225d 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetail.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetail.kt @@ -39,7 +39,17 @@ data class PipelineDetail( @ApiModelProperty("是否收藏") val hasCollect: Boolean, @ApiModelProperty("是否可以手动触发") - val canManualStartup: Int, + val canManualStartup: Boolean, @ApiModelProperty("是否有编辑权限") - val hasPermission: Boolean + val hasPermission: Boolean, + @ApiModelProperty("流水线描述") + val pipelineDesc: String, + @ApiModelProperty("创建者") + val creator: String, + @ApiModelProperty("创建时间") + val createTime: Long = 0, + @ApiModelProperty("更新时间") + val updateTime: Long = 0, + @ApiModelProperty("流水线组名称列表", required = false) + var viewNames: List? = null ) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetailInfo.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetailInfo.kt index f4e0f6ce87c..1a2d8ada236 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetailInfo.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetailInfo.kt @@ -39,15 +39,25 @@ data class PipelineDetailInfo( @ApiModelProperty("是否收藏") val hasCollect: Boolean, @ApiModelProperty("canManualStartup") - val canManualStartup: Int, + val canManualStartup: Boolean, @ApiModelProperty("是否关联模板") val instanceFromTemplate: Boolean, @ApiModelProperty("流水线版本") val pipelineVersion: String, - @ApiModelProperty("部署时间") - val deploymentTime: String, + @ApiModelProperty("发布时间-时间戳") + val deploymentTime: Long, @ApiModelProperty("是否有编辑权限") val hasPermission: Boolean, @ApiModelProperty("关联模板ID", required = false) - var templateId: String? = null + var templateId: String? = null, + @ApiModelProperty("流水线描述") + val pipelineDesc: String, + @ApiModelProperty("创建者") + val creator: String, + @ApiModelProperty("创建时间") + val createTime: Long = 0, + @ApiModelProperty("更新时间") + val updateTime: Long = 0, + @ApiModelProperty("流水线组名称列表", required = false) + var viewNames: List? = null ) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index af8e30356a0..7a8850631b5 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -393,7 +393,8 @@ class UserPipelineResourceImpl @Autowired constructor( userId = userId, projectId = projectId, pipelineId = pipelineId, - version = resource.settingVersion ?: resource.version + version = resource.settingVersion ?: resource.version, + detailInfo = detailInfo ) pipelineRecentUseService.record(userId, projectId, pipelineId) return Result( @@ -404,7 +405,12 @@ class UserPipelineResourceImpl @Autowired constructor( pipelineName = it.pipelineName, hasCollect = it.hasCollect, canManualStartup = it.canManualStartup, - hasPermission = it.hasPermission + hasPermission = it.hasPermission, + pipelineDesc = it.pipelineDesc, + creator = it.creator, + createTime = it.createTime, + updateTime = it.updateTime, + viewNames = it.viewNames ) }, pipelineResource = resource, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineListFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineListFacadeService.kt index 548c9033387..a650970fb50 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineListFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineListFacadeService.kt @@ -1726,8 +1726,7 @@ class PipelineListFacadeService @Autowired constructor( ) ) } - val pipelineInfo = pipelineInfoDao.getPipelineInfo( - dslContext = dslContext, + val pipelineInfo = pipelineRepositoryService.getPipelineInfo( projectId = projectId, pipelineId = pipelineId ) ?: return null @@ -1762,11 +1761,16 @@ class PipelineListFacadeService @Autowired constructor( pipelineName = pipelineInfo.pipelineName, instanceFromTemplate = instanceFromTemplate, hasCollect = hasCollect, - canManualStartup = pipelineInfo.manualStartup, + canManualStartup = pipelineInfo.canManualStartup, pipelineVersion = pipelineInfo.version.toString(), - deploymentTime = DateTimeUtil.toDateTime(pipelineInfo.updateTime), + deploymentTime = pipelineInfo.updateTime, hasPermission = hasEditPermission, - templateId = templateId + templateId = templateId, + creator = pipelineInfo.creator, + pipelineDesc = pipelineInfo.pipelineDesc, + createTime = pipelineInfo.createTime, + updateTime = pipelineInfo.updateTime, + viewNames = pipelineInfo.viewNames ) } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt index fe8f9b37e03..9b872c54777 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt @@ -44,6 +44,7 @@ import com.tencent.devops.process.engine.atom.AtomUtils import com.tencent.devops.process.engine.pojo.event.PipelineUpdateEvent import com.tencent.devops.process.engine.service.PipelineRepositoryService import com.tencent.devops.process.permission.PipelinePermissionService +import com.tencent.devops.process.pojo.PipelineDetailInfo import com.tencent.devops.process.pojo.audit.Audit import com.tencent.devops.process.pojo.config.JobCommonSettingConfig import com.tencent.devops.process.pojo.config.PipelineCommonSettingConfig @@ -194,7 +195,8 @@ class PipelineSettingFacadeService @Autowired constructor( pipelineId: String, channelCode: ChannelCode = ChannelCode.BS, version: Int = 0, - checkPermission: Boolean = false + checkPermission: Boolean = false, + detailInfo: PipelineDetailInfo? = null ): PipelineSetting { if (checkPermission) { @@ -225,16 +227,20 @@ class PipelineSettingFacadeService @Autowired constructor( labels.addAll(it.labels) } if (settingInfo == null) { - val pipeline = client.get(ServicePipelineResource::class).getPipelineInfo( + val (pipelineName, pipelineDesc) = detailInfo?.let { + Pair(it.pipelineName, it.pipelineDesc) + } ?: client.get(ServicePipelineResource::class).getPipelineInfo( projectId = projectId, pipelineId = pipelineId, channelCode = channelCode - ).data + ).data?.let { + Pair(it.pipelineName, it.pipelineDesc) + } ?: Pair(null, null) settingInfo = PipelineSetting( projectId = projectId, pipelineId = pipelineId, - pipelineName = pipeline?.pipelineName ?: "unknown pipeline name", - desc = pipeline?.pipelineDesc ?: "", + pipelineName = pipelineName ?: "unknown pipeline name", + desc = pipelineDesc ?: "", runLockType = PipelineRunLockType.MULTIPLE, successSubscription = Subscription(), failSubscription = Subscription(), @@ -249,6 +255,8 @@ class PipelineSettingFacadeService @Autowired constructor( val ve = pipelineSettingVersionService.getSubscriptionsVer(userId, projectId, pipelineId, version) settingInfo.successSubscription = ve.successSubscription settingInfo.failSubscription = ve.failSubscription + settingInfo.successSubscriptionList = ve.successSubscriptionList + settingInfo.failSubscriptionList = ve.failSubscriptionList } return settingInfo From e1ccc3274dd7594a6d4e413175407628430d1393 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Fri, 4 Aug 2023 18:01:20 +0800 Subject: [PATCH 035/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=BB=B4=E6=8A=A4=E8=BF=87=E7=A8=8B=E4=B8=AD=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/pojo/PipelineOperationLog.kt | 50 +++++++++ .../devops/process/dao/OperationLogDao.kt | 100 ++++++++++++++++++ 2 files changed, 150 insertions(+) create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineOperationLog.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/dao/OperationLogDao.kt diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineOperationLog.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineOperationLog.kt new file mode 100644 index 00000000000..b636a65bfcf --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineOperationLog.kt @@ -0,0 +1,50 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.pojo + +import com.tencent.devops.process.enums.OperationLogType +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty + +@ApiModel("流水线操作日志") +data class PipelineOperationLog( + @ApiModelProperty("唯一标识ID", required = true) + val id: Int, + @ApiModelProperty("项目ID", required = true) + val projectId: String, + @ApiModelProperty("流水线ID", required = true) + val pipelineId: String, + @ApiModelProperty("操作用户", required = true) + val operator: String, + @ApiModelProperty("操作类型", required = true) + val operationLogType: OperationLogType, + @ApiModelProperty("操作参数", required = true) + val params: String, + @ApiModelProperty("操作内容", required = false) + val description: String? +) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/dao/OperationLogDao.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/dao/OperationLogDao.kt new file mode 100644 index 00000000000..a864df2534e --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/dao/OperationLogDao.kt @@ -0,0 +1,100 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.dao + +import com.tencent.devops.model.process.tables.TPipelineOperationLog +import com.tencent.devops.process.enums.OperationLogType +import com.tencent.devops.process.pojo.PipelineOperationLog +import org.jooq.DSLContext +import org.springframework.stereotype.Repository + +@Repository +@Suppress("LongParameterList") +class OperationLogDao { + + fun add( + dslContext: DSLContext, + id: Int, + projectId: String, + pipelineId: String, + operator: String, + operationLogType: OperationLogType, + description: String? + ) { + with(TPipelineOperationLog.T_PIPELINE_OPERATION_LOG) { + dslContext.insertInto( + this, + ID, + PROJECT_ID, + PIPELINE_ID, + OPERATOR, + OPERATION_TYPE, + PARAMS, + DESCRIPTION + ).values( + id, + projectId, + pipelineId, + operator, + operator, + operationLogType.name, + description + ).execute() + } + } + + fun batchAddLogs( + dslContext: DSLContext, + operationLogList: List + ) { + with(TPipelineOperationLog.T_PIPELINE_OPERATION_LOG) { + val addStep = operationLogList.map { + dslContext.insertInto( + this, + ID, + PROJECT_ID, + PIPELINE_ID, + OPERATOR, + OPERATION_TYPE, + PARAMS, + DESCRIPTION + ) + .values( + it.id, + it.pipelineId, + it.pipelineId, + it.operator, + it.operationLogType.name, + it.params, + it.description + ) + } + dslContext.batch(addStep).execute() + } + } +} From 0e1e6a1b51ed39e4d300c29275af5f7c87df0a5b Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 7 Aug 2023 12:31:19 +0800 Subject: [PATCH 036/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=BB=B4=E6=8A=A4=E8=BF=87=E7=A8=8B=E4=B8=AD=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97=20#8197=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E6=97=A5=E5=BF=97=E5=AE=A1=E8=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/user/UserPipelineVersionResource.kt | 16 +++++ .../devops/process/enums/OperationLogType.kt | 14 +++- .../process/pojo/PipelineOperationLog.kt | 15 +++- .../engine/dao/PipelineResVersionDao.kt | 35 +++++++++ .../api/UserPipelineVersionResourceImpl.kt | 33 ++++++++- ...onLogDao.kt => PipelineOperationLogDao.kt} | 68 +++++++++++++++--- .../service/PipelineListFacadeService.kt | 1 - .../service/PipelineOperationLogService.kt | 72 +++++++++++++++++++ 8 files changed, 239 insertions(+), 15 deletions(-) rename src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/dao/{OperationLogDao.kt => PipelineOperationLogDao.kt} (60%) create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index b83de1218d4..5a2b2010e8b 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -33,6 +33,7 @@ import com.tencent.devops.common.api.pojo.Page import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.Model import com.tencent.devops.process.engine.pojo.PipelineResVersion +import com.tencent.devops.process.pojo.PipelineOperationLog import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import com.tencent.devops.process.pojo.setting.PipelineSetting import io.swagger.annotations.Api @@ -141,4 +142,19 @@ interface UserPipelineVersionResource { @QueryParam("pageSize") pageSize: Int? ): Result> + + @ApiOperation("获取流水线操作日志列表") + @GET + @Path("/projects/{projectId}/pipelines/{pipelineId}/log") + fun getPipelineOperationLogs( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String + ): Result> } diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/enums/OperationLogType.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/enums/OperationLogType.kt index dd6225d7e8b..379a9532c8e 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/enums/OperationLogType.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/enums/OperationLogType.kt @@ -37,5 +37,17 @@ enum class OperationLogType(val description: String) { UNABLE_PIPELINE("禁用流水线时:「禁用了流水线」"), ADD_PIPELINE_OWNER("添加流水线成员时:「添加 xxx,yyy 为执行者」"), ADD_PIPELINE_TO_GROUP("将流水线添加到流水线组时:「添加到流水线组 a」"), - MOVE_PIPELINE_OUT_OF_GROUP("将流水线移出流水线组时:「从流水线组 a 中移出」"); + MOVE_PIPELINE_OUT_OF_GROUP("将流水线移出流水线组时:「从流水线组 a 中移出」"), + NORMAL_SAVE_OPERATION("普通保存操作"); + + companion object { + fun parseType(type: String?): OperationLogType { + if (type.isNullOrBlank()) return NORMAL_SAVE_OPERATION + return try { + OperationLogType.valueOf(type) + } catch (ignore: Throwable) { + NORMAL_SAVE_OPERATION + } + } + } } diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineOperationLog.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineOperationLog.kt index b636a65bfcf..59b940730fb 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineOperationLog.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineOperationLog.kt @@ -27,6 +27,7 @@ package com.tencent.devops.process.pojo +import com.tencent.devops.common.pipeline.enums.VersionStatus import com.tencent.devops.process.enums.OperationLogType import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -39,12 +40,24 @@ data class PipelineOperationLog( val projectId: String, @ApiModelProperty("流水线ID", required = true) val pipelineId: String, + @ApiModelProperty("版本ID", required = true) + val version: Int, @ApiModelProperty("操作用户", required = true) val operator: String, @ApiModelProperty("操作类型", required = true) val operationLogType: OperationLogType, @ApiModelProperty("操作参数", required = true) val params: String, + @ApiModelProperty("操作时间", required = false) + val operateTime: Long, @ApiModelProperty("操作内容", required = false) - val description: String? + val description: String?, + @ApiModelProperty("版本名称", required = false) + val versionName: String?, + @ApiModelProperty("版本创建时间", required = false) + val versionCreateTime: Long?, + @ApiModelProperty("草稿版本标识", required = false) + val status: VersionStatus? = null, + @ApiModelProperty("来源代码库标识(分支名)", required = false) + val pacRefs: String? = null ) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt index b0570e20d48..9a94cefe39c 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt @@ -247,6 +247,41 @@ class PipelineResVersionDao { return list } + fun listPipelineVersionInList( + dslContext: DSLContext, + projectId: String, + pipelineId: String, + versions: Set + ): List { + val list = mutableListOf() + with(T_PIPELINE_RESOURCE_VERSION) { + val result = dslContext.selectFrom(this) + .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) + .and(VERSION.`in`(versions)) + .fetch() + result.forEach { record -> + list.add( + PipelineVersionSimple( + pipelineId = pipelineId, + creator = record.creator ?: "unknown", + createTime = record.createTime?.timestampmilli() ?: 0, + version = record.version ?: 1, + versionName = record.versionName ?: "init", + referFlag = record.referFlag, + referCount = record.referCount, + pipelineVersion = record.pipelineVersion, + triggerVersion = record.triggerVersion, + settingVersion = record.settingVersion, + status = record.status?.let { VersionStatus.valueOf(it) }, + debugBuildId = record.debugBuildId, + pacRefs = record.refs + ) + ) + } + } + return list + } + fun getVersionCreatorInPage( dslContext: DSLContext, projectId: String, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index 16d042b3eb2..a62e2f35be2 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -43,10 +43,12 @@ import com.tencent.devops.process.audit.service.AuditService import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.engine.service.PipelineVersionFacadeService import com.tencent.devops.process.permission.PipelinePermissionService +import com.tencent.devops.process.pojo.PipelineOperationLog import com.tencent.devops.process.pojo.audit.Audit import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import com.tencent.devops.process.pojo.setting.PipelineSetting import com.tencent.devops.process.service.PipelineInfoFacadeService +import com.tencent.devops.process.service.PipelineOperationLogService import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService import org.springframework.beans.factory.annotation.Autowired @@ -56,7 +58,8 @@ class UserPipelineVersionResourceImpl @Autowired constructor( private val pipelinePermissionService: PipelinePermissionService, private val pipelineInfoFacadeService: PipelineInfoFacadeService, private val auditService: AuditService, - private val pipelineVersionFacadeService: PipelineVersionFacadeService + private val pipelineVersionFacadeService: PipelineVersionFacadeService, + private val pipelineOperationLogService: PipelineOperationLogService ) : UserPipelineVersionResource { override fun savePipeline( @@ -199,6 +202,34 @@ class UserPipelineVersionResourceImpl @Autowired constructor( ) } + override fun getPipelineOperationLogs( + userId: String, + projectId: String, + pipelineId: String + ): Result> { + checkParam(userId, projectId) + val permission = AuthPermission.VIEW + pipelinePermissionService.validPipelinePermission( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + permission = permission, + message = MessageUtil.getMessageByLocale( + CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, + I18nUtil.getLanguage(userId), + arrayOf( + userId, + projectId, + permission.getI18n(I18nUtil.getLanguage(userId)), + pipelineId + ) + ) + ) + return Result( + pipelineOperationLogService.getOperationLogs(userId, projectId, pipelineId) + ) + } + private fun checkParam(userId: String, projectId: String) { if (userId.isBlank()) { throw ParamBlankException("Invalid userId") diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/dao/OperationLogDao.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/dao/PipelineOperationLogDao.kt similarity index 60% rename from src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/dao/OperationLogDao.kt rename to src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/dao/PipelineOperationLogDao.kt index a864df2534e..5d1c8ed975b 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/dao/OperationLogDao.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/dao/PipelineOperationLogDao.kt @@ -27,23 +27,29 @@ package com.tencent.devops.process.dao +import com.tencent.devops.common.api.util.timestampmilli import com.tencent.devops.model.process.tables.TPipelineOperationLog +import com.tencent.devops.model.process.tables.records.TPipelineOperationLogRecord import com.tencent.devops.process.enums.OperationLogType import com.tencent.devops.process.pojo.PipelineOperationLog import org.jooq.DSLContext +import org.jooq.RecordMapper +import org.slf4j.LoggerFactory import org.springframework.stereotype.Repository @Repository @Suppress("LongParameterList") -class OperationLogDao { +class PipelineOperationLogDao { fun add( dslContext: DSLContext, id: Int, projectId: String, pipelineId: String, + version: Int, operator: String, operationLogType: OperationLogType, + params: String, description: String? ) { with(TPipelineOperationLog.T_PIPELINE_OPERATION_LOG) { @@ -52,6 +58,7 @@ class OperationLogDao { ID, PROJECT_ID, PIPELINE_ID, + VERSION, OPERATOR, OPERATION_TYPE, PARAMS, @@ -60,9 +67,10 @@ class OperationLogDao { id, projectId, pipelineId, - operator, + version, operator, operationLogType.name, + params, description ).execute() } @@ -79,22 +87,60 @@ class OperationLogDao { ID, PROJECT_ID, PIPELINE_ID, + VERSION, OPERATOR, OPERATION_TYPE, PARAMS, DESCRIPTION + ).values( + it.id, + it.pipelineId, + it.pipelineId, + it.version, + it.operator, + it.operationLogType.name, + it.params, + it.description ) - .values( - it.id, - it.pipelineId, - it.pipelineId, - it.operator, - it.operationLogType.name, - it.params, - it.description - ) } dslContext.batch(addStep).execute() } } + + fun getList( + dslContext: DSLContext, + projectId: String, + pipelineId: String + ): List { + return with(TPipelineOperationLog.T_PIPELINE_OPERATION_LOG) { + dslContext.selectFrom(this) + .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) + .orderBy(CREATE_TIME.asc()).fetch(mapper) + } + } + + class PipelineOperationLogJooqMapper : RecordMapper { + override fun map(record: TPipelineOperationLogRecord?): PipelineOperationLog? { + return record?.run { + PipelineOperationLog( + id = id, + projectId = projectId, + pipelineId = pipelineId, + version = version, + operator = operator, + operationLogType = OperationLogType.parseType(operationType), + params = params, + description = description, + operateTime = createTime.timestampmilli(), + versionName = null, + versionCreateTime = null + ) + } + } + } + + companion object { + private val mapper = PipelineOperationLogJooqMapper() + private val logger = LoggerFactory.getLogger(PipelineOperationLogDao::class.java) + } } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineListFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineListFacadeService.kt index a650970fb50..d82d4a85386 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineListFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineListFacadeService.kt @@ -35,7 +35,6 @@ import com.tencent.devops.common.api.exception.PermissionForbiddenException import com.tencent.devops.common.api.model.SQLLimit import com.tencent.devops.common.api.model.SQLPage import com.tencent.devops.common.api.pojo.Page -import com.tencent.devops.common.api.util.DateTimeUtil import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.api.util.PageUtil diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt new file mode 100644 index 00000000000..a394ed2e7c8 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt @@ -0,0 +1,72 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.service + +import com.tencent.devops.process.dao.PipelineOperationLogDao +import com.tencent.devops.process.engine.dao.PipelineResVersionDao +import com.tencent.devops.process.pojo.PipelineOperationLog +import com.tencent.devops.process.pojo.setting.PipelineVersionSimple +import org.jooq.DSLContext +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Service + +@Service +class PipelineOperationLogService @Autowired constructor( + private val dslContext: DSLContext, + private val pipelineOperationLogDao: PipelineOperationLogDao, + private val pipelineResVersionDao: PipelineResVersionDao +) { + + fun getOperationLogs( + userId: String, + projectId: String, + pipelineId: String + ): List { + val opList = pipelineOperationLogDao.getList( + dslContext = dslContext, + projectId = projectId, + pipelineId = pipelineId + ) + val versions = mutableSetOf() + opList.forEach { versions.add(it.version) } + val versionMap = mutableMapOf() + pipelineResVersionDao.listPipelineVersionInList( + dslContext = dslContext, + projectId = projectId, + pipelineId = pipelineId, + versions = versions + ).forEach { versionMap[it.version] = it } + return opList.map { + it.copy( + versionName = versionMap[it.version]?.versionName, + versionCreateTime = versionMap[it.version]?.createTime, + status = versionMap[it.version]?.status + ) + } + } +} From b09bcea3613b9bc79c45077c79c001bad7a5d921 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 7 Aug 2023 19:45:47 +0800 Subject: [PATCH 037/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=BB=B4=E6=8A=A4=E8=BF=87=E7=A8=8B=E4=B8=AD=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/user/UserPipelineVersionResource.kt | 20 +++++++- .../pojo/pipeline/DeployPipelineResult.kt | 4 +- .../engine}/dao/PipelineOperationLogDao.kt | 5 +- .../service/PipelineRepositoryService.kt | 49 ++++++++++++++++--- .../service/PipelineOperationLogService.kt | 25 +++++++++- .../api/UserPipelineVersionResourceImpl.kt | 31 ++++++++++++ .../service/PipelineInfoFacadeService.kt | 7 ++- 7 files changed, 125 insertions(+), 16 deletions(-) rename src/backend/ci/core/process/{biz-process/src/main/kotlin/com/tencent/devops/process => biz-base/src/main/kotlin/com/tencent/devops/process/engine}/dao/PipelineOperationLogDao.kt (98%) rename src/backend/ci/core/process/{biz-process => biz-base}/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt (80%) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 5a2b2010e8b..7bbc50611a4 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -33,6 +33,7 @@ import com.tencent.devops.common.api.pojo.Page import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.Model import com.tencent.devops.process.engine.pojo.PipelineResVersion +import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineOperationLog import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import com.tencent.devops.process.pojo.setting.PipelineSetting @@ -57,6 +58,23 @@ import javax.ws.rs.core.MediaType @Suppress("LongParameterList") interface UserPipelineVersionResource { + @ApiOperation("新建流水线编排") + @POST + @Path("/projects/{projectId}/createPipeline") + fun createPipeline( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("是否使用模板配置", required = false) + @QueryParam("useTemplateSettings") + useTemplateSettings: Boolean? = false, + @ApiParam(value = "流水线模型", required = true) + pipeline: Model + ): Result + @ApiOperation("保存流水线编排草稿") @POST @Path("/projects/{projectId}/pipelines/{pipelineId}/saveDraft") @@ -145,7 +163,7 @@ interface UserPipelineVersionResource { @ApiOperation("获取流水线操作日志列表") @GET - @Path("/projects/{projectId}/pipelines/{pipelineId}/log") + @Path("/projects/{projectId}/pipelines/{pipelineId}/operationLog") fun getPipelineOperationLogs( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/DeployPipelineResult.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/DeployPipelineResult.kt index 385c538ba55..b8c006752d8 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/DeployPipelineResult.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/DeployPipelineResult.kt @@ -37,5 +37,7 @@ data class DeployPipelineResult( @ApiModelProperty("流水线名称", required = true) val pipelineName: String, @ApiModelProperty("流水线版本号", required = true) - val version: Int + val version: Int, + @ApiModelProperty("生成版本名称", required = false) + val versionName: String? ) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/dao/PipelineOperationLogDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt similarity index 98% rename from src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/dao/PipelineOperationLogDao.kt rename to src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt index 5d1c8ed975b..749d1cdaf20 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/dao/PipelineOperationLogDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt @@ -25,7 +25,7 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.tencent.devops.process.dao +package com.tencent.devops.process.engine.dao import com.tencent.devops.common.api.util.timestampmilli import com.tencent.devops.model.process.tables.TPipelineOperationLog @@ -43,7 +43,6 @@ class PipelineOperationLogDao { fun add( dslContext: DSLContext, - id: Int, projectId: String, pipelineId: String, version: Int, @@ -55,7 +54,6 @@ class PipelineOperationLogDao { with(TPipelineOperationLog.T_PIPELINE_OPERATION_LOG) { dslContext.insertInto( this, - ID, PROJECT_ID, PIPELINE_ID, VERSION, @@ -64,7 +62,6 @@ class PipelineOperationLogDao { PARAMS, DESCRIPTION ).values( - id, projectId, pipelineId, version, diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index 509cc442747..5263691323f 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -77,6 +77,7 @@ import com.tencent.devops.process.engine.pojo.event.PipelineCreateEvent import com.tencent.devops.process.engine.pojo.event.PipelineDeleteEvent import com.tencent.devops.process.engine.pojo.event.PipelineRestoreEvent import com.tencent.devops.process.engine.pojo.event.PipelineUpdateEvent +import com.tencent.devops.process.enums.OperationLogType import com.tencent.devops.process.plugin.load.ElementBizRegistrar import com.tencent.devops.process.pojo.PipelineCollation import com.tencent.devops.process.pojo.PipelineName @@ -86,6 +87,7 @@ import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion import com.tencent.devops.process.pojo.setting.PipelineModelVersion import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.process.service.PipelineOperationLogService import com.tencent.devops.process.utils.PIPELINE_MATRIX_CON_RUNNING_SIZE_MAX import com.tencent.devops.project.api.service.ServiceAllocIdResource import com.tencent.devops.project.api.service.ServiceProjectResource @@ -127,6 +129,7 @@ class PipelineRepositoryService constructor( private val pipelineViewGroupDao: PipelineViewGroupDao, private val versionConfigure: VersionConfigure, private val pipelineInfoExtService: PipelineInfoExtService, + private val operationLogService: PipelineOperationLogService, private val client: Client, private val objectMapper: ObjectMapper, private val redisOperation: RedisOperation @@ -191,7 +194,7 @@ class PipelineRepositoryService constructor( return if (!create) { val pipelineSetting = savedSetting ?: pipelineSettingDao.getSetting(dslContext, projectId, pipelineId) - update( + val result = update( projectId = projectId, pipelineId = pipelineId, userId = userId, @@ -206,8 +209,19 @@ class PipelineRepositoryService constructor( saveDraft = saveDraft, description = description ) + // TODO 提供新接口 + operationLogService.addOperationLog( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + version = result.version, + operationLogType = OperationLogType.NORMAL_SAVE_OPERATION, + params = result.versionName ?: "init", + description = null + ) + result } else { - create( + val result = create( projectId = projectId, pipelineId = pipelineId, model = model, @@ -222,6 +236,16 @@ class PipelineRepositoryService constructor( saveDraft = saveDraft, description = description ) + operationLogService.addOperationLog( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + version = result.version, + operationLogType = OperationLogType.NORMAL_SAVE_OPERATION, + params = result.versionName ?: "init", + description = null + ) + result } } @@ -513,6 +537,7 @@ class PipelineRepositoryService constructor( val taskCount: Int = model.taskCount() val id = client.get(ServiceAllocIdResource::class).generateSegmentId("PIPELINE_INFO").data val lock = PipelineModelLock(redisOperation, pipelineId) + var versionName: String? = null try { lock.lock() dslContext.transaction { configuration -> @@ -596,6 +621,7 @@ class PipelineRepositoryService constructor( } } // 如果不是草稿保存,最新版本永远是新增逻辑 + versionName = getVersionName(pipelineVersion, triggerVersion, settingVersion) if (saveDraft != true) pipelineResDao.create( dslContext = transactionContext, projectId = projectId, @@ -603,7 +629,7 @@ class PipelineRepositoryService constructor( creator = userId, version = 1, model = model, - versionName = getVersionName(pipelineVersion, triggerVersion, settingVersion), + versionName = versionName ?: "init", pipelineVersion = modelVersion, triggerVersion = triggerVersion, settingVersion = settingVersion @@ -616,7 +642,7 @@ class PipelineRepositoryService constructor( creator = userId, version = 1, model = model, - versionName = getVersionName(modelVersion, triggerVersion, settingVersion), + versionName = versionName ?: "init", pipelineVersion = modelVersion, triggerVersion = triggerVersion, settingVersion = settingVersion, @@ -648,7 +674,7 @@ class PipelineRepositoryService constructor( channelCode = channelCode.name ) ) - return DeployPipelineResult(pipelineId, pipelineName = model.name, version = 1) + return DeployPipelineResult(pipelineId, pipelineName = model.name, version = 1, versionName) } private fun update( @@ -670,6 +696,7 @@ class PipelineRepositoryService constructor( var version = 0 val lock = PipelineModelLock(redisOperation, pipelineId) val watcher = Watcher(id = "updatePipeline#$pipelineId#$saveDraft") + var versionName: String? = null try { lock.lock() dslContext.transaction { configuration -> @@ -733,6 +760,7 @@ class PipelineRepositoryService constructor( if (!originTriggerJson.similar(triggerJson)) triggerVersion++ if (!originPipelineJson.similar(pipelineJson)) pipelineVersion++ } + versionName = getVersionName(pipelineVersion, triggerVersion, settingVersion) watcher.start("updatePipelineResource") if (saveDraft != true) pipelineResDao.create( dslContext = transactionContext, @@ -741,7 +769,7 @@ class PipelineRepositoryService constructor( creator = userId, version = version, model = model, - versionName = getVersionName(pipelineVersion, triggerVersion, settingVersion), + versionName = versionName ?: "init", pipelineVersion = pipelineVersion, triggerVersion = triggerVersion, settingVersion = settingVersion @@ -753,7 +781,7 @@ class PipelineRepositoryService constructor( creator = userId, version = version, model = model, - versionName = getVersionName(pipelineVersion, triggerVersion, settingVersion), + versionName = versionName ?: "init", pipelineVersion = pipelineVersion, triggerVersion = triggerVersion, settingVersion = settingVersion, @@ -839,7 +867,12 @@ class PipelineRepositoryService constructor( channelCode = channelCode.name ) ) - return DeployPipelineResult(pipelineId, pipelineName = model.name, version = version) + return DeployPipelineResult( + pipelineId, + pipelineName = model.name, + version = version, + versionName = versionName + ) } fun getPipelineInfo( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt similarity index 80% rename from src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt rename to src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt index a394ed2e7c8..cbf440b9563 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt @@ -27,8 +27,9 @@ package com.tencent.devops.process.service -import com.tencent.devops.process.dao.PipelineOperationLogDao +import com.tencent.devops.process.engine.dao.PipelineOperationLogDao import com.tencent.devops.process.engine.dao.PipelineResVersionDao +import com.tencent.devops.process.enums.OperationLogType import com.tencent.devops.process.pojo.PipelineOperationLog import com.tencent.devops.process.pojo.setting.PipelineVersionSimple import org.jooq.DSLContext @@ -36,12 +37,34 @@ import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service @Service +@Suppress("LongParameterList") class PipelineOperationLogService @Autowired constructor( private val dslContext: DSLContext, private val pipelineOperationLogDao: PipelineOperationLogDao, private val pipelineResVersionDao: PipelineResVersionDao ) { + fun addOperationLog( + userId: String, + projectId: String, + pipelineId: String, + version: Int, + operationLogType: OperationLogType, + params: String, + description: String? + ) { + pipelineOperationLogDao.add( + dslContext = dslContext, + operator = userId, + projectId = projectId, + pipelineId = pipelineId, + version = version, + operationLogType = operationLogType, + params = params, + description = description + ) + } + fun getOperationLogs( userId: String, projectId: String, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index a62e2f35be2..eff9ac1eb72 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -43,6 +43,7 @@ import com.tencent.devops.process.audit.service.AuditService import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.engine.service.PipelineVersionFacadeService import com.tencent.devops.process.permission.PipelinePermissionService +import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineOperationLog import com.tencent.devops.process.pojo.audit.Audit import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage @@ -62,6 +63,36 @@ class UserPipelineVersionResourceImpl @Autowired constructor( private val pipelineOperationLogService: PipelineOperationLogService ) : UserPipelineVersionResource { + override fun createPipeline( + userId: String, + projectId: String, + useTemplateSettings: Boolean?, + pipeline: Model + ): Result { + checkParam(userId, projectId) + val pipelineId = PipelineId( + id = pipelineInfoFacadeService.createPipeline( + userId = userId, + projectId = projectId, + model = pipeline, + channelCode = ChannelCode.BS, + useTemplateSettings = useTemplateSettings + ) + ) + auditService.createAudit( + Audit( + resourceType = AuthResourceType.PIPELINE_DEFAULT.value, + resourceId = pipelineId.id, + resourceName = pipeline.name, + userId = userId, + action = "create", + actionContent = "Create", + projectId = projectId + ) + ) + return Result(pipelineId) + } + override fun savePipeline( userId: String, projectId: String, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index 8a5dcf9847c..fbf6dfc6a8c 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -517,7 +517,12 @@ class PipelineInfoFacadeService @Autowired constructor( pipelineId = pipelineId, pipelineName = model.name ) - return DeployPipelineResult(pipelineId, pipelineName = model.name, version = model.latestVersion) + return DeployPipelineResult( + pipelineId = pipelineId, + pipelineName = model.name, + version = model.latestVersion, + versionName = null + ) } finally { watcher.stop() LogUtils.printCostTimeWE(watcher) From f4f8afe87f8d6c375d8b84a490b7df60362e599a Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 7 Aug 2023 20:45:00 +0800 Subject: [PATCH 038/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=BB=B4=E6=8A=A4=E8=BF=87=E7=A8=8B=E4=B8=AD=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97=20#8197?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 支持国际化 --- .../api/user/UserPipelineVersionResource.kt | 4 +- .../devops/process/enums/OperationLogType.kt | 11 +++- .../process/pojo/PipelineOperationDetail.kt | 65 +++++++++++++++++++ .../process/pojo/PipelineOperationLog.kt | 11 +--- .../engine/dao/PipelineOperationLogDao.kt | 4 +- .../service/PipelineRepositoryService.kt | 12 +++- .../service/PipelineOperationLogService.kt | 27 ++++++-- .../api/UserPipelineVersionResourceImpl.kt | 4 +- 8 files changed, 111 insertions(+), 27 deletions(-) create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineOperationDetail.kt diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 7bbc50611a4..ab481289b32 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -34,7 +34,7 @@ import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.Model import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.pojo.PipelineId -import com.tencent.devops.process.pojo.PipelineOperationLog +import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import com.tencent.devops.process.pojo.setting.PipelineSetting import io.swagger.annotations.Api @@ -174,5 +174,5 @@ interface UserPipelineVersionResource { @ApiParam("流水线ID", required = true) @PathParam("pipelineId") pipelineId: String - ): Result> + ): Result> } diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/enums/OperationLogType.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/enums/OperationLogType.kt index 379a9532c8e..25baea9eb58 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/enums/OperationLogType.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/enums/OperationLogType.kt @@ -27,6 +27,8 @@ package com.tencent.devops.process.enums +import com.tencent.devops.common.api.util.MessageUtil + enum class OperationLogType(val description: String) { CREATE_PIPELINE_AND_DRAFT("创建流水线首次保存草稿:「创建了草稿」"), CREATE_DRAFT_VERSION("编辑流水线生成草稿:「从 P1.T2.0 创建了草稿」"), @@ -34,12 +36,19 @@ enum class OperationLogType(val description: String) { CREATE_BRANCH_VERSION("新增分支版本:「新增版本 P1.T2.0」"), UPDATE_BRANCH_VERSION("修改分支版本:「修改版本 P1.T2.0」"), RELEASE_MASTER_VERSION("正式版本完成时:「发布版本 P1.T2.0」"), - UNABLE_PIPELINE("禁用流水线时:「禁用了流水线」"), + DISABLE_PIPELINE("禁用流水线时:「禁用了流水线」"), ADD_PIPELINE_OWNER("添加流水线成员时:「添加 xxx,yyy 为执行者」"), ADD_PIPELINE_TO_GROUP("将流水线添加到流水线组时:「添加到流水线组 a」"), MOVE_PIPELINE_OUT_OF_GROUP("将流水线移出流水线组时:「从流水线组 a 中移出」"), NORMAL_SAVE_OPERATION("普通保存操作"); + fun getI18n(language: String): String { + return MessageUtil.getMessageByLocale( + messageCode = "operationLogType.${this.name}", + language = language + ) + } + companion object { fun parseType(type: String?): OperationLogType { if (type.isNullOrBlank()) return NORMAL_SAVE_OPERATION diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineOperationDetail.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineOperationDetail.kt new file mode 100644 index 00000000000..a059b9aceae --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineOperationDetail.kt @@ -0,0 +1,65 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.pojo + +import com.tencent.devops.common.pipeline.enums.VersionStatus +import com.tencent.devops.process.enums.OperationLogType +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty + +@ApiModel("流水线操作日志") +data class PipelineOperationDetail( + @ApiModelProperty("唯一标识ID", required = true) + val id: Int, + @ApiModelProperty("项目ID", required = true) + val projectId: String, + @ApiModelProperty("流水线ID", required = true) + val pipelineId: String, + @ApiModelProperty("版本ID", required = true) + val version: Int, + @ApiModelProperty("操作用户", required = true) + val operator: String, + @ApiModelProperty("操作类型", required = true) + val operationLogType: OperationLogType, + @ApiModelProperty("操作类型文字(国际化后)", required = true) + val operationLogStr: String, + @ApiModelProperty("操作参数", required = true) + val params: String, + @ApiModelProperty("操作时间", required = false) + val operateTime: Long, + @ApiModelProperty("操作内容", required = false) + val description: String?, + @ApiModelProperty("版本名称", required = false) + val versionName: String?, + @ApiModelProperty("版本创建时间", required = false) + val versionCreateTime: Long?, + @ApiModelProperty("草稿版本标识", required = false) + val status: VersionStatus? = null, + @ApiModelProperty("来源代码库标识(分支名)", required = false) + val pacRefs: String? = null +) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineOperationLog.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineOperationLog.kt index 59b940730fb..c3a52cceb9a 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineOperationLog.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineOperationLog.kt @@ -27,7 +27,6 @@ package com.tencent.devops.process.pojo -import com.tencent.devops.common.pipeline.enums.VersionStatus import com.tencent.devops.process.enums.OperationLogType import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -51,13 +50,5 @@ data class PipelineOperationLog( @ApiModelProperty("操作时间", required = false) val operateTime: Long, @ApiModelProperty("操作内容", required = false) - val description: String?, - @ApiModelProperty("版本名称", required = false) - val versionName: String?, - @ApiModelProperty("版本创建时间", required = false) - val versionCreateTime: Long?, - @ApiModelProperty("草稿版本标识", required = false) - val status: VersionStatus? = null, - @ApiModelProperty("来源代码库标识(分支名)", required = false) - val pacRefs: String? = null + val description: String? ) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt index 749d1cdaf20..5b83927a25c 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt @@ -128,9 +128,7 @@ class PipelineOperationLogDao { operationLogType = OperationLogType.parseType(operationType), params = params, description = description, - operateTime = createTime.timestampmilli(), - versionName = null, - versionCreateTime = null + operateTime = createTime.timestampmilli() ) } } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index 5263691323f..f50240f8800 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -215,7 +215,11 @@ class PipelineRepositoryService constructor( projectId = projectId, pipelineId = pipelineId, version = result.version, - operationLogType = OperationLogType.NORMAL_SAVE_OPERATION, + operationLogType = if (saveDraft == true) { + OperationLogType.UPDATE_DRAFT_VERSION + } else { + OperationLogType.NORMAL_SAVE_OPERATION + }, params = result.versionName ?: "init", description = null ) @@ -241,7 +245,11 @@ class PipelineRepositoryService constructor( projectId = projectId, pipelineId = pipelineId, version = result.version, - operationLogType = OperationLogType.NORMAL_SAVE_OPERATION, + operationLogType = if (saveDraft == true) { + OperationLogType.CREATE_PIPELINE_AND_DRAFT + } else { + OperationLogType.NORMAL_SAVE_OPERATION + }, params = result.versionName ?: "init", description = null ) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt index cbf440b9563..8924db9f8a4 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt @@ -27,10 +27,11 @@ package com.tencent.devops.process.service +import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.engine.dao.PipelineOperationLogDao import com.tencent.devops.process.engine.dao.PipelineResVersionDao import com.tencent.devops.process.enums.OperationLogType -import com.tencent.devops.process.pojo.PipelineOperationLog +import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.setting.PipelineVersionSimple import org.jooq.DSLContext import org.springframework.beans.factory.annotation.Autowired @@ -69,7 +70,7 @@ class PipelineOperationLogService @Autowired constructor( userId: String, projectId: String, pipelineId: String - ): List { + ): List { val opList = pipelineOperationLogDao.getList( dslContext = dslContext, projectId = projectId, @@ -85,11 +86,23 @@ class PipelineOperationLogService @Autowired constructor( versions = versions ).forEach { versionMap[it.version] = it } return opList.map { - it.copy( - versionName = versionMap[it.version]?.versionName, - versionCreateTime = versionMap[it.version]?.createTime, - status = versionMap[it.version]?.status - ) + with(it) { + PipelineOperationDetail( + id = id, + projectId = projectId, + pipelineId = pipelineId, + version = version, + operator = operator, + operationLogType = operationLogType, + operationLogStr = operationLogType.getI18n(I18nUtil.getRequestUserLanguage()), + params = params, + description = description, + operateTime = operateTime, + versionName = versionMap[it.version]?.versionName, + versionCreateTime = versionMap[it.version]?.createTime, + status = versionMap[it.version]?.status + ) + } } } } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index eff9ac1eb72..6ea877b1116 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -44,7 +44,7 @@ import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.engine.service.PipelineVersionFacadeService import com.tencent.devops.process.permission.PipelinePermissionService import com.tencent.devops.process.pojo.PipelineId -import com.tencent.devops.process.pojo.PipelineOperationLog +import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.audit.Audit import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import com.tencent.devops.process.pojo.setting.PipelineSetting @@ -237,7 +237,7 @@ class UserPipelineVersionResourceImpl @Autowired constructor( userId: String, projectId: String, pipelineId: String - ): Result> { + ): Result> { checkParam(userId, projectId) val permission = AuthPermission.VIEW pipelinePermissionService.validPipelinePermission( From bfcba99773cb39ef9da3647fcf939cb3f9b0540e Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 7 Aug 2023 20:46:14 +0800 Subject: [PATCH 039/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=BB=B4=E6=8A=A4=E8=BF=87=E7=A8=8B=E4=B8=AD=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97=20#8197=20?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=9B=BD=E9=99=85=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- support-files/i18n/process/message_en_US.properties | 11 +++++++++++ support-files/i18n/process/message_zh_CN.properties | 11 +++++++++++ 2 files changed, 22 insertions(+) diff --git a/support-files/i18n/process/message_en_US.properties b/support-files/i18n/process/message_en_US.properties index 95e46f05f6e..ad643ec77f7 100644 --- a/support-files/i18n/process/message_en_US.properties +++ b/support-files/i18n/process/message_en_US.properties @@ -355,3 +355,14 @@ bkQualityOut=Quality out bkBuildFinishedAndDenyPause=Build Finished And Deny Pause commonShutdownSuccessContent=【${%s}】- 【${%s}】#${%s} Execution succeed,consume time${%s}, trigger user: ${%s}。 commonShutdownFailureContent=【${%s}】- 【${%s}】#${%s} Execution failed,consume time${%s}, trigger user: ${%s}。 +operationLogType.NORMAL_SAVE_OPERATION=Normal save operation +operationLogType.CREATE_PIPELINE_AND_DRAFT=Created draft +operationLogType.CREATE_DRAFT_VERSION=Created draft based on +operationLogType.UPDATE_DRAFT_VERSION=Updated draft +operationLogType.CREATE_BRANCH_VERSION=Add branch version +operationLogType.UPDATE_BRANCH_VERSION=Update branch version +operationLogType.RELEASE_MASTER_VERSION=Released version +operationLogType.DISABLE_PIPELINE=Disable pipeline +operationLogType.ADD_PIPELINE_OWNER=Add pipeline executors +operationLogType.ADD_PIPELINE_TO_GROUP=Add to pipeline group +operationLogType.MOVE_PIPELINE_OUT_OF_GROUP=Move out of pipeline group diff --git a/support-files/i18n/process/message_zh_CN.properties b/support-files/i18n/process/message_zh_CN.properties index edfeace52c8..277835d75eb 100644 --- a/support-files/i18n/process/message_zh_CN.properties +++ b/support-files/i18n/process/message_zh_CN.properties @@ -355,3 +355,14 @@ bkQualityOut=质量红线(准出) bkBuildFinishedAndDenyPause=构建已结束,禁止暂停请求 commonShutdownSuccessContent=【${%s}】- 【${%s}】#${%s} 执行成功,耗时${%s}, 触发人: ${%s}。 commonShutdownFailureContent=【${%s}】- 【${%s}】#${%s} 执行失败,耗时${%s}, 触发人: ${%s}。 +operationLogType.NORMAL_SAVE_OPERATION=普通保存操作 +operationLogType.CREATE_PIPELINE_AND_DRAFT=创建了草稿 +operationLogType.CREATE_DRAFT_VERSION=创建了草稿 +operationLogType.UPDATE_DRAFT_VERSION=新草稿基于 +operationLogType.CREATE_BRANCH_VERSION=修改了草稿 +operationLogType.UPDATE_BRANCH_VERSION=修改版本 +operationLogType.RELEASE_MASTER_VERSION=发布版本 +operationLogType.DISABLE_PIPELINE=禁用了流水线 +operationLogType.ADD_PIPELINE_OWNER=添加执行者 +operationLogType.ADD_PIPELINE_TO_GROUP=添加到流水线组 +operationLogType.MOVE_PIPELINE_OUT_OF_GROUP=移出流水线组 From 7e5188a4bff0505c42ccb79a18bcb09b6670e4c5 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 8 Aug 2023 11:11:42 +0800 Subject: [PATCH 040/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=BB=B4=E6=8A=A4=E8=BF=87=E7=A8=8B=E4=B8=AD=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97=20#8197=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=86=99=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/engine/service/PipelineRepositoryService.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index f50240f8800..c597e6e0243 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -209,7 +209,6 @@ class PipelineRepositoryService constructor( saveDraft = saveDraft, description = description ) - // TODO 提供新接口 operationLogService.addOperationLog( userId = userId, projectId = projectId, From 3953cbed4a020b1f2fb63241e7143ae2f41d70e4 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 10 Aug 2023 14:56:00 +0800 Subject: [PATCH 041/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=BB=B4=E6=8A=A4=E8=BF=87=E7=A8=8B=E4=B8=AD=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97=20#8197=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=86=99=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/ServicePipelineVersionResource.kt | 180 ++++++++++++ .../api/ServicePipelineVersionResourceImpl.kt | 272 ++++++++++++++++++ 2 files changed, 452 insertions(+) create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt new file mode 100644 index 00000000000..fe99d198859 --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt @@ -0,0 +1,180 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.api.user + +import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID +import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE +import com.tencent.devops.common.api.pojo.Page +import com.tencent.devops.common.api.pojo.Result +import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.process.engine.pojo.PipelineResVersion +import com.tencent.devops.process.pojo.PipelineId +import com.tencent.devops.process.pojo.PipelineOperationDetail +import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage +import com.tencent.devops.process.pojo.setting.PipelineSetting +import io.swagger.annotations.Api +import io.swagger.annotations.ApiOperation +import io.swagger.annotations.ApiParam +import javax.validation.Valid +import javax.ws.rs.Consumes +import javax.ws.rs.GET +import javax.ws.rs.HeaderParam +import javax.ws.rs.POST +import javax.ws.rs.Path +import javax.ws.rs.PathParam +import javax.ws.rs.Produces +import javax.ws.rs.QueryParam +import javax.ws.rs.core.MediaType + +@Api(tags = ["USER_PIPELINE_VERSION"], description = "用户-流水线资源") +@Path("/user/version") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Suppress("LongParameterList") +interface UserPipelineVersionResource { + + + + @ApiOperation("新建流水线编排") + @POST + @Path("/projects/{projectId}/createPipeline") + fun createPipeline( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("是否使用模板配置", required = false) + @QueryParam("useTemplateSettings") + useTemplateSettings: Boolean? = false, + @ApiParam(value = "流水线模型", required = true) + pipeline: Model + ): Result + + @ApiOperation("保存流水线编排草稿") + @POST + @Path("/projects/{projectId}/pipelines/{pipelineId}/saveDraft") + fun savePipeline( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String, + @ApiParam(value = "流水线模型与设置", required = true) + @Valid + model: Model, + @ApiParam("变更说明", required = false) + @QueryParam("description") + description: String? = null + ): Result + + @ApiOperation("保存流水线设置") + @POST + @Path("/projects/{projectId}/pipelines/{pipelineId}/saveSetting") + fun saveSetting( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String, + @ApiParam(value = "流水线设置", required = true) + setting: PipelineSetting + ): Result + + @ApiOperation("获取流水线编创建人列表(分页)") + @GET + @Path("/projects/{projectId}/pipelines/{pipelineId}/creatorList") + fun creatorList( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String, + @ApiParam("第几页", required = false, defaultValue = "1") + @QueryParam("page") + page: Int?, + @ApiParam("每页多少条", required = false, defaultValue = "20") + @QueryParam("pageSize") + pageSize: Int? + ): Result> + + @ApiOperation("流水线编排版本列表(搜索、分页)") + @GET + @Path("/projects/{projectId}/pipelines/{pipelineId}/versions") + fun versionList( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String, + @ApiParam("过滤创建人", required = false) + @QueryParam("creator") + creator: String? = null, + @ApiParam("模糊查询变更说明", required = false) + @QueryParam("description") + description: String? = null, + @ApiParam("第几页", required = false, defaultValue = "1") + @QueryParam("page") + page: Int?, + @ApiParam("每页多少条", required = false, defaultValue = "20") + @QueryParam("pageSize") + pageSize: Int? + ): Result> + + @ApiOperation("获取流水线操作日志列表") + @GET + @Path("/projects/{projectId}/pipelines/{pipelineId}/operationLog") + fun getPipelineOperationLogs( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String + ): Result> +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt new file mode 100644 index 00000000000..6ea877b1116 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt @@ -0,0 +1,272 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.api + +import com.tencent.devops.common.api.constant.CommonMessageCode +import com.tencent.devops.common.api.exception.ParamBlankException +import com.tencent.devops.common.api.pojo.Page +import com.tencent.devops.common.api.pojo.Result +import com.tencent.devops.common.api.util.MessageUtil +import com.tencent.devops.common.auth.api.AuthPermission +import com.tencent.devops.common.auth.api.AuthResourceType +import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.common.pipeline.enums.ChannelCode +import com.tencent.devops.common.web.RestResource +import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.process.api.user.UserPipelineVersionResource +import com.tencent.devops.process.audit.service.AuditService +import com.tencent.devops.process.engine.pojo.PipelineResVersion +import com.tencent.devops.process.engine.service.PipelineVersionFacadeService +import com.tencent.devops.process.permission.PipelinePermissionService +import com.tencent.devops.process.pojo.PipelineId +import com.tencent.devops.process.pojo.PipelineOperationDetail +import com.tencent.devops.process.pojo.audit.Audit +import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage +import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.process.service.PipelineInfoFacadeService +import com.tencent.devops.process.service.PipelineOperationLogService +import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService +import org.springframework.beans.factory.annotation.Autowired + +@RestResource +class UserPipelineVersionResourceImpl @Autowired constructor( + private val pipelineSettingFacadeService: PipelineSettingFacadeService, + private val pipelinePermissionService: PipelinePermissionService, + private val pipelineInfoFacadeService: PipelineInfoFacadeService, + private val auditService: AuditService, + private val pipelineVersionFacadeService: PipelineVersionFacadeService, + private val pipelineOperationLogService: PipelineOperationLogService +) : UserPipelineVersionResource { + + override fun createPipeline( + userId: String, + projectId: String, + useTemplateSettings: Boolean?, + pipeline: Model + ): Result { + checkParam(userId, projectId) + val pipelineId = PipelineId( + id = pipelineInfoFacadeService.createPipeline( + userId = userId, + projectId = projectId, + model = pipeline, + channelCode = ChannelCode.BS, + useTemplateSettings = useTemplateSettings + ) + ) + auditService.createAudit( + Audit( + resourceType = AuthResourceType.PIPELINE_DEFAULT.value, + resourceId = pipelineId.id, + resourceName = pipeline.name, + userId = userId, + action = "create", + actionContent = "Create", + projectId = projectId + ) + ) + return Result(pipelineId) + } + + override fun savePipeline( + userId: String, + projectId: String, + pipelineId: String, + model: Model, + description: String? + ): Result { + checkParam(userId, projectId) + val pipelineResult = pipelineInfoFacadeService.editPipeline( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + model = model, + channelCode = ChannelCode.BS, + checkPermission = true, + checkTemplate = true, + saveDraft = true, + description = description + ) + auditService.createAudit( + Audit( + resourceType = AuthResourceType.PIPELINE_DEFAULT.value, + resourceId = pipelineId, + resourceName = model.name, + userId = userId, + action = "edit", + actionContent = "Save Ver.${pipelineResult.version}", + projectId = projectId + ) + ) + return Result(true) + } + + override fun saveSetting( + userId: String, + projectId: String, + pipelineId: String, + setting: PipelineSetting + ): Result { + checkParam(userId, projectId) + val savedSetting = pipelineSettingFacadeService.saveSetting( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + setting = setting, + checkPermission = true + ) + pipelineInfoFacadeService.updatePipelineSettingVersion( + userId = userId, + projectId = setting.projectId, + pipelineId = setting.pipelineId, + settingVersion = savedSetting.version + ) + auditService.createAudit( + Audit( + resourceType = AuthResourceType.PIPELINE_DEFAULT.value, + resourceId = pipelineId, + resourceName = setting.pipelineName, + userId = userId, + action = "edit", + actionContent = "Update Setting", + projectId = projectId + ) + ) + return Result(true) + } + + override fun creatorList( + userId: String, + projectId: String, + pipelineId: String, + page: Int?, + pageSize: Int? + ): Result> { + checkParam(userId, projectId) + val permission = AuthPermission.VIEW + pipelinePermissionService.validPipelinePermission( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + permission = permission, + message = MessageUtil.getMessageByLocale( + CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, + I18nUtil.getLanguage(userId), + arrayOf( + userId, + projectId, + permission.getI18n(I18nUtil.getLanguage(userId)), + pipelineId + ) + ) + ) + val result = pipelineVersionFacadeService.getVersionCreatorInPage( + projectId = projectId, + pipelineId = pipelineId, + page = page, + pageSize = pageSize + ) + return Result(result) + } + + override fun versionList( + userId: String, + projectId: String, + pipelineId: String, + creator: String?, + description: String?, + page: Int?, + pageSize: Int? + ): Result> { + checkParam(userId, projectId) + val permission = AuthPermission.VIEW + pipelinePermissionService.validPipelinePermission( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + permission = permission, + message = MessageUtil.getMessageByLocale( + CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, + I18nUtil.getLanguage(userId), + arrayOf( + userId, + projectId, + permission.getI18n(I18nUtil.getLanguage(userId)), + pipelineId + ) + ) + ) + return Result( + pipelineVersionFacadeService.listPipelineVersion( + projectId = projectId, + pipelineId = pipelineId, + creator = creator?.takeIf { it.isNotBlank() }, + description = description?.takeIf { it.isNotBlank() }, + page = page, + pageSize = pageSize + ) + ) + } + + override fun getPipelineOperationLogs( + userId: String, + projectId: String, + pipelineId: String + ): Result> { + checkParam(userId, projectId) + val permission = AuthPermission.VIEW + pipelinePermissionService.validPipelinePermission( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + permission = permission, + message = MessageUtil.getMessageByLocale( + CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, + I18nUtil.getLanguage(userId), + arrayOf( + userId, + projectId, + permission.getI18n(I18nUtil.getLanguage(userId)), + pipelineId + ) + ) + ) + return Result( + pipelineOperationLogService.getOperationLogs(userId, projectId, pipelineId) + ) + } + + private fun checkParam(userId: String, projectId: String) { + if (userId.isBlank()) { + throw ParamBlankException("Invalid userId") + } + if (projectId.isBlank()) { + throw ParamBlankException("Invalid projectId") + } + } +} From a37f2d67076d15a80dcc32f1c710beb91797b827 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 10 Aug 2023 14:56:12 +0800 Subject: [PATCH 042/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=BB=B4=E6=8A=A4=E8=BF=87=E7=A8=8B=E4=B8=AD=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97=20#8197=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=86=99=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/ServicePipelineVersionResource.kt | 53 +++++++++---------- .../api/user/UserPipelineVersionResource.kt | 6 ++- .../api/ServicePipelineVersionResourceImpl.kt | 51 +++++------------- .../api/UserPipelineVersionResourceImpl.kt | 4 +- 4 files changed, 45 insertions(+), 69 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt index fe99d198859..b0440fdd512 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt @@ -25,13 +25,14 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.tencent.devops.process.api.user +package com.tencent.devops.process.api.service import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE import com.tencent.devops.common.api.pojo.Page import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.common.pipeline.enums.ChannelCode import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineOperationDetail @@ -51,31 +52,12 @@ import javax.ws.rs.Produces import javax.ws.rs.QueryParam import javax.ws.rs.core.MediaType -@Api(tags = ["USER_PIPELINE_VERSION"], description = "用户-流水线资源") -@Path("/user/version") +@Api(tags = ["SERVICE_PIPELINE_VERSION"], description = "服务-流水线版本管理") +@Path("/service/version") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @Suppress("LongParameterList") -interface UserPipelineVersionResource { - - - - @ApiOperation("新建流水线编排") - @POST - @Path("/projects/{projectId}/createPipeline") - fun createPipeline( - @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) - @HeaderParam(AUTH_HEADER_USER_ID) - userId: String, - @ApiParam("项目ID", required = true) - @PathParam("projectId") - projectId: String, - @ApiParam("是否使用模板配置", required = false) - @QueryParam("useTemplateSettings") - useTemplateSettings: Boolean? = false, - @ApiParam(value = "流水线模型", required = true) - pipeline: Model - ): Result +interface ServicePipelineVersionResource { @ApiOperation("保存流水线编排草稿") @POST @@ -95,7 +77,10 @@ interface UserPipelineVersionResource { model: Model, @ApiParam("变更说明", required = false) @QueryParam("description") - description: String? = null + description: String? = null, + @ApiParam("渠道号,默认为BS", required = false) + @QueryParam("channelCode") + channelCode: ChannelCode ): Result @ApiOperation("保存流水线设置") @@ -112,7 +97,10 @@ interface UserPipelineVersionResource { @PathParam("pipelineId") pipelineId: String, @ApiParam(value = "流水线设置", required = true) - setting: PipelineSetting + setting: PipelineSetting, + @ApiParam("渠道号,默认为BS", required = false) + @QueryParam("channelCode") + channelCode: ChannelCode ): Result @ApiOperation("获取流水线编创建人列表(分页)") @@ -133,7 +121,10 @@ interface UserPipelineVersionResource { page: Int?, @ApiParam("每页多少条", required = false, defaultValue = "20") @QueryParam("pageSize") - pageSize: Int? + pageSize: Int?, + @ApiParam("渠道号,默认为BS", required = false) + @QueryParam("channelCode") + channelCode: ChannelCode ): Result> @ApiOperation("流水线编排版本列表(搜索、分页)") @@ -160,7 +151,10 @@ interface UserPipelineVersionResource { page: Int?, @ApiParam("每页多少条", required = false, defaultValue = "20") @QueryParam("pageSize") - pageSize: Int? + pageSize: Int?, + @ApiParam("渠道号,默认为BS", required = false) + @QueryParam("channelCode") + channelCode: ChannelCode ): Result> @ApiOperation("获取流水线操作日志列表") @@ -175,6 +169,9 @@ interface UserPipelineVersionResource { projectId: String, @ApiParam("流水线ID", required = true) @PathParam("pipelineId") - pipelineId: String + pipelineId: String, + @ApiParam("渠道号,默认为BS", required = false) + @QueryParam("channelCode") + channelCode: ChannelCode ): Result> } diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index ab481289b32..43a68bd4d47 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -51,7 +51,7 @@ import javax.ws.rs.Produces import javax.ws.rs.QueryParam import javax.ws.rs.core.MediaType -@Api(tags = ["USER_PIPELINE_VERSION"], description = "用户-流水线资源") +@Api(tags = ["USER_PIPELINE_VERSION"], description = "用户-流水线版本管理") @Path("/user/version") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) @@ -72,7 +72,9 @@ interface UserPipelineVersionResource { @QueryParam("useTemplateSettings") useTemplateSettings: Boolean? = false, @ApiParam(value = "流水线模型", required = true) - pipeline: Model + pipeline: Model, + @ApiParam(value = "流水线模型", required = false) + yaml: String? ): Result @ApiOperation("保存流水线编排草稿") diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt index 6ea877b1116..a11a469e1eb 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt @@ -38,7 +38,7 @@ import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.enums.ChannelCode import com.tencent.devops.common.web.RestResource import com.tencent.devops.common.web.utils.I18nUtil -import com.tencent.devops.process.api.user.UserPipelineVersionResource +import com.tencent.devops.process.api.service.ServicePipelineVersionResource import com.tencent.devops.process.audit.service.AuditService import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.engine.service.PipelineVersionFacadeService @@ -54,51 +54,22 @@ import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService import org.springframework.beans.factory.annotation.Autowired @RestResource -class UserPipelineVersionResourceImpl @Autowired constructor( +class ServicePipelineVersionResourceImpl @Autowired constructor( private val pipelineSettingFacadeService: PipelineSettingFacadeService, private val pipelinePermissionService: PipelinePermissionService, private val pipelineInfoFacadeService: PipelineInfoFacadeService, private val auditService: AuditService, private val pipelineVersionFacadeService: PipelineVersionFacadeService, private val pipelineOperationLogService: PipelineOperationLogService -) : UserPipelineVersionResource { - - override fun createPipeline( - userId: String, - projectId: String, - useTemplateSettings: Boolean?, - pipeline: Model - ): Result { - checkParam(userId, projectId) - val pipelineId = PipelineId( - id = pipelineInfoFacadeService.createPipeline( - userId = userId, - projectId = projectId, - model = pipeline, - channelCode = ChannelCode.BS, - useTemplateSettings = useTemplateSettings - ) - ) - auditService.createAudit( - Audit( - resourceType = AuthResourceType.PIPELINE_DEFAULT.value, - resourceId = pipelineId.id, - resourceName = pipeline.name, - userId = userId, - action = "create", - actionContent = "Create", - projectId = projectId - ) - ) - return Result(pipelineId) - } +) : ServicePipelineVersionResource { override fun savePipeline( userId: String, projectId: String, pipelineId: String, model: Model, - description: String? + description: String?, + channelCode: ChannelCode ): Result { checkParam(userId, projectId) val pipelineResult = pipelineInfoFacadeService.editPipeline( @@ -130,7 +101,8 @@ class UserPipelineVersionResourceImpl @Autowired constructor( userId: String, projectId: String, pipelineId: String, - setting: PipelineSetting + setting: PipelineSetting, + channelCode: ChannelCode ): Result { checkParam(userId, projectId) val savedSetting = pipelineSettingFacadeService.saveSetting( @@ -165,7 +137,8 @@ class UserPipelineVersionResourceImpl @Autowired constructor( projectId: String, pipelineId: String, page: Int?, - pageSize: Int? + pageSize: Int?, + channelCode: ChannelCode ): Result> { checkParam(userId, projectId) val permission = AuthPermission.VIEW @@ -201,7 +174,8 @@ class UserPipelineVersionResourceImpl @Autowired constructor( creator: String?, description: String?, page: Int?, - pageSize: Int? + pageSize: Int?, + channelCode: ChannelCode ): Result> { checkParam(userId, projectId) val permission = AuthPermission.VIEW @@ -236,7 +210,8 @@ class UserPipelineVersionResourceImpl @Autowired constructor( override fun getPipelineOperationLogs( userId: String, projectId: String, - pipelineId: String + pipelineId: String, + channelCode: ChannelCode ): Result> { checkParam(userId, projectId) val permission = AuthPermission.VIEW diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index 6ea877b1116..d4bde18be1e 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -67,9 +67,11 @@ class UserPipelineVersionResourceImpl @Autowired constructor( userId: String, projectId: String, useTemplateSettings: Boolean?, - pipeline: Model + pipeline: Model, + yaml: String? ): Result { checkParam(userId, projectId) + // 如果穿了yaml val pipelineId = PipelineId( id = pipelineInfoFacadeService.createPipeline( userId = userId, From a9ba340fadd4029492170a070804ef96d86cee26 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 10 Aug 2023 15:54:50 +0800 Subject: [PATCH 043/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=BB=B4=E6=8A=A4=E8=BF=87=E7=A8=8B=E4=B8=AD=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E6=93=8D=E4=BD=9C=E6=97=A5=E5=BF=97=20#8197=20?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=88=86=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/ServicePipelineVersionResource.kt | 8 ++++- .../api/user/UserPipelineVersionResource.kt | 10 ++++-- .../engine/dao/PipelineOperationLogDao.kt | 20 +++++++++-- .../service/PipelineOperationLogService.kt | 34 ++++++++++++++++--- .../api/ServicePipelineVersionResourceImpl.kt | 13 +++++-- .../api/UserPipelineVersionResourceImpl.kt | 24 ++++++++----- 6 files changed, 88 insertions(+), 21 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt index b0440fdd512..9422091ab11 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt @@ -170,8 +170,14 @@ interface ServicePipelineVersionResource { @ApiParam("流水线ID", required = true) @PathParam("pipelineId") pipelineId: String, + @ApiParam("第几页", required = false, defaultValue = "1") + @QueryParam("page") + page: Int?, + @ApiParam("每页多少条", required = false, defaultValue = "20") + @QueryParam("pageSize") + pageSize: Int?, @ApiParam("渠道号,默认为BS", required = false) @QueryParam("channelCode") channelCode: ChannelCode - ): Result> + ): Result> } diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 43a68bd4d47..a0e177f758a 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -175,6 +175,12 @@ interface UserPipelineVersionResource { projectId: String, @ApiParam("流水线ID", required = true) @PathParam("pipelineId") - pipelineId: String - ): Result> + pipelineId: String, + @ApiParam("第几页", required = false, defaultValue = "1") + @QueryParam("page") + page: Int?, + @ApiParam("每页多少条", required = false, defaultValue = "20") + @QueryParam("pageSize") + pageSize: Int? + ): Result> } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt index 5b83927a25c..41ee25cea15 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt @@ -104,15 +104,31 @@ class PipelineOperationLogDao { } } - fun getList( + fun getCountByPipeline( dslContext: DSLContext, projectId: String, pipelineId: String + ): Int { + return with(TPipelineOperationLog.T_PIPELINE_OPERATION_LOG) { + dslContext.selectCount().from(this) + .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) + .fetchOne(0, Int::class.java)!! + } + } + + fun getListByPipeline( + dslContext: DSLContext, + projectId: String, + pipelineId: String, + offset: Int, + limit: Int ): List { return with(TPipelineOperationLog.T_PIPELINE_OPERATION_LOG) { dslContext.selectFrom(this) .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) - .orderBy(CREATE_TIME.asc()).fetch(mapper) + .orderBy(CREATE_TIME.asc()) + .limit(limit).offset(offset) + .fetch(mapper) } } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt index 8924db9f8a4..12a3db5375c 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt @@ -27,11 +27,14 @@ package com.tencent.devops.process.service +import com.tencent.devops.common.api.model.SQLLimit +import com.tencent.devops.common.api.util.PageUtil import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.engine.dao.PipelineOperationLogDao import com.tencent.devops.process.engine.dao.PipelineResVersionDao import com.tencent.devops.process.enums.OperationLogType import com.tencent.devops.process.pojo.PipelineOperationDetail +import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import com.tencent.devops.process.pojo.setting.PipelineVersionSimple import org.jooq.DSLContext import org.springframework.beans.factory.annotation.Autowired @@ -66,16 +69,31 @@ class PipelineOperationLogService @Autowired constructor( ) } - fun getOperationLogs( + fun getOperationLogsInPage( userId: String, projectId: String, - pipelineId: String - ): List { - val opList = pipelineOperationLogDao.getList( + pipelineId: String, + page: Int?, + pageSize: Int? + ): PipelineViewPipelinePage { + val pageNotNull = page ?: 0 + val pageSizeNotNull = pageSize ?: -1 + var slqLimit: SQLLimit? = null + if (pageSizeNotNull != -1) slqLimit = PageUtil.convertPageSizeToSQLLimit(pageNotNull, pageSizeNotNull) + val offset = slqLimit?.offset ?: 0 + val limit = slqLimit?.limit ?: -1 + val opCount = pipelineOperationLogDao.getCountByPipeline( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId ) + val opList = pipelineOperationLogDao.getListByPipeline( + dslContext = dslContext, + projectId = projectId, + pipelineId = pipelineId, + offset = offset, + limit = limit + ) val versions = mutableSetOf() opList.forEach { versions.add(it.version) } val versionMap = mutableMapOf() @@ -85,7 +103,7 @@ class PipelineOperationLogService @Autowired constructor( pipelineId = pipelineId, versions = versions ).forEach { versionMap[it.version] = it } - return opList.map { + val detailList = opList.map { with(it) { PipelineOperationDetail( id = id, @@ -104,5 +122,11 @@ class PipelineOperationLogService @Autowired constructor( ) } } + return PipelineViewPipelinePage( + page = pageNotNull, + pageSize = pageSizeNotNull, + count = opCount.toLong(), + records = detailList + ) } } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt index a11a469e1eb..7e8d19d5022 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt @@ -43,7 +43,6 @@ import com.tencent.devops.process.audit.service.AuditService import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.engine.service.PipelineVersionFacadeService import com.tencent.devops.process.permission.PipelinePermissionService -import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.audit.Audit import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage @@ -211,8 +210,10 @@ class ServicePipelineVersionResourceImpl @Autowired constructor( userId: String, projectId: String, pipelineId: String, + page: Int?, + pageSize: Int?, channelCode: ChannelCode - ): Result> { + ): Result> { checkParam(userId, projectId) val permission = AuthPermission.VIEW pipelinePermissionService.validPipelinePermission( @@ -232,7 +233,13 @@ class ServicePipelineVersionResourceImpl @Autowired constructor( ) ) return Result( - pipelineOperationLogService.getOperationLogs(userId, projectId, pipelineId) + pipelineOperationLogService.getOperationLogsInPage( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + page = page, + pageSize = pageSize + ) ) } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index d4bde18be1e..93de50682dd 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -188,11 +188,11 @@ class UserPipelineVersionResourceImpl @Autowired constructor( ) ) val result = pipelineVersionFacadeService.getVersionCreatorInPage( - projectId = projectId, - pipelineId = pipelineId, - page = page, - pageSize = pageSize - ) + projectId = projectId, + pipelineId = pipelineId, + page = page, + pageSize = pageSize + ) return Result(result) } @@ -238,8 +238,10 @@ class UserPipelineVersionResourceImpl @Autowired constructor( override fun getPipelineOperationLogs( userId: String, projectId: String, - pipelineId: String - ): Result> { + pipelineId: String, + page: Int?, + pageSize: Int? + ): Result> { checkParam(userId, projectId) val permission = AuthPermission.VIEW pipelinePermissionService.validPipelinePermission( @@ -259,7 +261,13 @@ class UserPipelineVersionResourceImpl @Autowired constructor( ) ) return Result( - pipelineOperationLogService.getOperationLogs(userId, projectId, pipelineId) + pipelineOperationLogService.getOperationLogsInPage( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + page = page, + pageSize = pageSize + ) ) } From fed38a5cb5de1a8adfe50da878c216349a5dbd4f Mon Sep 17 00:00:00 2001 From: royalhuang Date: Fri, 11 Aug 2023 10:44:32 +0800 Subject: [PATCH 044/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/pipeline/PipelineModelAndYaml.kt | 37 +++++++++++++++++++ .../api/user/UserPipelineVersionResource.kt | 7 ++-- 2 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt new file mode 100644 index 00000000000..d7a8b993f35 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt @@ -0,0 +1,37 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.common.pipeline + +import io.swagger.annotations.ApiModelProperty + +data class PipelineModelAndYaml( + @ApiModelProperty("流水线模型", required = true) + val model: Model, + @ApiModelProperty("流水线YAML编排", required = false) + val yaml: String? +) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 43a68bd4d47..dc13b129967 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -32,6 +32,7 @@ import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE import com.tencent.devops.common.api.pojo.Page import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.common.pipeline.PipelineModelAndYaml import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineOperationDetail @@ -71,10 +72,8 @@ interface UserPipelineVersionResource { @ApiParam("是否使用模板配置", required = false) @QueryParam("useTemplateSettings") useTemplateSettings: Boolean? = false, - @ApiParam(value = "流水线模型", required = true) - pipeline: Model, - @ApiParam(value = "流水线模型", required = false) - yaml: String? + @ApiParam(value = "流水线PAC模型", required = true) + pipeline: PipelineModelAndYaml ): Result @ApiOperation("保存流水线编排草稿") From e85dad24409fbb14f07f37777f4dddfb5e82975a Mon Sep 17 00:00:00 2001 From: royalhuang Date: Fri, 11 Aug 2023 11:03:52 +0800 Subject: [PATCH 045/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/api/UserPipelineVersionResourceImpl.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index 93de50682dd..0c586c2543a 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -35,6 +35,7 @@ import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.auth.api.AuthResourceType import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.common.pipeline.PipelineModelAndYaml import com.tencent.devops.common.pipeline.enums.ChannelCode import com.tencent.devops.common.web.RestResource import com.tencent.devops.common.web.utils.I18nUtil @@ -67,16 +68,15 @@ class UserPipelineVersionResourceImpl @Autowired constructor( userId: String, projectId: String, useTemplateSettings: Boolean?, - pipeline: Model, - yaml: String? + pipeline: PipelineModelAndYaml ): Result { checkParam(userId, projectId) - // 如果穿了yaml + // TODO #8161 如果传了YAML则以YAML为准 val pipelineId = PipelineId( id = pipelineInfoFacadeService.createPipeline( userId = userId, projectId = projectId, - model = pipeline, + model = pipeline.model, channelCode = ChannelCode.BS, useTemplateSettings = useTemplateSettings ) @@ -85,7 +85,7 @@ class UserPipelineVersionResourceImpl @Autowired constructor( Audit( resourceType = AuthResourceType.PIPELINE_DEFAULT.value, resourceId = pipelineId.id, - resourceName = pipeline.name, + resourceName = pipeline.model.name, userId = userId, action = "create", actionContent = "Create", From 80f35a050d42732033934dc2cfa7a697ce8429d3 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Fri, 11 Aug 2023 14:41:46 +0800 Subject: [PATCH 046/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/ServicePipelineVersionResource.kt | 5 +-- .../api/user/UserPipelineVersionResource.kt | 30 +++++++++++--- .../engine/dao/PipelineOperationLogDao.kt | 29 ++++++++++++++ .../service/PipelineOperationLogService.kt | 36 +++++++++++++++-- .../api/UserPipelineVersionResourceImpl.kt | 39 +++++++++++++++++-- .../service/PipelineVersionFacadeService.kt | 5 +-- 6 files changed, 127 insertions(+), 17 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt index 9422091ab11..46619c62093 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt @@ -34,7 +34,6 @@ import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.enums.ChannelCode import com.tencent.devops.process.engine.pojo.PipelineResVersion -import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import com.tencent.devops.process.pojo.setting.PipelineSetting @@ -103,7 +102,7 @@ interface ServicePipelineVersionResource { channelCode: ChannelCode ): Result - @ApiOperation("获取流水线编创建人列表(分页)") + @ApiOperation("获取流水线编排创建人列表(分页)") @GET @Path("/projects/{projectId}/pipelines/{pipelineId}/creatorList") fun creatorList( @@ -157,7 +156,7 @@ interface ServicePipelineVersionResource { channelCode: ChannelCode ): Result> - @ApiOperation("获取流水线操作日志列表") + @ApiOperation("获取流水线操作日志列表(分页)") @GET @Path("/projects/{projectId}/pipelines/{pipelineId}/operationLog") fun getPipelineOperationLogs( diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index e711cb6f5b4..4db5942162d 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -36,7 +36,6 @@ import com.tencent.devops.common.pipeline.PipelineModelAndYaml import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineOperationDetail -import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import com.tencent.devops.process.pojo.setting.PipelineSetting import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation @@ -114,7 +113,7 @@ interface UserPipelineVersionResource { setting: PipelineSetting ): Result - @ApiOperation("获取流水线编创建人列表(分页)") + @ApiOperation("获取流水线编排创建人列表(分页)") @GET @Path("/projects/{projectId}/pipelines/{pipelineId}/creatorList") fun creatorList( @@ -160,9 +159,9 @@ interface UserPipelineVersionResource { @ApiParam("每页多少条", required = false, defaultValue = "20") @QueryParam("pageSize") pageSize: Int? - ): Result> + ): Result> - @ApiOperation("获取流水线操作日志列表") + @ApiOperation("获取流水线操作日志列表(分页)") @GET @Path("/projects/{projectId}/pipelines/{pipelineId}/operationLog") fun getPipelineOperationLogs( @@ -181,5 +180,26 @@ interface UserPipelineVersionResource { @ApiParam("每页多少条", required = false, defaultValue = "20") @QueryParam("pageSize") pageSize: Int? - ): Result> + ): Result> + + @ApiOperation("获取流水线操作人列表(分页)") + @GET + @Path("/projects/{projectId}/pipelines/{pipelineId}/operatorList") + fun operatorList( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String, + @ApiParam("第几页", required = false, defaultValue = "1") + @QueryParam("page") + page: Int?, + @ApiParam("每页多少条", required = false, defaultValue = "20") + @QueryParam("pageSize") + pageSize: Int? + ): Result> } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt index 41ee25cea15..98b04618edb 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt @@ -132,6 +132,35 @@ class PipelineOperationLogDao { } } + fun countOperator( + dslContext: DSLContext, + projectId: String, + pipelineId: String + ): Int { + with(TPipelineOperationLog.T_PIPELINE_OPERATION_LOG) { + val query = dslContext.selectDistinct(OPERATOR) + .from(this) + .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) + return query.fetchCount() + } + } + + fun getOperatorInPage( + dslContext: DSLContext, + projectId: String, + pipelineId: String, + offset: Int, + limit: Int + ): List { + with(TPipelineOperationLog.T_PIPELINE_OPERATION_LOG) { + return dslContext.selectDistinct(OPERATOR) + .from(this) + .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) + .limit(limit).offset(offset) + .fetch().map { it.component1() } + } + } + class PipelineOperationLogJooqMapper : RecordMapper { override fun map(record: TPipelineOperationLogRecord?): PipelineOperationLog? { return record?.run { diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt index 12a3db5375c..8f0a898c7b0 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt @@ -28,13 +28,13 @@ package com.tencent.devops.process.service import com.tencent.devops.common.api.model.SQLLimit +import com.tencent.devops.common.api.pojo.Page import com.tencent.devops.common.api.util.PageUtil import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.engine.dao.PipelineOperationLogDao import com.tencent.devops.process.engine.dao.PipelineResVersionDao import com.tencent.devops.process.enums.OperationLogType import com.tencent.devops.process.pojo.PipelineOperationDetail -import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import com.tencent.devops.process.pojo.setting.PipelineVersionSimple import org.jooq.DSLContext import org.springframework.beans.factory.annotation.Autowired @@ -75,7 +75,7 @@ class PipelineOperationLogService @Autowired constructor( pipelineId: String, page: Int?, pageSize: Int? - ): PipelineViewPipelinePage { + ): Page { val pageNotNull = page ?: 0 val pageSizeNotNull = pageSize ?: -1 var slqLimit: SQLLimit? = null @@ -122,11 +122,41 @@ class PipelineOperationLogService @Autowired constructor( ) } } - return PipelineViewPipelinePage( + return Page( page = pageNotNull, pageSize = pageSizeNotNull, count = opCount.toLong(), records = detailList ) } + + fun getOperatorInPage( + projectId: String, + pipelineId: String, + page: Int?, + pageSize: Int? + ): Page { + val pageNotNull = page ?: 0 + val pageSizeNotNull = pageSize ?: -1 + var slqLimit: SQLLimit? = null + if (pageSizeNotNull != -1) slqLimit = PageUtil.convertPageSizeToSQLLimit(pageNotNull, pageSizeNotNull) + + val offset = slqLimit?.offset ?: 0 + val limit = slqLimit?.limit ?: -1 + val size = pipelineOperationLogDao.countOperator(dslContext, projectId, pipelineId) + val operators = pipelineOperationLogDao.getOperatorInPage( + dslContext = dslContext, + projectId = projectId, + pipelineId = pipelineId, + offset = offset, + limit = limit + ) + + return Page( + page = pageNotNull, + pageSize = pageSizeNotNull, + count = size.toLong(), + records = operators + ) + } } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index 0c586c2543a..c06eba2c811 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -47,7 +47,6 @@ import com.tencent.devops.process.permission.PipelinePermissionService import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.audit.Audit -import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import com.tencent.devops.process.pojo.setting.PipelineSetting import com.tencent.devops.process.service.PipelineInfoFacadeService import com.tencent.devops.process.service.PipelineOperationLogService @@ -204,7 +203,7 @@ class UserPipelineVersionResourceImpl @Autowired constructor( description: String?, page: Int?, pageSize: Int? - ): Result> { + ): Result> { checkParam(userId, projectId) val permission = AuthPermission.VIEW pipelinePermissionService.validPipelinePermission( @@ -241,7 +240,7 @@ class UserPipelineVersionResourceImpl @Autowired constructor( pipelineId: String, page: Int?, pageSize: Int? - ): Result> { + ): Result> { checkParam(userId, projectId) val permission = AuthPermission.VIEW pipelinePermissionService.validPipelinePermission( @@ -271,6 +270,40 @@ class UserPipelineVersionResourceImpl @Autowired constructor( ) } + override fun operatorList( + userId: String, + projectId: String, + pipelineId: String, + page: Int?, + pageSize: Int? + ): Result> { + checkParam(userId, projectId) + val permission = AuthPermission.VIEW + pipelinePermissionService.validPipelinePermission( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + permission = permission, + message = MessageUtil.getMessageByLocale( + CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, + I18nUtil.getLanguage(userId), + arrayOf( + userId, + projectId, + permission.getI18n(I18nUtil.getLanguage(userId)), + pipelineId + ) + ) + ) + val result = pipelineOperationLogService.getOperatorInPage( + projectId = projectId, + pipelineId = pipelineId, + page = page, + pageSize = pageSize + ) + return Result(result) + } + private fun checkParam(userId: String, projectId: String) { if (userId.isBlank()) { throw ParamBlankException("Invalid userId") diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt index 9e19610b955..b3c0d20c440 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt @@ -36,7 +36,6 @@ import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.permission.PipelinePermissionService -import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service @@ -91,7 +90,7 @@ class PipelineVersionFacadeService @Autowired constructor( pageSize: Int?, creator: String? = null, description: String? = null - ): PipelineViewPipelinePage { + ): Page { val pageNotNull = page ?: 0 val pageSizeNotNull = pageSize ?: -1 var slqLimit: SQLLimit? = null @@ -111,7 +110,7 @@ class PipelineVersionFacadeService @Autowired constructor( limit = limit ) - return PipelineViewPipelinePage( + return Page( page = pageNotNull, pageSize = pageSizeNotNull, count = size.toLong(), From 6cd41f9b495f849fa692d4a41893b99bc34a8133 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Fri, 11 Aug 2023 14:55:19 +0800 Subject: [PATCH 047/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/api/service/ServicePipelineVersionResource.kt | 5 ++--- .../tencent/devops/process/api/user/UserPipelineResource.kt | 2 +- .../devops/process/api/ServicePipelineVersionResourceImpl.kt | 5 ++--- .../tencent/devops/process/api/UserPipelineResourceImpl.kt | 2 +- 4 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt index 46619c62093..bf8b618cb30 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt @@ -35,7 +35,6 @@ import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.enums.ChannelCode import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.pojo.PipelineOperationDetail -import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import com.tencent.devops.process.pojo.setting.PipelineSetting import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation @@ -154,7 +153,7 @@ interface ServicePipelineVersionResource { @ApiParam("渠道号,默认为BS", required = false) @QueryParam("channelCode") channelCode: ChannelCode - ): Result> + ): Result> @ApiOperation("获取流水线操作日志列表(分页)") @GET @@ -178,5 +177,5 @@ interface ServicePipelineVersionResource { @ApiParam("渠道号,默认为BS", required = false) @QueryParam("channelCode") channelCode: ChannelCode - ): Result> + ): Result> } diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt index c127e76d8e7..3e5b019d2b0 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt @@ -594,7 +594,7 @@ interface UserPipelineResource { @ApiParam("每页多少条", required = false, defaultValue = "20") @QueryParam("pageSize") pageSize: Int? - ): Result> + ): Result> @ApiOperation("校验matrix yaml格式") @POST diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt index 7e8d19d5022..389ba4db8b0 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt @@ -45,7 +45,6 @@ import com.tencent.devops.process.engine.service.PipelineVersionFacadeService import com.tencent.devops.process.permission.PipelinePermissionService import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.audit.Audit -import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import com.tencent.devops.process.pojo.setting.PipelineSetting import com.tencent.devops.process.service.PipelineInfoFacadeService import com.tencent.devops.process.service.PipelineOperationLogService @@ -175,7 +174,7 @@ class ServicePipelineVersionResourceImpl @Autowired constructor( page: Int?, pageSize: Int?, channelCode: ChannelCode - ): Result> { + ): Result> { checkParam(userId, projectId) val permission = AuthPermission.VIEW pipelinePermissionService.validPipelinePermission( @@ -213,7 +212,7 @@ class ServicePipelineVersionResourceImpl @Autowired constructor( page: Int?, pageSize: Int?, channelCode: ChannelCode - ): Result> { + ): Result> { checkParam(userId, projectId) val permission = AuthPermission.VIEW pipelinePermissionService.validPipelinePermission( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index 3da8206ae84..f01061c32af 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -713,7 +713,7 @@ class UserPipelineResourceImpl @Autowired constructor( pipelineId: String, page: Int?, pageSize: Int? - ): Result> { + ): Result> { checkParam(userId, projectId) return Result( pipelineVersionFacadeService.listPipelineVersion( From e9b95981803587d920fa5461c97a117951e87aa2 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Fri, 11 Aug 2023 17:00:33 +0800 Subject: [PATCH 048/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/user/UserPipelineVersionResource.kt | 10 ++----- .../engine/dao/PipelineOperationLogDao.kt | 7 ++--- .../service/PipelineOperationLogService.kt | 27 +++---------------- .../api/UserPipelineVersionResourceImpl.kt | 10 +++---- 4 files changed, 11 insertions(+), 43 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 4db5942162d..257b63faa4c 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -194,12 +194,6 @@ interface UserPipelineVersionResource { projectId: String, @ApiParam("流水线ID", required = true) @PathParam("pipelineId") - pipelineId: String, - @ApiParam("第几页", required = false, defaultValue = "1") - @QueryParam("page") - page: Int?, - @ApiParam("每页多少条", required = false, defaultValue = "20") - @QueryParam("pageSize") - pageSize: Int? - ): Result> + pipelineId: String + ): Result> } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt index 98b04618edb..237402aeb04 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineOperationLogDao.kt @@ -145,18 +145,15 @@ class PipelineOperationLogDao { } } - fun getOperatorInPage( + fun getOperatorList( dslContext: DSLContext, projectId: String, - pipelineId: String, - offset: Int, - limit: Int + pipelineId: String ): List { with(TPipelineOperationLog.T_PIPELINE_OPERATION_LOG) { return dslContext.selectDistinct(OPERATOR) .from(this) .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) - .limit(limit).offset(offset) .fetch().map { it.component1() } } } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt index 8f0a898c7b0..0f3286165c7 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt @@ -132,31 +132,12 @@ class PipelineOperationLogService @Autowired constructor( fun getOperatorInPage( projectId: String, - pipelineId: String, - page: Int?, - pageSize: Int? - ): Page { - val pageNotNull = page ?: 0 - val pageSizeNotNull = pageSize ?: -1 - var slqLimit: SQLLimit? = null - if (pageSizeNotNull != -1) slqLimit = PageUtil.convertPageSizeToSQLLimit(pageNotNull, pageSizeNotNull) - - val offset = slqLimit?.offset ?: 0 - val limit = slqLimit?.limit ?: -1 - val size = pipelineOperationLogDao.countOperator(dslContext, projectId, pipelineId) - val operators = pipelineOperationLogDao.getOperatorInPage( + pipelineId: String + ): List { + return pipelineOperationLogDao.getOperatorList( dslContext = dslContext, projectId = projectId, - pipelineId = pipelineId, - offset = offset, - limit = limit - ) - - return Page( - page = pageNotNull, - pageSize = pageSizeNotNull, - count = size.toLong(), - records = operators + pipelineId = pipelineId ) } } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index c06eba2c811..07daf022182 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -273,10 +273,8 @@ class UserPipelineVersionResourceImpl @Autowired constructor( override fun operatorList( userId: String, projectId: String, - pipelineId: String, - page: Int?, - pageSize: Int? - ): Result> { + pipelineId: String + ): Result> { checkParam(userId, projectId) val permission = AuthPermission.VIEW pipelinePermissionService.validPipelinePermission( @@ -297,9 +295,7 @@ class UserPipelineVersionResourceImpl @Autowired constructor( ) val result = pipelineOperationLogService.getOperatorInPage( projectId = projectId, - pipelineId = pipelineId, - page = page, - pageSize = pageSize + pipelineId = pipelineId ) return Result(result) } From 49fad03678538f8fa19d6cb1ef36864e30d1b5f9 Mon Sep 17 00:00:00 2001 From: yongyiduan Date: Thu, 10 Aug 2023 10:23:56 +0800 Subject: [PATCH 049/852] =?UTF-8?q?=E3=80=90=E8=93=9D=E7=9B=BE-=E8=AF=84?= =?UTF-8?q?=E5=AE=A1=E4=BC=9A=E5=B7=B2=E8=AF=84=E5=AE=A1=E3=80=91=E3=80=90?= =?UTF-8?q?PAC=E3=80=91feat=EF=BC=9A=E6=96=B0=E5=BB=BA/=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=94=AF=E6=8C=81=E4=BB=A5=20Code?= =?UTF-8?q?=20=E6=96=B9=E5=BC=8F=E7=BC=96=E6=8E=92=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=20#8125?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common-pipeline-yaml/build.gradle.kts | 8 +- .../process/yaml/modelCreate/ModelCommon.kt | 17 + .../yaml/modelCreate/ModelContainer.kt | 207 +++++- .../yaml/modelTransfer/ElementTransfer.kt | 426 +++++++++++ .../yaml/modelTransfer/ModelTransfer.kt | 289 +++++++ .../yaml/modelTransfer/StageTransfer.kt | 331 +++++++++ .../modelTransfer/TransferCacheService.kt | 52 ++ .../yaml/modelTransfer/TransferMapper.kt | 488 ++++++++++++ .../yaml/modelTransfer/TriggerTransfer.kt | 494 ++++++++++++ .../inner/TransferModelCreator.kt | 69 ++ .../inner/TransferModelCreatorImpl.kt | 133 ++++ .../modelTransfer/pojo/CheckoutAtomParam.kt | 236 ++++++ .../modelTransfer/pojo/ModelTransferInput.kt | 13 + .../yaml/modelTransfer/pojo/RunAtomParam.kt | 44 ++ .../pojo/WebHookTriggerElementChanger.kt | 193 +++++ .../modelTransfer/pojo/YamlTransferInput.kt | 15 + .../devops/process/yaml/pojo/TemplatePath.kt | 37 + .../devops/process/yaml/pojo/YamlVersion.kt | 10 + .../process/yaml/utils/StreamDispatchUtils.kt | 2 +- .../process/yaml/v2/enums/TemplateType.kt | 1 + .../devops/process/yaml/v2/models/Extends.kt | 8 +- .../yaml/v2/models/PreScriptBuildYaml.kt | 12 +- .../v2/models/PreTemplateScriptBuildYaml.kt | 119 ++- .../process/yaml/v2/models/ScriptBuildYaml.kt | 7 +- .../devops/process/yaml/v2/models/Template.kt | 1 + .../devops/process/yaml/v2/models/Variable.kt | 50 +- .../process/yaml/v2/models/job/PreJob.kt | 4 +- .../process/yaml/v2/models/on/MrRule.kt | 16 +- .../process/yaml/v2/models/on/NoteRule.kt | 6 +- .../process/yaml/v2/models/on/ReviewRule.kt | 6 +- .../process/yaml/v2/models/on/TriggerOn.kt | 101 ++- .../process/yaml/v2/models/stage/PreStage.kt | 4 +- .../process/yaml/v2/models/step/PreStep.kt | 4 +- .../yaml/v2/parsers/template/Constants.kt | 1 + .../template/ParametersExpressionParse.kt | 23 +- .../v2/parsers/template/TemplateLibrary.kt | 13 +- .../v2/parsers/template/TemplateYamlUtil.kt | 21 +- .../yaml/v2/parsers/template/YamlObjects.kt | 57 +- .../yaml/v2/parsers/template/YamlTemplate.kt | 153 ++-- .../template/models/GetTemplateParam.kt | 3 +- .../template/models/TemplateDeepTreeNode.kt | 5 +- .../process/yaml/v2/utils/ScriptYmlUtils.kt | 112 +-- .../process/yaml/v2/utils/StreamEnvUtils.kt | 3 +- .../yaml/v3/models/PreScriptBuildYamlV3.kt | 69 ++ .../v3/models/PreTemplateScriptBuildYamlV3.kt | 120 +++ .../yaml/v3/models/ScriptBuildYamlV3.kt | 63 ++ .../yaml/v3/models/on/PreTriggerOnV3.kt | 65 ++ .../yaml/modelTransfer/MergeYamlTest.kt | 55 ++ .../yaml/parsers/template/YamlTemplateTest.kt | 24 +- .../template/ParametersExpressionParseTest.kt | 3 +- .../resources/TransferYaml/base-1/new.yml | 21 + .../resources/TransferYaml/base-1/old.yml | 23 + .../resources/TransferYaml/base-1/out.yml | 25 + .../resources/TransferYaml/base-2/new.yml | 9 + .../resources/TransferYaml/base-2/old.yml | 15 + .../resources/TransferYaml/base-2/out.yml | 15 + .../src/test/resources/compared/all/all.yml | 238 ++---- .../test/resources/compared/all/all_old.yml | 238 ++---- .../resources/compared/extends/extends.yml | 686 ++++------------- .../compared/extends/extends_old.yml | 686 ++++------------- .../src/test/resources/compared/jobs/jobs.yml | 514 +++---------- .../compared/parameters/parameters.yml | 127 +--- .../compared/parameters/parameters_old.yml | 127 +--- .../compared/specials/longParametersTest.yml | 130 ++-- .../specials/longParametersTest_old.yml | 130 ++-- .../test/resources/compared/specials/user.yml | 702 ++++++------------ .../test/resources/compared/stages/stages.yml | 182 +---- .../test/resources/compared/steps/stepss.yml | 588 ++++++--------- .../src/test/resources/samples/all/all.yml | 2 - .../templates/repoC/templates/pipeline.yml | 2 +- .../trigger/CodeGitWebHookTriggerElement.kt | 14 +- .../CodeGithubWebHookTriggerElement.kt | 47 +- .../trigger/CodeTGitWebHookTriggerElement.kt | 38 +- .../api/user/UserPipelineTransferResource.kt | 123 +++ .../process/pojo/transfer/PreviewResponse.kt | 45 ++ .../pojo/transfer/TransferActionType.kt | 41 + .../process/pojo/transfer/TransferBody.kt | 40 + .../process/pojo/transfer/TransferMark.kt | 46 ++ .../process/pojo/transfer/TransferResponse.kt | 42 ++ .../core/process/biz-process/build.gradle.kts | 1 + .../api/UserPipelineTransferResourceImpl.kt | 76 ++ .../transfer/PipelineTransferService.kt | 204 +++++ .../service/ServiceStoreImageResource.kt | 12 + .../api/atom/ServiceMarketAtomResource.kt | 8 + .../service/ServiceStoreImageResourceImpl.kt | 9 + .../store/service/image/ImageService.kt | 24 + .../atom/ServiceMarketAtomResourceImpl.kt | 5 + .../store/service/atom/MarketAtomService.kt | 6 + .../atom/impl/MarketAtomServiceImpl.kt | 44 +- .../stream/trigger/ManualTriggerService.kt | 3 +- .../stream/trigger/StreamYamlTrigger.kt | 7 +- .../trigger/pojo/ManualPreScriptBuildYaml.kt | 5 +- 92 files changed, 6056 insertions(+), 3437 deletions(-) create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferCacheService.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferMapper.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreator.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreatorImpl.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/CheckoutAtomParam.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/ModelTransferInput.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/RunAtomParam.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/WebHookTriggerElementChanger.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/YamlTransferInput.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/TemplatePath.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/YamlVersion.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreScriptBuildYamlV3.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYamlV3.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/ScriptBuildYamlV3.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PreTriggerOnV3.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/test/kotlin/com/tencent/devops/process/yaml/modelTransfer/MergeYamlTest.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-1/new.yml create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-1/old.yml create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-1/out.yml create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-2/new.yml create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-2/old.yml create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-2/out.yml create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/PreviewResponse.kt create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferActionType.kt create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferBody.kt create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferMark.kt create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferResponse.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferService.kt diff --git a/src/backend/ci/core/common/common-pipeline-yaml/build.gradle.kts b/src/backend/ci/core/common/common-pipeline-yaml/build.gradle.kts index 6a8409de08e..06015021c87 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/build.gradle.kts +++ b/src/backend/ci/core/common/common-pipeline-yaml/build.gradle.kts @@ -33,8 +33,14 @@ dependencies { api("org.apache.ant:ant") api("org.apache.commons:commons-text") - api("org.yaml:snakeyaml") api("com.github.fge:json-schema-validator") + // https://mvnrepository.com/artifact/io.github.java-diff-utils/java-diff-utils + implementation("io.github.java-diff-utils:java-diff-utils:4.12") + // https://mvnrepository.com/artifact/org.json/json + implementation("org.json:json:20230618") + // https://mvnrepository.com/artifact/org.yaml/snakeyaml +// implementation("org.yaml:snakeyaml:2.1") + testImplementation(project(":core:common:common-test")) } plugins { diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelCommon.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelCommon.kt index 84eeaa5a3f7..dab2fa89afd 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelCommon.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelCommon.kt @@ -28,6 +28,7 @@ package com.tencent.devops.process.yaml.modelCreate import com.tencent.devops.common.client.Client +import com.tencent.devops.common.pipeline.NameAndValue import com.tencent.devops.common.pipeline.enums.ChannelCode import com.tencent.devops.process.yaml.v2.utils.ScriptYmlUtils import com.tencent.devops.store.api.atom.ServiceMarketAtomResource @@ -98,4 +99,20 @@ object ModelCommon { return parseReceivers } + + fun customVariableMatch(input: List?): String? { + val ifString = input?.joinToString(separator = " && ") { + "${it.key} == '${it.value}' " + } + return if (input?.isEmpty() == true) null + else ifString + } + + fun customVariableMatchNotRun(input: List?): String? { + val ifString = input?.joinToString(separator = " || ") { + "${it.key} != '${it.value}' " + } + return if (input?.isEmpty() == true) null + else ifString + } } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelContainer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelContainer.kt index d0ac40162bf..13417ee2bf8 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelContainer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelContainer.kt @@ -31,6 +31,7 @@ import com.fasterxml.jackson.databind.ObjectMapper import com.tencent.devops.common.api.constant.CommonMessageCode.BK_ENV_NOT_YET_SUPPORTED import com.tencent.devops.common.api.exception.CustomException import com.tencent.devops.common.api.util.JsonUtil +import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.api.util.YamlUtil import com.tencent.devops.common.client.Client import com.tencent.devops.common.pipeline.container.Container @@ -38,6 +39,7 @@ import com.tencent.devops.common.pipeline.container.MutexGroup import com.tencent.devops.common.pipeline.container.NormalContainer import com.tencent.devops.common.pipeline.container.VMBuildContainer import com.tencent.devops.common.pipeline.enums.DependOnType +import com.tencent.devops.common.pipeline.enums.DockerVersion import com.tencent.devops.common.pipeline.enums.JobRunCondition import com.tencent.devops.common.pipeline.enums.VMBaseOS import com.tencent.devops.common.pipeline.matrix.DispatchInfo @@ -45,27 +47,40 @@ import com.tencent.devops.common.pipeline.matrix.MatrixConfig.Companion.MATRIX_C import com.tencent.devops.common.pipeline.option.JobControlOption import com.tencent.devops.common.pipeline.option.MatrixControlOption import com.tencent.devops.common.pipeline.pojo.element.Element +import com.tencent.devops.common.pipeline.type.StoreDispatchType +import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentEnvDispatchType +import com.tencent.devops.common.pipeline.type.docker.DockerDispatchType +import com.tencent.devops.common.pipeline.type.docker.ImageType import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.process.constant.ProcessMessageCode import com.tencent.devops.process.pojo.BuildTemplateAcrossInfo import com.tencent.devops.process.yaml.modelCreate.inner.InnerModelCreator +import com.tencent.devops.process.yaml.modelTransfer.TransferCacheService import com.tencent.devops.process.yaml.pojo.StreamDispatchInfo import com.tencent.devops.process.yaml.utils.ModelCreateUtil import com.tencent.devops.process.yaml.utils.StreamDispatchUtils import com.tencent.devops.process.yaml.v2.models.IfType import com.tencent.devops.process.yaml.v2.models.Resources +import com.tencent.devops.process.yaml.v2.models.job.Container2 import com.tencent.devops.process.yaml.v2.models.job.Job +import com.tencent.devops.process.yaml.v2.models.job.JobRunsOnType import com.tencent.devops.process.yaml.v2.models.job.Mutex +import com.tencent.devops.process.yaml.v2.models.job.PreJob +import com.tencent.devops.process.yaml.v2.models.job.RunsOn +import com.tencent.devops.process.yaml.v2.models.job.Strategy +import com.tencent.devops.process.yaml.v2.models.step.PreStep import com.tencent.devops.store.api.container.ServiceContainerAppResource -import javax.ws.rs.core.Response import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component +import javax.ws.rs.core.Response @Component class ModelContainer @Autowired(required = false) constructor( val client: Client, val objectMapper: ObjectMapper, @Autowired(required = false) - val inner: InnerModelCreator? + val inner: InnerModelCreator?, + val transferCache: TransferCacheService ) { fun addVmBuildContainer( @@ -275,4 +290,192 @@ class ModelContainer @Autowired(required = false) constructor( timeout = resource.timeoutMinutes ?: 10 ) } + + fun addYamlNormalContainer( + job: NormalContainer, + steps: List? + ): PreJob { + return PreJob( + name = job.name, + runsOn = RunsOn( + selfHosted = null, + poolName = JobRunsOnType.AGENT_LESS.type, + container = null + ), + container = null, + services = null, + ifField = when (job.jobControlOption?.runCondition) { + JobRunCondition.CUSTOM_CONDITION_MATCH -> job.jobControlOption?.customCondition + JobRunCondition.CUSTOM_VARIABLE_MATCH -> ModelCommon.customVariableMatch( + job.jobControlOption?.customVariables + ) + JobRunCondition.CUSTOM_VARIABLE_MATCH_NOT_RUN -> ModelCommon.customVariableMatchNotRun( + job.jobControlOption?.customVariables + ) + else -> null + }, + steps = steps, + timeoutMinutes = job.jobControlOption?.timeout, + env = null, + continueOnError = if (job.jobControlOption?.continueWhenFailed == true) true else null, + strategy = if (job.matrixGroupFlag == true) { + getMatrixFromJob(job.matrixControlOption) + } else null, + // 蓝盾这边是自定义Job ID + dependOn = if (!job.jobControlOption?.dependOnId.isNullOrEmpty()) { + job.jobControlOption?.dependOnId + } else null + ) + } + + fun addYamlVMBuildContainer( + job: VMBuildContainer, + steps: List? + ): PreJob { + return PreJob( + name = job.name, + runsOn = getRunsOn(job), + container = null, + services = null, + ifField = when (job.jobControlOption?.runCondition) { + JobRunCondition.CUSTOM_CONDITION_MATCH -> job.jobControlOption?.customCondition + JobRunCondition.CUSTOM_VARIABLE_MATCH -> ModelCommon.customVariableMatch( + job.jobControlOption?.customVariables + ) + JobRunCondition.CUSTOM_VARIABLE_MATCH_NOT_RUN -> ModelCommon.customVariableMatchNotRun( + job.jobControlOption?.customVariables + ) + else -> null + }, + steps = steps, + timeoutMinutes = job.jobControlOption?.timeout, + env = null, + continueOnError = if (job.jobControlOption?.continueWhenFailed == true) true else null, + strategy = if (job.matrixGroupFlag == true) { + getMatrixFromJob(job.matrixControlOption) + } else null, + dependOn = if (!job.jobControlOption?.dependOnId.isNullOrEmpty()) { + job.jobControlOption?.dependOnId + } else null + ) + } + + fun getRunsOn( + job: VMBuildContainer + ): RunsOn = when (val dispatchType = job.dispatchType) { + is ThirdPartyAgentEnvDispatchType -> { + RunsOn( + selfHosted = true, + poolName = I18nUtil.getCodeLanMessage( + messageCode = ProcessMessageCode.BK_AUTOMATIC_EXPORT_NOT_SUPPORTED + ), + container = null, + agentSelector = listOf(job.baseOS.name.toLowerCase()), + needs = job.buildEnv + ) + } + is DockerDispatchType -> { + // todo 凭据是否处理 + val (containerImage, credentials) = getImageNameAndCredentials( + dispatchType + ) + RunsOn( + selfHosted = null, + poolName = JobRunsOnType.DOCKER.type, + container = Container2( + image = containerImage, + credentials = credentials, + options = null, + imagePullPolicy = null + ), + agentSelector = null, + needs = job.buildEnv + ) + } + else -> { + RunsOn( + selfHosted = null, + poolName = I18nUtil.getCodeLanMessage( + messageCode = ProcessMessageCode.BK_AUTOMATIC_EXPORT_NOT_SUPPORTED + ), + container = null, + agentSelector = null + ) + } + } + + fun getImageNameAndCredentials( + dispatchType: StoreDispatchType + ): Pair { + try { + when (dispatchType.imageType) { + ImageType.BKSTORE -> { + val imageRepoInfo = transferCache.getStoreImageInfo( + imageCode = dispatchType.imageCode ?: "", + imageVersion = dispatchType.imageVersion + ) ?: return Pair(dispatchType.imageCode ?: "", null) + val completeImageName = if (ImageType.BKDEVOPS == imageRepoInfo.sourceType) { + // 蓝盾项目源镜像 + "${imageRepoInfo.repoUrl}/${imageRepoInfo.repoName}" + } else { + // 第三方源镜像 + // dockerhub镜像名称不带斜杠前缀 + if (imageRepoInfo.repoUrl.isBlank()) { + imageRepoInfo.repoName + } else { + "${imageRepoInfo.repoUrl}/${imageRepoInfo.repoName}" + } + } + ":" + imageRepoInfo.repoTag + return if (imageRepoInfo.publicFlag) { + Pair(completeImageName, null) + } else Pair( + completeImageName, imageRepoInfo.ticketId + ) + } + ImageType.BKDEVOPS -> { + // 针对非商店的旧数据处理 + return if (dispatchType.value != DockerVersion.TLINUX1_2.value && + dispatchType.value != DockerVersion.TLINUX2_2.value + ) { + dispatchType.dockerBuildVersion = "bkdevops/" + dispatchType.value + Pair("bkdevops/" + dispatchType.value, null) + } else { + Pair( + MessageUtil.getMessageByLocale( + messageCode = ProcessMessageCode.BK_AUTOMATIC_EXPORT_NOT_SUPPORTED_IMAGE, + language = I18nUtil.getLanguage() + ), null + ) + } + } + else -> { + return if (dispatchType.credentialId.isNullOrBlank()) { + Pair(dispatchType.value, null) + } else Pair( + dispatchType.value, dispatchType.credentialId + ) + } + } + } catch (e: Exception) { + return Pair( + MessageUtil.getMessageByLocale( + messageCode = ProcessMessageCode.BK_ENTER_URL_ADDRESS_IMAGE, + language = I18nUtil.getLanguage() + ), null + ) + } + } + + fun getMatrixFromJob( + matrixControlOption: MatrixControlOption? + ): Strategy? { + if (matrixControlOption == null) { + return null + } + return Strategy( + matrix = matrixControlOption.convertMatrixToYamlConfig() ?: return null, + fastKill = matrixControlOption.fastKill, + maxParallel = matrixControlOption.maxConcurrency + ) + } } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt new file mode 100644 index 00000000000..5cdff16ebbd --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt @@ -0,0 +1,426 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.modelTransfer + +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.common.client.Client +import com.tencent.devops.common.pipeline.NameAndValue +import com.tencent.devops.common.pipeline.container.Container +import com.tencent.devops.common.pipeline.enums.BuildScriptType +import com.tencent.devops.common.pipeline.pojo.element.Element +import com.tencent.devops.common.pipeline.pojo.element.ElementAdditionalOptions +import com.tencent.devops.common.pipeline.pojo.element.RunCondition +import com.tencent.devops.common.pipeline.pojo.element.agent.LinuxScriptElement +import com.tencent.devops.common.pipeline.pojo.element.agent.WindowsScriptElement +import com.tencent.devops.common.pipeline.pojo.element.market.MarketBuildAtomElement +import com.tencent.devops.common.pipeline.pojo.element.market.MarketBuildLessAtomElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGitWebHookTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGithubWebHookTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeTGitWebHookTriggerElement +import com.tencent.devops.process.yaml.modelCreate.ModelCommon +import com.tencent.devops.process.yaml.modelCreate.ModelCreateException +import com.tencent.devops.process.yaml.modelTransfer.inner.TransferModelCreator +import com.tencent.devops.process.yaml.modelTransfer.pojo.CheckoutAtomParam +import com.tencent.devops.process.yaml.modelTransfer.pojo.RunAtomParam +import com.tencent.devops.process.yaml.modelTransfer.pojo.WebHookTriggerElementChanger +import com.tencent.devops.process.yaml.modelTransfer.pojo.YamlTransferInput +import com.tencent.devops.process.yaml.utils.ModelCreateUtil +import com.tencent.devops.process.yaml.v2.models.IfType +import com.tencent.devops.process.yaml.v2.models.job.Job +import com.tencent.devops.process.yaml.v2.models.on.TriggerOn +import com.tencent.devops.process.yaml.v2.models.step.PreStep +import com.tencent.devops.process.yaml.v2.models.step.Step +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component + +@Component +class ElementTransfer @Autowired(required = false) constructor( + val client: Client, + @Autowired(required = false) + val creator: TransferModelCreator, + val transferCache: TransferCacheService, + val triggerTransfer: TriggerTransfer +) { + companion object { + private val logger = LoggerFactory.getLogger(ElementTransfer::class.java) + } + + fun yaml2Triggers(triggerOns: Map, elements: MutableList) { + triggerOns.forEach { + when (it.key) { + ScmType.CODE_GIT -> triggerTransfer.yaml2TriggerGit(it.value, elements) + ScmType.CODE_TGIT -> triggerTransfer.yaml2TriggerTGit(it.value, elements) + ScmType.GITHUB -> triggerTransfer.yaml2TriggerGithub(it.value, elements) + } + } + } + + fun triggers2Yaml(elements: List): Map { + val res = mutableMapOf() + val fix = elements.groupBy { it.getClassType() } + + val gitElement = fix[CodeGitWebHookTriggerElement.classType]?.map { + WebHookTriggerElementChanger(it as CodeGitWebHookTriggerElement) + } + if (!gitElement.isNullOrEmpty()) { + val gitTrigger = triggerTransfer.git2YamlTriggerOn(gitElement) + res.putAll(gitTrigger.associateBy { ScmType.CODE_GIT }) + } + + val tGitElement = fix[CodeTGitWebHookTriggerElement.classType]?.map { + WebHookTriggerElementChanger(it as CodeTGitWebHookTriggerElement) + } + if (!tGitElement.isNullOrEmpty()) { + val gitTrigger = triggerTransfer.git2YamlTriggerOn(tGitElement) + res.putAll(gitTrigger.associateBy { ScmType.CODE_TGIT }) + } + + val githubElement = fix[CodeGithubWebHookTriggerElement.classType]?.map { + WebHookTriggerElementChanger(it as CodeGithubWebHookTriggerElement) + } + if (!githubElement.isNullOrEmpty()) { + val gitTrigger = triggerTransfer.git2YamlTriggerOn(githubElement) + res.putAll(gitTrigger.associateBy { ScmType.GITHUB }) + } + return res + } + + @Suppress("ComplexMethod", "NestedBlockDepth") + fun yaml2Elements( + job: Job, + yamlInput: YamlTransferInput + ): MutableList { + // 解析service + val elementList = makeServiceElementList(job) + // 解析job steps + job.steps!!.forEach { step -> + val element: Element = yaml2element(step, job.runsOn.agentSelector?.first()) + elementList.add(element) + } + + return elementList + } + + fun yaml2element( + step: Step, + agentSelector: String?, + ): Element { + val timeout = setupTimeout(step) + val additionalOptions = ElementAdditionalOptions( + continueWhenFailed = step.continueOnError ?: false, + timeout = timeout, + timeoutVar = timeout.toString(), + retryWhenFailed = step.retryTimes != null, + retryCount = step.retryTimes ?: 0, + enableCustomEnv = step.env != null, + customEnv = getElementEnv(step.env), + runCondition = when { + step.ifFiled.isNullOrBlank() -> RunCondition.PRE_TASK_SUCCESS + IfType.ALWAYS_UNLESS_CANCELLED.name == (step.ifFiled) -> + RunCondition.PRE_TASK_FAILED_BUT_CANCEL + + IfType.ALWAYS.name == (step.ifFiled) -> + RunCondition.PRE_TASK_FAILED_EVEN_CANCEL + + IfType.FAILURE.name == (step.ifFiled) -> + RunCondition.PRE_TASK_FAILED_ONLY + + else -> RunCondition.CUSTOM_CONDITION_MATCH + }, + customCondition = if (step.ifFiled.isNullOrBlank()) { + step.ifFiled + } else { + ModelCreateUtil.removeIfBrackets(step.ifFiled) + }, + manualRetry = false + ) + + // bash + val element: Element = when { + step.run != null -> { + makeRunElement(step, agentSelector, additionalOptions) + } + + step.checkout != null -> { + creator.transferCheckoutElement(step, additionalOptions) + } + + else -> { + creator.transferMarketBuildAtomElement(step, additionalOptions) + } + } + return element + } + + private fun setupTimeout(step: Step) = step.timeoutMinutes?.toLong() ?: 480 + + private fun makeRunElement( + step: Step, + agentSelector: String?, + additionalOptions: ElementAdditionalOptions + ): Element { + val type = step.runAdditionalOptions?.get(RunAtomParam::shell.name) + ?: when (agentSelector) { + "windows" -> + RunAtomParam.ShellType.CMD.shellName + null -> null + else -> RunAtomParam.ShellType.BASH.shellName + } + return when (type) { + RunAtomParam.ShellType.BASH.shellName -> LinuxScriptElement( + id = step.taskId, + name = step.name ?: "run", + stepId = step.id, + scriptType = BuildScriptType.SHELL, + script = step.run ?: "", + continueNoneZero = false, + additionalOptions = additionalOptions + ) + RunAtomParam.ShellType.CMD.shellName -> WindowsScriptElement( + id = step.taskId, + name = step.name ?: "run", + stepId = step.id, + scriptType = BuildScriptType.BAT, + script = step.run ?: "" + ) + else -> { + val data = mutableMapOf() + data["input"] = mapOf( + RunAtomParam::script.name to step.run, + RunAtomParam::shell.name to type + ) + MarketBuildAtomElement( + id = step.taskId, + name = step.name ?: "run", + stepId = step.id, + atomCode = creator.runPlugInAtomCode ?: throw ModelCreateException("runPlugInAtomCode must exist"), + version = creator.runPlugInVersion ?: throw ModelCreateException("runPlugInVersion must exist"), + data = data, + additionalOptions = additionalOptions + ) + } + } + } + + fun model2YamlSteps( + job: Container + ): List { + val stepList = mutableListOf() + job.elements.forEach { element -> + val step = element2YamlStep(element) + if (step != null) { + stepList.add(step) + } + } + return stepList + } + + @Suppress("ComplexMethod") + fun element2YamlStep(element: Element): PreStep? { + val retryTimes = element.additionalOptions?.retryCount ?: 0 + val timeoutMinutes = element.additionalOptions?.timeout?.toInt() ?: 480 + val continueOnError = element.additionalOptions?.continueWhenFailed + val uses = "${element.getAtomCode()}@${element.version}" + return when { + element is LinuxScriptElement -> { + PreStep( + name = element.name, + id = element.stepId, + // bat插件上的 + ifFiled = parseStepIfFiled(element), + uses = null, + with = null, + timeoutMinutes = timeoutMinutes, + continueOnError = continueOnError, + retryTimes = retryTimes, + env = null, + run = element.script, + checkout = null, + shell = RunAtomParam.ShellType.BASH.shellName + ) + } + element is WindowsScriptElement -> { + PreStep( + name = element.name, + id = element.stepId, + // bat插件上的 + ifFiled = parseStepIfFiled(element), + uses = null, + with = null, + timeoutMinutes = timeoutMinutes, + continueOnError = continueOnError, + retryTimes = retryTimes, + env = null, + run = element.script, + checkout = null, + shell = RunAtomParam.ShellType.CMD.shellName + ) + } + element.getAtomCode() == "checkout" && element is MarketBuildAtomElement -> { + val input = element.data["input"] as Map? ?: emptyMap() + val url = input[CheckoutAtomParam::repositoryUrl.name].toString().ifBlank { null } + // todo 等待checkout插件新增self参数 + PreStep( + name = element.name, + id = element.stepId, + // 插件上的 + ifFiled = parseStepIfFiled(element), + uses = null, + with = simplifyParams(uses, input), + timeoutMinutes = timeoutMinutes, + continueOnError = continueOnError, + retryTimes = retryTimes, + env = null, + run = null, + checkout = url, + shell = null + ) + } + element.getAtomCode() == "run" && element is MarketBuildAtomElement -> { + val input = element.data["input"] as Map? ?: emptyMap() + PreStep( + name = element.name, + id = element.stepId, + // 插件上的 + ifFiled = parseStepIfFiled(element), + uses = null, + with = simplifyParams( + uses, + input.filterNot { + it.key == RunAtomParam::shell.name || it.key == RunAtomParam::script.name + } + ), + timeoutMinutes = timeoutMinutes, + continueOnError = continueOnError, + retryTimes = retryTimes, + env = null, + run = input[RunAtomParam::script.name]?.toString(), + checkout = null, + shell = input[RunAtomParam::shell.name]?.toString() + ) + } + element is MarketBuildLessAtomElement -> { + val input = element.data["input"] as Map? ?: emptyMap() + PreStep( + name = element.name, + id = element.stepId, + // 插件上的 + ifFiled = parseStepIfFiled(element), + uses = uses, + with = simplifyParams(uses, input), + timeoutMinutes = timeoutMinutes, + continueOnError = continueOnError, + retryTimes = retryTimes, + env = null, + run = null, + checkout = null, + shell = null + ) + } + element is MarketBuildAtomElement -> { + val input = element.data["input"] as Map? ?: emptyMap() + PreStep( + name = element.name, + id = element.stepId, + // 插件上的 + ifFiled = parseStepIfFiled(element), + uses = uses, + with = simplifyParams(uses, input), + timeoutMinutes = timeoutMinutes, + continueOnError = continueOnError, + retryTimes = retryTimes, + env = null, + run = null, + checkout = null, + shell = null + ) + } + else -> null + } + } + + private fun parseStepIfFiled( + step: Element + ): String? { + return when (step.additionalOptions?.runCondition) { + RunCondition.CUSTOM_CONDITION_MATCH -> step.additionalOptions?.customCondition + RunCondition.CUSTOM_VARIABLE_MATCH -> ModelCommon.customVariableMatch( + step.additionalOptions?.customVariables + ) + RunCondition.CUSTOM_VARIABLE_MATCH_NOT_RUN -> ModelCommon.customVariableMatchNotRun( + step.additionalOptions?.customVariables + ) + RunCondition.PRE_TASK_FAILED_BUT_CANCEL -> + IfType.ALWAYS_UNLESS_CANCELLED.name + RunCondition.PRE_TASK_FAILED_EVEN_CANCEL -> + IfType.ALWAYS.name + RunCondition.PRE_TASK_FAILED_ONLY -> + IfType.FAILURE.name + else -> null + } + } + + private fun simplifyParams(uses: String, input: Map): Map { + val out = input.toMutableMap() + val defaultValue = transferCache.getAtomDefaultValue(uses) + defaultValue.forEach { + val value = out[it.key] + if (value is String && it.value == value) { + out.remove(it.key) + } + // 单独针对list的情况 + if (value is List<*> && it.value == value.joinToString(separator = ",")) { + out.remove(it.key) + } + } + return out + } + + protected fun makeServiceElementList(job: Job): MutableList { + return mutableListOf() + } + + private fun getElementEnv(env: Map?): List? { + if (env == null) { + return null + } + + val nameAndValueList = mutableListOf() + env.forEach { + nameAndValueList.add( + NameAndValue( + key = it.key, + value = it.value.toString() + ) + ) + } + + return nameAndValueList + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt new file mode 100644 index 00000000000..a4463a64794 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt @@ -0,0 +1,289 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.modelTransfer + +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.common.client.Client +import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.common.pipeline.container.Stage +import com.tencent.devops.common.pipeline.container.TriggerContainer +import com.tencent.devops.process.api.user.UserPipelineGroupResource +import com.tencent.devops.process.pojo.classify.PipelineGroup +import com.tencent.devops.process.pojo.classify.PipelineGroupCreate +import com.tencent.devops.process.pojo.classify.PipelineLabelCreate +import com.tencent.devops.process.pojo.setting.PipelineRunLockType +import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.process.yaml.modelTransfer.pojo.ModelTransferInput +import com.tencent.devops.process.yaml.modelTransfer.pojo.YamlTransferInput +import com.tencent.devops.process.yaml.pojo.YamlVersion +import com.tencent.devops.process.yaml.v2.models.Concurrency +import com.tencent.devops.process.yaml.v2.models.GitNotices +import com.tencent.devops.process.yaml.v2.models.IPreTemplateScriptBuildYaml +import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYaml +import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYamlI +import com.tencent.devops.process.yaml.v2.models.Variable +import com.tencent.devops.process.yaml.v2.models.on.TriggerOn +import com.tencent.devops.process.yaml.v2.models.stage.PreStage +import com.tencent.devops.process.yaml.v3.models.PreScriptBuildYamlV3 +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component +import java.util.concurrent.TimeUnit + +@Component +class ModelTransfer @Autowired constructor( + val client: Client, + val modelStage: StageTransfer, + val modelElement: ElementTransfer +) { + + companion object { + private val logger = LoggerFactory.getLogger(ModelTransfer::class.java) + } + + fun yaml2Labels(yamlInput: YamlTransferInput): List { + return preparePipelineLabels(yamlInput.userId, yamlInput.projectCode, yamlInput.yaml) + } + + fun yaml2Setting(yamlInput: YamlTransferInput): PipelineSetting { + val yaml = yamlInput.yaml + return PipelineSetting( + concurrencyGroup = yaml.concurrency?.group, + // Cancel-In-Progress 配置group后默认为true + concurrencyCancelInProgress = yaml.concurrency?.cancelInProgress + ?: yaml.concurrency?.group?.let { true } + ?: true, + runLockType = when { + yaml.concurrency?.group != null -> PipelineRunLockType.GROUP_LOCK + else -> PipelineRunLockType.MULTIPLE + }, + waitQueueTimeMinute = yaml.concurrency?.queueTimeoutMinutes ?: TimeUnit.HOURS.toMinutes(8).toInt(), + // #6090 stream重试时均需要清理变量表 + cleanVariablesWhenRetry = true, + maxQueueSize = yaml.concurrency?.queueLength ?: 1, + labels = yaml2Labels(yamlInput), + pipelineAsCodeSettings = yamlInput.asCodeSettings + ) + } + + fun yaml2Model( + yamlInput: YamlTransferInput + ): Model { + + val stageList = mutableListOf() + + // 蓝盾引擎会将stageId从1开始顺序强制重写,因此在生成model时保持一致 + var stageIndex = 1 + // todo 需要trigger on + stageList.add(modelStage.yaml2TriggerStage(yamlInput, stageIndex++)) + + // 其他的stage + yamlInput.yaml.formatStages().forEach { stage -> + stageList.add( + modelStage.yaml2Stage( + stage = stage, + // stream的stage标号从1开始,后续都加1 + stageIndex = stageIndex++, + yamlInput = yamlInput + ) + ) + } + // 添加finally + val finallyJobs = yamlInput.yaml.formatFinallyStage() + if (finallyJobs.isNotEmpty()) { + stageList.add( + modelStage.yaml2FinallyStage( + stageIndex = stageIndex, + finallyJobs = finallyJobs, + yamlInput = yamlInput + ) + ) + } + + return Model( + name = yamlInput.yaml.name ?: "", + desc = "", + stages = stageList, + labels = emptyList(), + instanceFromTemplate = false, + pipelineCreator = yamlInput.userId + ) + } + + fun model2yaml(modelInput: ModelTransferInput): PreScriptBuildYamlI { + val stages = mutableListOf() + modelInput.model.stages.forEachIndexed { index, stage -> + if (index == 0 || stage.finally) return@forEachIndexed + val ymlStage = modelStage.model2YamlStage(stage) + stages.add(ymlStage) + } + val label = modelInput.model.labels.ifEmpty { null } + val triggerOn = getTriggerOn(modelInput.model) + val variables = getVariableFromModel(modelInput.model) + val finally = modelStage.model2YamlStage(modelInput.model.stages.last()).jobs + val concurrency = getConcurrency(modelInput.setting) + val notices = ""// TODO: 2023/7/17 + + return when (modelInput.version) { + YamlVersion.Version.V2_0 -> PreScriptBuildYaml( + version = "v2.0", + name = modelInput.model.name, + label = label, + triggerOn = triggerOn[modelInput.defaultScmType]?.toPreV2(), + variables = variables, + stages = stages, + extends = null, + resources = null, + notices = null, + finally = finally, + concurrency = concurrency + ) + YamlVersion.Version.V3_0 -> PreScriptBuildYamlV3( + version = "v3.0", + name = modelInput.model.name, + label = label, + triggerOn = triggerOn.map { it.value.toPreV3() }, + variables = variables, + stages = stages, + extends = null, + resources = null, + notices = null, + finally = finally, + concurrency = concurrency + ) + } + } + + private fun getNotices(setting: PipelineSetting): List { + return emptyList() + } + + private fun getConcurrency(setting: PipelineSetting): Concurrency? { + if (setting.runLockType == PipelineRunLockType.GROUP_LOCK) { + return Concurrency( + group = setting.concurrencyGroup, + cancelInProgress = setting.concurrencyCancelInProgress, + queueLength = setting.maxQueueSize, + queueTimeoutMinutes = setting.waitQueueTimeMinute + ) + } + return null + } + + private fun getTriggerOn(model: Model): Map { + val triggers = (model.stages[0].containers[0] as TriggerContainer).elements + return modelElement.triggers2Yaml(triggers) + } + + private fun getVariableFromModel(model: Model): Map? { + val result = mutableMapOf() + (model.stages[0].containers[0] as TriggerContainer).params.forEach { + // todo 启动参数需要更详细的解析 + result[it.id] = Variable(it.defaultValue.toString()) + } + return if (result.isEmpty()) { + null + } else { + result + } + } + + @Suppress("NestedBlockDepth") + private fun preparePipelineLabels( + userId: String, + projectCode: String, + yaml: IPreTemplateScriptBuildYaml + ): List { + val gitCIPipelineLabels = mutableListOf() + + try { + // 获取当前项目下存在的标签组 + val pipelineGroups = client.get(UserPipelineGroupResource::class) + .getGroups(userId, projectCode) + .data + + yaml.label?.forEach { + // 要设置的标签组不存在,新建标签组和标签(同名) + if (!checkPipelineLabel(it, pipelineGroups)) { + client.get(UserPipelineGroupResource::class).addGroup( + userId, + PipelineGroupCreate( + projectId = projectCode, + name = it + ) + ) + + val pipelineGroup = getPipelineGroup(it, userId, projectCode) + if (pipelineGroup != null) { + client.get(UserPipelineGroupResource::class).addLabel( + userId = userId, + projectId = projectCode, + pipelineLabel = PipelineLabelCreate( + groupId = pipelineGroup.id, + name = it + ) + ) + } + } + + // 保证标签已创建成功后,取label加密ID + val pipelineGroup = getPipelineGroup(it, userId, projectCode) + gitCIPipelineLabels.add(pipelineGroup!!.labels[0].id) + } + } catch (e: Exception) { + logger.warn("$userId|$projectCode preparePipelineLabels error.", e) + } + + return gitCIPipelineLabels + } + + private fun checkPipelineLabel(gitciPipelineLabel: String, pipelineGroups: List?): Boolean { + pipelineGroups?.forEach { pipelineGroup -> + pipelineGroup.labels.forEach { + if (it.name == gitciPipelineLabel) { + return true + } + } + } + + return false + } + + private fun getPipelineGroup(labelGroupName: String, userId: String, projectId: String): PipelineGroup? { + val pipelineGroups = client.get(UserPipelineGroupResource::class) + .getGroups(userId, projectId) + .data + pipelineGroups?.forEach { + if (it.name == labelGroupName) { + return it + } + } + + return null + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt new file mode 100644 index 00000000000..b1e6b8a3069 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt @@ -0,0 +1,331 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.modelTransfer + +import com.fasterxml.jackson.databind.ObjectMapper +import com.tencent.devops.common.api.constant.CommonMessageCode +import com.tencent.devops.common.client.Client +import com.tencent.devops.common.pipeline.container.Container +import com.tencent.devops.common.pipeline.container.NormalContainer +import com.tencent.devops.common.pipeline.container.Stage +import com.tencent.devops.common.pipeline.container.TriggerContainer +import com.tencent.devops.common.pipeline.container.VMBuildContainer +import com.tencent.devops.common.pipeline.enums.BuildFormPropertyType +import com.tencent.devops.common.pipeline.enums.StageRunCondition +import com.tencent.devops.common.pipeline.option.StageControlOption +import com.tencent.devops.common.pipeline.pojo.BuildFormProperty +import com.tencent.devops.common.pipeline.pojo.StagePauseCheck +import com.tencent.devops.common.pipeline.pojo.StageReviewGroup +import com.tencent.devops.common.pipeline.pojo.element.Element +import com.tencent.devops.common.pipeline.pojo.element.atom.ManualReviewParam +import com.tencent.devops.common.pipeline.pojo.element.atom.ManualReviewParamPair +import com.tencent.devops.common.pipeline.pojo.element.atom.ManualReviewParamType +import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.process.engine.common.VMUtils +import com.tencent.devops.process.yaml.modelCreate.ModelCommon +import com.tencent.devops.process.yaml.modelCreate.ModelContainer +import com.tencent.devops.process.yaml.modelCreate.ModelCreateException +import com.tencent.devops.process.yaml.modelTransfer.pojo.YamlTransferInput +import com.tencent.devops.process.yaml.utils.ModelCreateUtil +import com.tencent.devops.process.yaml.v2.models.Variable +import com.tencent.devops.process.yaml.v2.models.job.Job +import com.tencent.devops.process.yaml.v2.models.job.JobRunsOnType +import com.tencent.devops.process.yaml.v2.models.stage.PreStage +import com.tencent.devops.process.yaml.v2.stageCheck.PreFlow +import com.tencent.devops.process.yaml.v2.stageCheck.PreStageCheck +import com.tencent.devops.process.yaml.v2.stageCheck.PreStageReviews +import com.tencent.devops.process.yaml.v2.stageCheck.ReviewVariable +import com.tencent.devops.process.yaml.v2.stageCheck.StageCheck +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component +import com.tencent.devops.process.yaml.v2.models.stage.Stage as StreamV2Stage + +@Component +class StageTransfer @Autowired(required = false) constructor( + val client: Client, + val objectMapper: ObjectMapper, + val modelContainer: ModelContainer, + val modelElement: ElementTransfer +) { + companion object { + private val logger = LoggerFactory.getLogger(StageTransfer::class.java) + private const val VARIABLE_PREFIX = "variables." + } + + fun yaml2TriggerStage(yamlInput: YamlTransferInput, stageIndex: Int): Stage { + // 第一个stage,触发类 + val triggerElementList = mutableListOf() + modelElement.yaml2Triggers(yamlInput.yaml.formatTriggerOn(yamlInput.defaultScmType), triggerElementList) + + val triggerContainer = TriggerContainer( + id = "0", + name = I18nUtil.getCodeLanMessage(CommonMessageCode.BK_BUILD_MSG_TRIGGERS), + elements = triggerElementList, + status = null, + startEpoch = null, + systemElapsed = null, + elementElapsed = null, + params = getBuildFormPropertyFromYmlVariable(yamlInput.yaml.formatVariables()) + ) + + val stageId = VMUtils.genStageId(stageIndex) + return Stage(listOf(triggerContainer), id = stageId, name = stageId) + } + + fun yaml2FinallyStage( + stageIndex: Int, + finallyJobs: List, + yamlInput: YamlTransferInput, + ): Stage { + return yaml2Stage( + stage = StreamV2Stage( + name = "Finally", + label = emptyList(), + ifField = null, + fastKill = false, + jobs = finallyJobs, + checkIn = null, + checkOut = null + ), + stageIndex = stageIndex, + yamlInput = yamlInput, + finalStage = true + ) + } + + fun yaml2Stage( + stage: StreamV2Stage, + stageIndex: Int, + yamlInput: YamlTransferInput, + finalStage: Boolean = false + ): Stage { + val containerList = mutableListOf() + + stage.jobs.forEachIndexed { jobIndex, job -> + val elementList = modelElement.yaml2Elements( + job = job, + yamlInput = yamlInput + ) + + if (job.runsOn.poolName == JobRunsOnType.AGENT_LESS.type) { + modelContainer.addNormalContainer( + job = job, + elementList = elementList, + containerList = containerList, + jobIndex = jobIndex, + finalStage = finalStage + ) + } else { + modelContainer.addVmBuildContainer( + job = job, + elementList = elementList, + containerList = containerList, + jobIndex = jobIndex, + projectCode = yamlInput.projectCode, + finalStage = finalStage, + resources = yamlInput.yaml.formatResources(), + buildTemplateAcrossInfo = yamlInput.jobTemplateAcrossInfo?.get(job.id) + ) + } + } + + // 根据if设置stageController + val stageControlOption = if (!finalStage && !stage.ifField.isNullOrBlank()) { + StageControlOption( + runCondition = StageRunCondition.CUSTOM_CONDITION_MATCH, + customCondition = ModelCreateUtil.removeIfBrackets(stage.ifField.toString()) + ) + } else StageControlOption() + + val stageId = VMUtils.genStageId(stageIndex) + return Stage( + id = stageId, + name = stage.name ?: if (finalStage) { + "Final" + } else { + VMUtils.genStageId(stageIndex - 1) + }, + tag = stage.label, + fastKill = stage.fastKill, + stageControlOption = stageControlOption, + containers = containerList, + finally = finalStage, + checkIn = createStagePauseCheck( + stageCheck = stage.checkIn + ), + checkOut = createStagePauseCheck( + stageCheck = stage.checkOut + ) + ) + } + + fun model2YamlStage( + stage: Stage + ): PreStage { + val jobs = stage.containers.associate { job -> + + val steps = modelElement.model2YamlSteps(job) + + (job.jobId ?: "job_${job.id}") to when (job.getClassType()) { + NormalContainer.classType -> modelContainer.addYamlNormalContainer(job as NormalContainer, steps) + VMBuildContainer.classType -> modelContainer.addYamlVMBuildContainer(job as VMBuildContainer, steps) + else -> throw ModelCreateException("unknown classType:(${job.getClassType()})") + } + } + return PreStage( + name = stage.name, + label = stage.tag?.ifEmpty { null }, + ifField = when (stage.stageControlOption?.runCondition) { + StageRunCondition.CUSTOM_CONDITION_MATCH -> stage.stageControlOption?.customCondition + StageRunCondition.CUSTOM_VARIABLE_MATCH -> ModelCommon.customVariableMatch( + stage.stageControlOption?.customVariables + ) + StageRunCondition.CUSTOM_VARIABLE_MATCH_NOT_RUN -> ModelCommon.customVariableMatchNotRun( + stage.stageControlOption?.customVariables + ) + else -> null + }, + fastKill = if (stage.fastKill == true) true else null, + jobs = jobs, + checkIn = getCheckInForStage(stage), + // TODO 暂时不支持准出和gates的导出 + checkOut = null + ) + } + + private fun getCheckInForStage(stage: Stage): PreStageCheck? { + val reviews = PreStageReviews( + flows = stage.checkIn?.reviewGroups?.map { PreFlow(it.name, it.reviewers) }, + variables = stage.checkIn?.reviewParams?.associate { + it.key to ReviewVariable( + label = it.chineseName ?: it.key, + type = when (it.valueType) { + ManualReviewParamType.TEXTAREA -> "TEXTAREA" + ManualReviewParamType.ENUM -> "SELECTOR" + ManualReviewParamType.MULTIPLE -> "SELECTOR-MULTIPLE" + ManualReviewParamType.BOOLEAN -> "BOOL" + else -> "INPUT" + }, + default = it.value, + values = it.options?.map { mit -> mit.key }, + description = it.desc + ) + }, + description = stage.checkIn?.reviewDesc + ) + if (reviews.flows.isNullOrEmpty()) { + return null + } + return PreStageCheck( + reviews = reviews, + gates = null, + timeoutHours = stage.checkIn?.timeout + ) + } + + private fun createStagePauseCheck( + stageCheck: StageCheck? + ): StagePauseCheck? { + if (stageCheck == null) return null + val check = StagePauseCheck() + check.timeout = stageCheck.timeoutHours + if (stageCheck.reviews?.flows?.isNotEmpty() == true) { + check.manualTrigger = true + check.reviewDesc = stageCheck.reviews.description + check.reviewParams = createReviewParams(stageCheck.reviews.variables) + check.reviewGroups = stageCheck.reviews.flows.map { + StageReviewGroup( + name = it.name, + reviewers = ModelCommon.parseReceivers(it.reviewers).toList() + ) + }.toMutableList() + } + return check + } + + private fun createReviewParams(variables: Map?): List? { + if (variables.isNullOrEmpty()) return null + val params = mutableListOf() + variables.forEach { (key, variable) -> + params.add( + ManualReviewParam( + key = "variables.$key", + value = variable.default, + required = true, + valueType = when (variable.type) { + "TEXTAREA" -> ManualReviewParamType.TEXTAREA + "SELECTOR" -> ManualReviewParamType.ENUM + "SELECTOR-MULTIPLE" -> ManualReviewParamType.MULTIPLE + "BOOL" -> ManualReviewParamType.BOOLEAN + else -> ManualReviewParamType.STRING + }, + chineseName = variable.label, + desc = variable.description, + options = (variable.values.takeIf { it is List<*>? } as List<*>?)?.map { + ManualReviewParamPair( + it.toString(), + it.toString() + ) + }, + variableOption = variable.values.takeIf { it is String? } as String? + ) + ) + } + return params + } + + private fun getBuildFormPropertyFromYmlVariable( + variables: Map? + ): List { + if (variables.isNullOrEmpty()) { + return emptyList() + } + val buildFormProperties = mutableListOf() + variables.forEach { (key, variable) -> + buildFormProperties.add( + BuildFormProperty( + id = key, + required = false, + type = BuildFormPropertyType.STRING, + defaultValue = variable.value ?: "", + options = null, + desc = null, + repoHashId = null, + relativePath = null, + scmType = null, + containerType = null, + glob = null, + properties = null, + readOnly = variable.readonly + ) + ) + } + return buildFormProperties + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferCacheService.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferCacheService.kt new file mode 100644 index 00000000000..c50eb117e85 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferCacheService.kt @@ -0,0 +1,52 @@ +package com.tencent.devops.process.yaml.modelTransfer + +import com.github.benmanes.caffeine.cache.Caffeine +import com.tencent.devops.common.client.Client +import com.tencent.devops.store.api.atom.ServiceMarketAtomResource +import com.tencent.devops.store.api.image.service.ServiceStoreImageResource +import com.tencent.devops.store.pojo.atom.ElementThirdPartySearchParam +import com.tencent.devops.store.pojo.image.response.ImageRepoInfo +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Service +import java.util.concurrent.TimeUnit + +@Service +class TransferCacheService @Autowired constructor( + private val client: Client +) { + + companion object { + private val logger = LoggerFactory.getLogger(TransferCacheService::class.java) + } + + private val atomDefaultValueCache = Caffeine.newBuilder() + .maximumSize(1000) + .expireAfterWrite(1, TimeUnit.DAYS) + .build> { key -> + kotlin.runCatching { + val (atomCode, version) = key.split("@") + client.get(ServiceMarketAtomResource::class) + .getAtomsDefaultValue(ElementThirdPartySearchParam(atomCode, version)).data + }.onFailure { logger.warn("get $key default value error.") }.getOrNull() ?: emptyMap() + } + + private val storeImageInfoCache = Caffeine.newBuilder() + .maximumSize(1000) + .expireAfterWrite(1, TimeUnit.DAYS) + .build { key -> + kotlin.runCatching { + val (imageCode, imageVersion) = key.split("@@") + client.get(ServiceStoreImageResource::class) + .getImageInfoByCodeAndVersion( + imageCode = imageCode, + imageVersion = imageVersion + ).data + }.onFailure { logger.warn("get $key default value error.") }.getOrNull() + } + + fun getAtomDefaultValue(key: String) = atomDefaultValueCache.get(key) ?: emptyMap() + + fun getStoreImageInfo(imageCode: String, imageVersion: String?) = + storeImageInfoCache.get("$imageCode@@${imageVersion ?: ""}") +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferMapper.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferMapper.kt new file mode 100644 index 00000000000..fe5ef96307a --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferMapper.kt @@ -0,0 +1,488 @@ +package com.tencent.devops.process.yaml.modelTransfer + +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.core.io.IOContext +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter +import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory +import com.fasterxml.jackson.dataformat.yaml.YAMLFactoryBuilder +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator +import com.fasterxml.jackson.dataformat.yaml.util.StringQuotingChecker +import com.fasterxml.jackson.module.kotlin.registerKotlinModule +import com.github.difflib.DiffUtils +import com.github.difflib.algorithm.myers.MeyersDiffWithLinearSpace +import com.github.difflib.patch.DeltaType +import com.tencent.devops.common.api.util.JsonUtil +import com.tencent.devops.common.api.util.ReflectUtil +import com.tencent.devops.process.pojo.transfer.TransferMark +import com.tencent.devops.process.yaml.v2.models.YAME_META_DATA_JSON_FILTER +import org.json.JSONArray +import org.json.JSONObject +import org.yaml.snakeyaml.DumperOptions +import org.yaml.snakeyaml.LoaderOptions +import org.yaml.snakeyaml.Yaml +import org.yaml.snakeyaml.composer.Composer +import org.yaml.snakeyaml.constructor.SafeConstructor +import org.yaml.snakeyaml.events.Event +import org.yaml.snakeyaml.events.NodeEvent +import org.yaml.snakeyaml.nodes.AnchorNode +import org.yaml.snakeyaml.nodes.MappingNode +import org.yaml.snakeyaml.nodes.Node +import org.yaml.snakeyaml.nodes.NodeId +import org.yaml.snakeyaml.nodes.NodeTuple +import org.yaml.snakeyaml.nodes.ScalarNode +import org.yaml.snakeyaml.nodes.SequenceNode +import org.yaml.snakeyaml.nodes.Tag +import org.yaml.snakeyaml.parser.Parser +import org.yaml.snakeyaml.representer.Representer +import org.yaml.snakeyaml.resolver.Resolver +import org.yaml.snakeyaml.serializer.AnchorGenerator +import java.io.StringWriter +import java.io.Writer +import java.util.function.Supplier +import java.util.regex.Pattern + +object TransferMapper { + + /** + * 重写StringQuotingChecker 以支持on关键字特性 + */ + class CustomStringQuotingChecker : StringQuotingChecker() { + override fun needToQuoteName(name: String): Boolean { + // 自定义字符串引号检查逻辑 + return reservedKeyword(name) || looksLikeYAMLNumber(name) + } + + override fun needToQuoteValue(value: String): Boolean { + // Only consider reserved keywords but not numbers? + return isReservedKeyword(value) || valueHasQuotableChar(value) + } + + /* + *重写此处逻辑,以兼容对on关键字的特殊用法 + */ + private fun reservedKeyword(value: String): Boolean { + if (value == "on") return false + return if (value.isEmpty()) { + true + } else _isReservedKeyword(value[0].code, value) + } + } + + /* + * 实现Parser接口,以支持由events生成yaml node + * */ + class CustomParser(private val events: List) : Parser { + var idx = 0 + private var currentEvent: Event? = null + override fun checkEvent(choice: Event.ID): Boolean { + peekEvent() + return currentEvent != null && currentEvent?.`is`(choice) == true + } + + override fun peekEvent(): Event? { + if (currentEvent == null) { + currentEvent = events[idx++] + } + return currentEvent + } + + override fun getEvent(): Event? { + peekEvent() + val value = currentEvent + currentEvent = null + return value + } + } + + /* + * Parser 的空实现 + * */ + class EmptyParser : Parser { + override fun checkEvent(choice: Event.ID): Boolean { + return true + } + + override fun peekEvent(): Event? { + return null + } + + override fun getEvent(): Event? { + return null + } + } + + private val BOOL_PATTERN = Pattern + .compile("^(?:yes|Yes|YES|no|No|NO|true|True|TRUE|false|False|FALSE|On|ON|off|Off|OFF)$") + + private val resolver = object : Resolver() { + + override fun addImplicitResolver(tag: Tag, regexp: Pattern, first: String?) { + if (tag == Tag.BOOL) { + super.addImplicitResolver(tag, BOOL_PATTERN, first) + } else { + super.addImplicitResolver(tag, regexp, first) + } + } + } + + private val dumper = DumperOptions().apply { + this.isPrettyFlow = false + this.splitLines = false + this.defaultScalarStyle = DumperOptions.ScalarStyle.LITERAL + this.defaultFlowStyle = DumperOptions.FlowStyle.FLOW + this.isAllowReadOnlyProperties = true + this.isProcessComments = true + this.anchorGenerator = CustomAnchorGenerator() + } + + private val loader = LoaderOptions().apply { + this.isProcessComments = true + } + + private fun eventsComposer(events: List) = Composer( + CustomParser(events), Resolver(), loader + ) + + private val constructor = SafeConstructor(loader) + private fun node2JsonString(node: Node): String { + constructor.setComposer( + object : Composer( + EmptyParser(), Resolver(), loader + ) { + override fun getSingleNode(): Node { + return node + } + } + ) + val res = constructor.getSingleData(Any::class.java) + return JsonUtil.toJson(res, false) + } + + private fun checkCommentEvent(comments: List): List { + var index = comments.size + for (i in (comments.size - 1) downTo 0) { + if (comments[i].eventId != Event.ID.Comment) { + break + } + index = i + } + return comments.subList(index, comments.size) + } + + private fun anchorNode(node: Node, anchors: MutableMap) { + var realNode = node + if (node.nodeId == NodeId.anchor) { + realNode = (node as AnchorNode).realNode + } + if (realNode.anchor != null) { + anchors[realNode.anchor] = realNode + } + when (realNode.nodeId) { + NodeId.sequence -> { + val seqNode = realNode as SequenceNode + val list = seqNode.value + for (item in list) { + anchorNode(item, anchors) + } + } + NodeId.mapping -> { + val mNode = realNode as MappingNode + val map = mNode.value + for (obj in map) { + val key = obj.keyNode + val value = obj.valueNode + anchorNode(key, anchors) + anchorNode(value, anchors) + } + } + } + } + + /** + * @param node 当前需要做替换的节点 + * @param anchors 锚点信息 + */ + private fun replaceAnchor(node: Node, anchors: Map) { + when (node.nodeId) { + NodeId.scalar -> {} + NodeId.anchor -> {} + NodeId.sequence -> { + val seqNode = node as SequenceNode + val list = seqNode.value + for (item in list) { + replaceAnchor(item, anchors) + } + if (node.anchor != null) return + anchors.forEach { (key, n) -> + if (n !is SequenceNode) return@forEach + if (exactlyTheSameNode(node, n)) { + node.anchor = key + return@forEach + } + } + } + NodeId.mapping -> { + val mNode = node as MappingNode + val map = mNode.value + for (obj in map) { + val key = obj.keyNode + val value = obj.valueNode + replaceAnchor(key, anchors) + replaceAnchor(value, anchors) + } + if (node.anchor != null) return + anchors.forEach anchors@{ key, n -> + if (n !is MappingNode) return@anchors + val needRemove = mutableListOf() + // key 需要全部有 + n.value.forEach value@{ v -> + val index = map.find { + it.keyNode is ScalarNode && + v.keyNode is ScalarNode && + (it.keyNode as ScalarNode).value == (v.keyNode as ScalarNode).value + } ?: return@anchors + + if (exactlyTheSameNode(index.valueNode, v.valueNode)) { + needRemove.add(index) + } + } + // value相同的去掉 + map.removeAll(needRemove) + map.add( + NodeTuple( + ScalarNode( + /* tag = */ Tag.MERGE, + /* value = */ "<<", + /* startMark = */ n.startMark, + /* endMark = */ n.endMark, + /* style = */ DumperOptions.ScalarStyle.PLAIN + ), n + ) + ) + } + } + } + } + + private fun exactlyTheSameNode(l: Node, r: Node): Boolean { + if (l.nodeId != r.nodeId) return false + + when (l.nodeId) { + NodeId.scalar -> { + val ln = l as ScalarNode + val rn = r as ScalarNode + if (ln.value != rn.value) return false + } + NodeId.sequence -> { + val ls = node2JsonString(l) + val rs = node2JsonString(r) + return JSONArray(ls).similar(JSONArray(rs)) + } + NodeId.mapping -> { + val ls = node2JsonString(l) + val rs = node2JsonString(r) + return JSONObject(ls).similar(JSONObject(rs)) + } + NodeId.anchor -> { + val ln = l as AnchorNode + val rn = r as AnchorNode + return exactlyTheSameNode(ln.realNode, rn.realNode) + } + } + return true + } + + /** + * 重写YAMLFactory 以支持一些yaml规范外的特性 + */ + private val CustomYAMLFactoryBuilder = object : YAMLFactoryBuilder() { + override fun build(): YAMLFactory { + return object : YAMLFactory(this) { + override fun _createGenerator(out: Writer, ctxt: IOContext): YAMLGenerator { + val feats = _yamlGeneratorFeatures + return object : YAMLGenerator( + ctxt, _generatorFeatures, feats, + _quotingChecker, _objectCodec, out, _version + ) { + override fun writeString(text: String) { + super.writeString(removeTrailingSpaces(text)) + } + + /* + * 去掉换行符前的空格,以支持yaml block输出 + * */ + private fun removeTrailingSpaces(text: String): String { + val result = StringBuilder(text.length) + var start = 0 + var end = 0 + val chars = text.toCharArray() + + while (end < chars.size) { + if (chars[end] == '\n') { + val line = chars.sliceArray(start until end) + var endIdx = end - start - 1 + while (endIdx >= 0 && line[endIdx] == ' ') { + endIdx-- + } + result.append(line.sliceArray(0 until endIdx + 1)) + result.append('\n') + start = end + 1 + } + end++ + } + + if (start < chars.size) { + val line = chars.sliceArray(start until chars.size) + var endIdx = end - start - 1 + while (endIdx >= 0 && line[endIdx] == ' ') { + endIdx-- + } + result.append(line.sliceArray(0 until endIdx + 1)) + } + return result.toString() + } + } + } + } + } + } + + private val yamlObjectMapper = ObjectMapper( + CustomYAMLFactoryBuilder.enable(YAMLGenerator.Feature.LITERAL_BLOCK_STYLE) + .enable(YAMLGenerator.Feature.MINIMIZE_QUOTES) + .disable(YAMLGenerator.Feature.SPLIT_LINES) + .stringQuotingChecker(CustomStringQuotingChecker()).build() + ).setSerializationInclusion(JsonInclude.Include.NON_NULL).apply { + registerKotlinModule().setFilterProvider( + SimpleFilterProvider().addFilter( + YAME_META_DATA_JSON_FILTER, + SimpleBeanPropertyFilter.serializeAllExcept(YAME_META_DATA_JSON_FILTER) + ) + ) + } + + /* + * 默认锚点命名生成规则是重命名。而预期的行为是不改变原有锚点命名。 + * 所以此处重写AnchorGenerator方法,对锚点不进行重命名 + * */ + class CustomAnchorGenerator : AnchorGenerator { + override fun nextAnchor(node: Node): String { + return node.anchor + } + } + + private val yamlFactory = ThreadLocal.withInitial( + Supplier { + Yaml(SafeConstructor(loader), Representer(dumper), dumper, loader, resolver) + } + ) + + private fun parseMappingNodeIndex(node: MappingNode): Map { + val res = mutableMapOf() + node.value.forEach { nodeTuple -> + if (nodeTuple.keyNode.nodeId != NodeId.scalar) return@forEach + val kn = nodeTuple.keyNode as ScalarNode + res[kn.value] = TransferMark( + startMark = TransferMark.Mark( + nodeTuple.valueNode.startMark.line, nodeTuple.valueNode.startMark.column + ), + endMark = TransferMark.Mark( + nodeTuple.valueNode.endMark.line, nodeTuple.valueNode.endMark.column + ) + ) + } + return res + } + + fun getYamlFactory(): Yaml = yamlFactory.get() + + fun getObjectMapper(): ObjectMapper = yamlObjectMapper + + fun toYaml(bean: Any): String { + if (ReflectUtil.isNativeType(bean) || bean is String) { + return bean.toString() + } + return getObjectMapper().writeValueAsString(bean)!! + } + + /** + * 获得 yaml 第一层级的坐标定位信息 + */ + fun getYamlLevelOneIndex(yaml: String): Map { + val node = getYamlFactory().compose(yaml.reader()) + if (node.nodeId != NodeId.mapping) return emptyMap() + return parseMappingNodeIndex(node as MappingNode) + } + + /* + * yaml合并入口 + * 将minor中的内容融合进main中。 + * 融合策略: + * 1.保留注释信息 + * 2.保留锚点信息 + * */ + fun mergeYaml(old: String, new: String): String { + + val oldE = getYamlFactory().parse(old.reader()).toList() + val newL = getYamlFactory().parse(new.reader()).toList() + val newE = newL.toMutableList() + + val patch = DiffUtils.diff(oldE, newE, MeyersDiffWithLinearSpace.factory().create()) + val anchorChecker = mutableMapOf() + for (i in (patch.deltas.size - 1) downTo 0) { + val delta = patch.deltas[i] + when (delta.type) { + DeltaType.INSERT -> { + anchorChecker[delta.source.position]?.let { checker -> + delta.target.lines.forEachIndexed { index, event -> + if (event.eventId == checker.eventId) { + newE[delta.target.position + index] = checker + } + } + } + } + DeltaType.DELETE -> { + val sourceComment = checkCommentEvent(delta.source.lines) + if (sourceComment.isNotEmpty()) { + newE.addAll(delta.target.position, sourceComment) + } + // 锚点覆写逻辑 + delta.source.lines.forEachIndexed { index, event -> + if (event !is NodeEvent) return@forEachIndexed + if (event.anchor != null) { + anchorChecker[delta.source.position + index] = event + } + } + } + } + } + + val newNode = eventsComposer(newE).singleNode + val anchorNodes = mutableMapOf() + anchorNode(newNode, anchorNodes) + if (anchorNodes.isNotEmpty()) { + replaceAnchor(newNode, anchorNodes) + } + + val stringWriter = StringWriter() + + getYamlFactory().serialize(newNode, stringWriter) + + val out = stringWriter.toString() + +// if (!exactlyTheSameNode(eventsComposer(newL).singleNode, newNode)) { +// throw Exception("not same node") +// } + if (!exactlyTheSameNode(getYamlFactory().compose(new.reader()), getYamlFactory().compose(out.reader()))) { + throw Exception("not same node") + } + return out + } + + fun formatYaml(yaml: String): String { + val res = getYamlFactory().load(yaml) as Any + return toYaml(res) + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt new file mode 100644 index 00000000000..4fe796f47b3 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt @@ -0,0 +1,494 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.modelTransfer + +import com.tencent.devops.common.api.constant.CommonMessageCode +import com.tencent.devops.common.api.enums.RepositoryType +import com.tencent.devops.common.client.Client +import com.tencent.devops.common.pipeline.pojo.element.Element +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGitWebHookTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGithubWebHookTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeTGitWebHookTriggerData +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeTGitWebHookTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeTGitWebHookTriggerInput +import com.tencent.devops.common.pipeline.pojo.element.trigger.ManualTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.enums.CodeEventType +import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.process.yaml.modelTransfer.inner.TransferModelCreator +import com.tencent.devops.process.yaml.modelTransfer.pojo.WebHookTriggerElementChanger +import com.tencent.devops.process.yaml.v2.models.on.IssueRule +import com.tencent.devops.process.yaml.v2.models.on.MrRule +import com.tencent.devops.process.yaml.v2.models.on.NoteRule +import com.tencent.devops.process.yaml.v2.models.on.PushRule +import com.tencent.devops.process.yaml.v2.models.on.ReviewRule +import com.tencent.devops.process.yaml.v2.models.on.TagRule +import com.tencent.devops.process.yaml.v2.models.on.TriggerOn +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component + +@Component +class TriggerTransfer @Autowired(required = false) constructor( + val client: Client, + @Autowired(required = false) + val creator: TransferModelCreator, + val transferCache: TransferCacheService +) { + companion object { + private val logger = LoggerFactory.getLogger(TriggerTransfer::class.java) + } + + @Suppress("ComplexMethod") + fun yaml2TriggerGit(triggerOn: TriggerOn, elementQueue: MutableList) { + if (triggerOn.manual != "disabled") { + elementQueue.add( + ManualTriggerElement( + I18nUtil.getCodeLanMessage(CommonMessageCode.BK_BUILD_MSG_MANUAL), + "T-1-1-1" + ) + ) + } + + triggerOn.push?.let { push -> + elementQueue.add( + CodeGitWebHookTriggerElement( + branchName = push.branches.nonEmptyOrNull()?.join(), + excludeBranchName = push.branchesIgnore.nonEmptyOrNull()?.join(), + includePaths = push.paths.nonEmptyOrNull()?.join(), + excludePaths = push.pathsIgnore.nonEmptyOrNull()?.join(), + includeUsers = push.users, + excludeUsers = push.usersIgnore, + eventType = CodeEventType.PUSH, + // todo action + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + } + + triggerOn.tag?.let { tag -> + elementQueue.add( + CodeGitWebHookTriggerElement( + tagName = tag.tags.nonEmptyOrNull()?.join(), + excludeTagName = tag.tagsIgnore.nonEmptyOrNull()?.join(), + fromBranches = tag.fromBranches.nonEmptyOrNull()?.join(), + includeUsers = tag.users, + excludeUsers = tag.usersIgnore, + eventType = CodeEventType.TAG_PUSH, + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + } + + triggerOn.mr?.let { mr -> + elementQueue.add( + CodeGitWebHookTriggerElement( + branchName = mr.targetBranches.nonEmptyOrNull()?.join(), + excludeBranchName = mr.targetBranchesIgnore.nonEmptyOrNull()?.join(), + includeSourceBranchName = mr.sourceBranches.nonEmptyOrNull()?.join(), + excludeSourceBranchName = mr.sourceBranchesIgnore.nonEmptyOrNull()?.join(), + includePaths = mr.paths.nonEmptyOrNull()?.join(), + excludePaths = mr.pathsIgnore.nonEmptyOrNull()?.join(), + includeUsers = mr.users, + excludeUsers = mr.usersIgnore, + block = mr.block, + webhookQueue = mr.webhookQueue, + enableCheck = mr.enableCheck, + // todo action + eventType = CodeEventType.MERGE_REQUEST, + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + } + + triggerOn.review?.let { review -> + elementQueue.add( + CodeGitWebHookTriggerElement( + includeCrState = review.states, + includeCrTypes = review.types, + eventType = CodeEventType.REVIEW, + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + } + + triggerOn.issue?.let { issue -> + elementQueue.add( + CodeGitWebHookTriggerElement( + includeIssueAction = issue.action, + eventType = CodeEventType.ISSUES, + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + } + + triggerOn.note?.let { note -> + elementQueue.add( + CodeGitWebHookTriggerElement( + includeNoteTypes = note.types?.map { + when (it) { + "commit" -> "Commit" + "merge_request" -> "Review" + "issue" -> "Issue" + else -> it + } + }, + includeNoteComment = note.comment.nonEmptyOrNull()?.join(), + eventType = CodeEventType.NOTE, + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + } + } + + @Suppress("ComplexMethod") + fun git2YamlTriggerOn(elements: List): List { + val fix = elements.groupBy { + when (it.repositoryType) { + RepositoryType.ID -> it.repositoryHashId ?: "" + RepositoryType.NAME -> it.repositoryName ?: "" + else -> "" + } + } + val res = mutableMapOf() + fix.forEach { (name, group) -> + group.forEach { git -> + val nowExist = res.getOrPut(name) { + when (name) { + git.repositoryHashId -> TriggerOn(repoHashId = name) + git.repositoryName -> TriggerOn(name = name) + else -> TriggerOn() + } + } + when (git.eventType) { + CodeEventType.PUSH -> nowExist.push = PushRule( + branches = git.branchName?.disjoin() ?: emptyList(), + branchesIgnore = git.excludeBranchName?.disjoin(), + paths = git.includePaths?.disjoin(), + pathsIgnore = git.excludePaths?.disjoin(), + users = git.includeUsers, + usersIgnore = git.excludeUsers, + // todo action + action = null + ) + CodeEventType.TAG_PUSH -> nowExist.tag = TagRule( + tags = git.tagName?.disjoin(), + tagsIgnore = git.excludeTagName?.disjoin(), + fromBranches = git.fromBranches?.disjoin(), + users = git.includeUsers, + usersIgnore = git.excludeUsers + ) + CodeEventType.MERGE_REQUEST -> nowExist.mr = MrRule( + targetBranches = git.branchName?.disjoin(), + targetBranchesIgnore = git.excludeBranchName?.disjoin(), + sourceBranches = git.includeSourceBranchName?.disjoin(), + sourceBranchesIgnore = git.excludeSourceBranchName?.disjoin(), + paths = git.includePaths?.disjoin(), + pathsIgnore = git.excludePaths?.disjoin(), + users = git.includeUsers, + usersIgnore = git.excludeUsers, + block = git.block, + webhookQueue = git.webhookQueue, + enableCheck = git.enableCheck, + // todo action + action = null + ) + CodeEventType.REVIEW -> nowExist.review = ReviewRule( + states = git.includeCrState, + types = git.includeCrTypes + ) + CodeEventType.ISSUES -> nowExist.issue = IssueRule( + action = git.includeIssueAction + ) + CodeEventType.NOTE -> nowExist.note = NoteRule( + types = git.includeNoteTypes?.map { + when (it) { + "Commit" -> "commit" + "Review" -> "merge_request" + "Issue" -> "issue" + else -> it + } + } + ) + } + } +// res[name] = nowExist + } + return res.values.toList() + } + + @Suppress("ComplexMethod") + fun yaml2TriggerTGit(triggerOn: TriggerOn, elementQueue: MutableList) { + triggerOn.push?.let { push -> + elementQueue.add( + CodeTGitWebHookTriggerElement( + data = CodeTGitWebHookTriggerData( + input = CodeTGitWebHookTriggerInput( + branchName = push.branches.nonEmptyOrNull()?.join(), + excludeBranchName = push.branchesIgnore.nonEmptyOrNull()?.join(), + includePaths = push.paths.nonEmptyOrNull()?.join(), + excludePaths = push.pathsIgnore.nonEmptyOrNull()?.join(), + includeUsers = push.users, + excludeUsers = push.usersIgnore, + eventType = CodeEventType.PUSH, + // todo action + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + ) + ) + } + + triggerOn.tag?.let { tag -> + elementQueue.add( + CodeTGitWebHookTriggerElement( + data = CodeTGitWebHookTriggerData( + input = CodeTGitWebHookTriggerInput( + tagName = tag.tags.nonEmptyOrNull()?.join(), + excludeTagName = tag.tagsIgnore.nonEmptyOrNull()?.join(), + fromBranches = tag.fromBranches.nonEmptyOrNull()?.join(), + includeUsers = tag.users, + excludeUsers = tag.usersIgnore, + eventType = CodeEventType.TAG_PUSH, + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + ) + ) + } + + triggerOn.mr?.let { mr -> + elementQueue.add( + CodeTGitWebHookTriggerElement( + data = CodeTGitWebHookTriggerData( + input = CodeTGitWebHookTriggerInput( + branchName = mr.targetBranches.nonEmptyOrNull()?.join(), + excludeBranchName = mr.targetBranchesIgnore.nonEmptyOrNull()?.join(), + includeSourceBranchName = mr.sourceBranches.nonEmptyOrNull()?.join(), + excludeSourceBranchName = mr.sourceBranchesIgnore.nonEmptyOrNull()?.join(), + includePaths = mr.paths.nonEmptyOrNull()?.join(), + excludePaths = mr.pathsIgnore.nonEmptyOrNull()?.join(), + includeUsers = mr.users, + excludeUsers = mr.usersIgnore, + block = mr.block, + webhookQueue = mr.webhookQueue, + enableCheck = mr.enableCheck, + // todo action + eventType = CodeEventType.MERGE_REQUEST, + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + ) + ) + } + + triggerOn.review?.let { review -> + elementQueue.add( + CodeTGitWebHookTriggerElement( + data = CodeTGitWebHookTriggerData( + input = CodeTGitWebHookTriggerInput( + includeCrState = review.states, + includeCrTypes = review.types, + eventType = CodeEventType.REVIEW, + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + ) + ) + } + + triggerOn.issue?.let { issue -> + elementQueue.add( + CodeTGitWebHookTriggerElement( + data = CodeTGitWebHookTriggerData( + input = CodeTGitWebHookTriggerInput( + includeIssueAction = issue.action, + eventType = CodeEventType.ISSUES, + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + ) + ) + } + + triggerOn.note?.let { note -> + elementQueue.add( + CodeTGitWebHookTriggerElement( + data = CodeTGitWebHookTriggerData( + input = CodeTGitWebHookTriggerInput( + includeNoteTypes = note.types?.map { + when (it) { + "commit" -> "Commit" + "merge_request" -> "Review" + "issue" -> "Issue" + else -> it + } + }, + includeNoteComment = note.comment.nonEmptyOrNull()?.join(), + eventType = CodeEventType.NOTE, + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + ) + ) + } + } + + @Suppress("ComplexMethod") + fun yaml2TriggerGithub(triggerOn: TriggerOn, elementQueue: MutableList) { + triggerOn.push?.let { push -> + elementQueue.add( + CodeGithubWebHookTriggerElement( + branchName = push.branches.nonEmptyOrNull()?.join(), + excludeBranchName = push.branchesIgnore.nonEmptyOrNull()?.join(), + includePaths = push.paths.nonEmptyOrNull()?.join(), + excludePaths = push.pathsIgnore.nonEmptyOrNull()?.join(), + includeUsers = push.users, + excludeUsers = push.usersIgnore.nonEmptyOrNull()?.join(), + eventType = CodeEventType.PUSH, + // todo action + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + } + + triggerOn.tag?.let { tag -> + elementQueue.add( + CodeGithubWebHookTriggerElement( + tagName = tag.tags.nonEmptyOrNull()?.join(), + excludeTagName = tag.tagsIgnore.nonEmptyOrNull()?.join(), + fromBranches = tag.fromBranches.nonEmptyOrNull()?.join(), + includeUsers = tag.users, + excludeUsers = tag.usersIgnore.nonEmptyOrNull()?.join(), + eventType = CodeEventType.TAG_PUSH, + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + } + + triggerOn.mr?.let { mr -> + elementQueue.add( + CodeGithubWebHookTriggerElement( + branchName = mr.targetBranches.nonEmptyOrNull()?.join(), + excludeBranchName = mr.targetBranchesIgnore.nonEmptyOrNull()?.join(), + includeSourceBranchName = mr.sourceBranches.nonEmptyOrNull()?.join(), + excludeSourceBranchName = mr.sourceBranchesIgnore.nonEmptyOrNull()?.join(), + includePaths = mr.paths.nonEmptyOrNull()?.join(), + excludePaths = mr.pathsIgnore.nonEmptyOrNull()?.join(), + includeUsers = mr.users, + excludeUsers = mr.usersIgnore.nonEmptyOrNull()?.join(), + webhookQueue = mr.webhookQueue, + enableCheck = mr.enableCheck, + // todo action + eventType = CodeEventType.PULL_REQUEST, + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + } + + triggerOn.review?.let { review -> + elementQueue.add( + CodeGithubWebHookTriggerElement( + includeCrState = review.states, + includeCrTypes = review.types, + eventType = CodeEventType.REVIEW, + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + } + + triggerOn.issue?.let { issue -> + elementQueue.add( + CodeGithubWebHookTriggerElement( + includeIssueAction = issue.action, + eventType = CodeEventType.ISSUES, + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + } + + triggerOn.note?.let { note -> + elementQueue.add( + CodeGithubWebHookTriggerElement( + includeNoteTypes = note.types?.map { + when (it) { + "commit" -> "Commit" + "merge_request" -> "Review" + "issue" -> "Issue" + else -> it + } + }, + includeNoteComment = note.comment.nonEmptyOrNull()?.join(), + eventType = CodeEventType.NOTE, + repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.name + ) + ) + } + } + + private fun List.join() = this.joinToString(separator = ",") + + private fun String.disjoin() = this.split(",") + + private fun List?.nonEmptyOrNull() = this?.ifEmpty { null } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreator.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreator.kt new file mode 100644 index 00000000000..f520b28c058 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreator.kt @@ -0,0 +1,69 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.modelTransfer.inner + +import com.tencent.devops.common.pipeline.pojo.element.ElementAdditionalOptions +import com.tencent.devops.common.pipeline.pojo.element.market.MarketBuildAtomElement +import com.tencent.devops.process.yaml.v2.models.job.Job +import com.tencent.devops.process.yaml.v2.models.step.Step + +/** + * ModelCreate的内部类,用来放一些不同使用者的不同方法和参数 + */ +interface TransferModelCreator { + // 控制run插件是否是研发商店插件 + val marketRunTask: Boolean + + // 研发商店的run插件的code + val runPlugInAtomCode: String? + + // 研发商店的run插件的版本 + val runPlugInVersion: String? + + // 默认的公共镜像 + val defaultImage: String + + /** + * 构造具有特殊语法的checkout插件 + * @param step 当前step对象 + * @param event model创建的总事件 + * @param additionalOptions 插件的控制参数 + */ + fun transferCheckoutElement( + step: Step, + additionalOptions: ElementAdditionalOptions + ): MarketBuildAtomElement + + /** + * 构造编译类的插件 + */ + fun transferMarketBuildAtomElement( + step: Step, + additionalOptions: ElementAdditionalOptions + ): MarketBuildAtomElement +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreatorImpl.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreatorImpl.kt new file mode 100644 index 00000000000..12e4e0f5f7e --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreatorImpl.kt @@ -0,0 +1,133 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.modelTransfer.inner + +import com.tencent.devops.common.api.exception.CustomException +import com.tencent.devops.common.pipeline.pojo.element.ElementAdditionalOptions +import com.tencent.devops.common.pipeline.pojo.element.market.MarketBuildAtomElement +import com.tencent.devops.process.yaml.v2.models.step.Step +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.beans.factory.annotation.Value +import org.springframework.context.annotation.Primary +import org.springframework.stereotype.Component +import javax.ws.rs.core.Response + +@Primary +@Component +class TransferModelCreatorImpl @Autowired constructor( +) : TransferModelCreator { + @Value("\${stream.marketRun.enable:#{false}}") + private val marketRunTaskData: Boolean = false + + @Value("\${stream.marketRun.atomCode:#{null}}") + private val runPlugInAtomCodeData: String? = null + + @Value("\${stream.marketRun.atomVersion:#{null}}") + private val runPlugInVersionData: String? = null + + @Value("\${container.defaultImage:#{null}}") + private val defaultImageData: String = "http://mirrors.tencent.com/ci/tlinux3_ci:1.5.0" + + companion object { + private const val STREAM_CHECK_AUTH_TYPE = "AUTH_USER_TOKEN" + } + + override val marketRunTask: Boolean + get() = marketRunTaskData + + override val runPlugInAtomCode: String? + get() = runPlugInAtomCodeData + + override val runPlugInVersion: String? + get() = runPlugInVersionData + + override val defaultImage: String + get() = defaultImageData + + override fun transferCheckoutElement( + step: Step, + additionalOptions: ElementAdditionalOptions + ): MarketBuildAtomElement { + // checkout插件装配 + val inputMap = mutableMapOf() + if (!step.with.isNullOrEmpty()) { + inputMap.putAll(step.with!!) + } + + // 用户不允许指定 stream的开启人参数 + if ((inputMap["authType"] != null && inputMap["authType"] == STREAM_CHECK_AUTH_TYPE) || + inputMap["authUserId"] != null + ) { + throw CustomException( + Response.Status.BAD_REQUEST, + "The parameter authType:AUTH_USER_TOKEN or authUserId does not support user-specified" + ) + } + + inputMap["repositoryUrl"] = step.checkout!! + + + // 用户未指定时缺省为 AUTH_USER_TOKEN 同时指定 开启人 + if (inputMap["authType"] == null) { + inputMap["authType"] = STREAM_CHECK_AUTH_TYPE + } + + // 拼装插件固定参数 + inputMap["repositoryType"] = "URL" + + val data = mutableMapOf() + data["input"] = inputMap + + return MarketBuildAtomElement( + id = step.taskId, + name = step.name ?: "checkout", + stepId = step.id, + atomCode = "checkout", + version = "1.*", + data = data, + additionalOptions = additionalOptions + ) + } + + override fun transferMarketBuildAtomElement( + step: Step, + additionalOptions: ElementAdditionalOptions + ): MarketBuildAtomElement { + val data = mutableMapOf() + data["input"] = step.with ?: Any() + return MarketBuildAtomElement( + id = step.taskId, + name = step.name ?: step.uses!!.split('@')[0], + stepId = step.id, + atomCode = step.uses!!.split('@')[0], + version = step.uses!!.split('@')[1], + data = data, + additionalOptions = additionalOptions + ) + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/CheckoutAtomParam.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/CheckoutAtomParam.kt new file mode 100644 index 00000000000..0eed59d5695 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/CheckoutAtomParam.kt @@ -0,0 +1,236 @@ +package com.tencent.devops.process.yaml.modelTransfer.pojo + +import com.fasterxml.jackson.annotation.JsonIgnore +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.common.api.enums.RepositoryConfig +import com.tencent.devops.common.api.enums.RepositoryType + +@JsonInclude(JsonInclude.Include.NON_NULL) +data class CheckoutAtomParam( + /** + * 代码库, 必选, 默认: ID, options: 按代码库选择[ID] | 按代码库别名输入[NAME] | 按仓库URL输入[URL] + */ + var repositoryType: CheckoutRepositoryType? = null, + + /** + * 按代码库选择, 当 [repositoryType] = [ID] 时必选 + */ + var repositoryHashId: String? = null, + + /** + * 按代码库别名输入, 当 [repositoryType] = [NAME] 时必选 + */ + var repositoryName: String? = null, + + /** + * 代码库链接, 当 [repositoryType] = [URL] 时必选 + */ + var repositoryUrl: String? = null, + + /** + * 授权类型, 默认: TICKET, + * 当 [repositoryType] = [URL] 时必选, single, + * + * options: + * + * EMPTY[空] | TICKET[凭证] | ACCESS_TOKEN[access token] | USERNAME_PASSWORD[username/password] | + * START_USER_TOKEN[流水线启动人token] | PERSONAL_ACCESS_TOKEN[工蜂personal_access_token] + */ + var authType: AuthType? = null, + var authUserId: String? = null, + + /** + * 代码库凭证, 当 [repositoryType] = [URL] 和 [authType] = [TICKET] 时必选 + */ + var ticketId: String? = null, + + /** + * access token, 当 [repositoryType] = [URL] 和 [authType] = [ACCESS_TOKEN] 时必选 + */ + var accessToken: String? = null, + + /** + * 工蜂personal_access_token, 当 [repositoryType] = [URL] 和 [authType] = [PERSONAL_ACCESS_TOKEN] 时必选 + */ + var personalAccessToken: String? = null, + + /** + * username, 当 [repositoryType] = [URL] 和 [authType] = [USERNAME_PASSWORD] 时必选 + */ + var username: String? = null, + + /** + * password, 当 [repositoryType] = [URL] 和 [authType] = [USERNAME_PASSWORD] 时必选 + */ + var password: String? = null, + + /** + * 指定拉取方式, 默认: BRANCH, single, options: BRANCH[BRANCH] | TAG[TAG] | COMMIT_ID[COMMIT_ID] + */ + var pullType: String? = null, + + /** + * 分支/TAG/COMMIT, 必选, 默认: master + */ + var refName: String? = null, + + /** + * 代码保存路径 + */ + var localPath: String? = null, + + /** + * 拉取策略, 默认: REVERT_UPDATE, + * + * options: + * + * Revert Update[REVERT_UPDATE] | Fresh Checkout[FRESH_CHECKOUT] | Increment Update[INCREMENT_UPDATE] + */ + var strategy: String? = null, + + /** + * git fetch的depth参数值 + */ + var fetchDepth: Int? = null, + + /** + * 启用拉取指定分支, 默认: false + */ + val enableFetchRefSpec: Boolean? = null, + + /** + * 插件配置的分支不需要设置,默认会设置.配置的分支必须存在,否则会报错, 当 [enableFetchRefSpec] = [true] 时必选 + */ + val fetchRefSpec: String? = null, + + /** + * 是否开启Git Lfs, 默认: true + */ + var enableGitLfs: Boolean? = null, + + /** + * lfs并发上传下载的数量 + */ + val lfsConcurrentTransfers: Int? = null, + + /** + * MR事件触发时执行Pre-Merge, 必选, 默认: true + */ + var enableVirtualMergeBranch: Boolean? = null, + + /** + * 启用子模块, 默认: true + */ + var enableSubmodule: Boolean? = null, + + /** + * 子模块路径当 [enableSubmodule] = [true] 时必选 + */ + var submodulePath: String? = null, + + /** + * 执行git submodule update后面是否带上--remote参数, 默认: false, 当 [enableSubmodule] = [true] 时必选 + */ + var enableSubmoduleRemote: Boolean? = null, + + /** + * 执行git submodule update后面是否带上--recursive参数, 默认: true, 当 [enableSubmodule] = [true] 时必选 + */ + var enableSubmoduleRecursive: Boolean? = null, + + /** + * AutoCrlf配置值, 默认: false, single, options: false[false] | true[true] | input[input] + */ + var autoCrlf: String? = null, + + /** + * 是否开启Git Clean, 必选, 默认: true, 当 [strategy] = [REVERT_UPDATE] 时必选 + */ + var enableGitClean: Boolean? = null, + + /** + * 清理没有版本跟踪的ignored文件, 必选, 默认: true, 当 [strategy] = [REVERT_UPDATE] 和 [enableGitClean] = [true] 时必选 + */ + val enableGitCleanIgnore: Boolean? = null, + + /** + * 清理没有版本跟踪的嵌套仓库, 必选, 默认: false, 当 [strategy] = [REVERT_UPDATE] 和 [enableGitClean] = [true] 时必选 + */ + val enableGitCleanNested: Boolean? = null, + + /** + * 拉取代码库以下路径 + */ + var includePath: String? = null, + + /** + * 排除代码库以下路径 + */ + var excludePath: String? = null, + + // 非前端传递的参数 + @JsonProperty("pipeline.start.type") + val pipelineStartType: String? = null, + val hookEventType: String? = null, + val hookSourceBranch: String? = null, + val hookTargetBranch: String? = null, + val hookSourceUrl: String? = null, + val hookTargetUrl: String? = null, + + @JsonProperty("git_mr_number") + val gitMrNumber: String? = null, + +// 重试时检出的commitId + var retryStartPoint: String? = null, + + /** + * 是否持久化凭证, 默认: true + */ + var persistCredentials: Boolean? = null, + + /** + * 是否开启调试, 必选, 默认: false + */ + var enableTrace: Boolean? = null, + + /** + * 是否开启部分克隆,部分克隆只有git版本大于2.22.0才可以使用 + */ + var enablePartialClone: Boolean? = null, + + /** + * 归档的缓存路径 + */ + val cachePath: String? = null +) { + enum class AuthType { + TICKET, + ACCESS_TOKEN, + USERNAME_PASSWORD, + START_USER_TOKEN, + + // 工蜂专有授权类型 + PERSONAL_ACCESS_TOKEN, + EMPTY, + + // 指定授权用户 + AUTH_USER_TOKEN + } + + enum class CheckoutRepositoryType { + ID, + NAME, + URL + } + + @JsonIgnore + fun getRepositoryConfig(): RepositoryConfig { + return RepositoryConfig( + repositoryHashId = repositoryHashId, + repositoryName = repositoryName, + repositoryType = kotlin.runCatching { RepositoryType.valueOf(repositoryType?.name ?: "ID") } + .getOrDefault(RepositoryType.ID) + ) + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/ModelTransferInput.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/ModelTransferInput.kt new file mode 100644 index 00000000000..840c12df566 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/ModelTransferInput.kt @@ -0,0 +1,13 @@ +package com.tencent.devops.process.yaml.modelTransfer.pojo + +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.process.yaml.pojo.YamlVersion + +data class ModelTransferInput( + var model: Model, + val setting: PipelineSetting, + val version: YamlVersion.Version, + val defaultScmType: ScmType = ScmType.CODE_GIT +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/RunAtomParam.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/RunAtomParam.kt new file mode 100644 index 00000000000..4148c4092ef --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/RunAtomParam.kt @@ -0,0 +1,44 @@ +package com.tencent.devops.process.yaml.modelTransfer.pojo + +data class RunAtomParam( + val shell: String? = null, + val script: String? = null, + val charsetType: CharsetType? = null +) { + enum class CharsetType { + /*默认类型*/ + DEFAULT, + + /*UTF_8*/ + UTF_8, + + /*GBK*/ + GBK + } + + enum class ShellType(val shellName: String) { + /*bash*/ + BASH("bash"), + + /*cmd*/ + CMD("cmd"), + + /*powershell*/ + POWERSHELL_CORE("pwsh"), + + /*powershell*/ + POWERSHELL_DESKTOP("powershell"), + + /*python*/ + PYTHON("python"), + + /*sh命令*/ + SH("sh"), + + /*windows 执行 bash*/ + WIN_BASH("win_bash"), + + /*按系统默认*/ + AUTO("auto"); + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/WebHookTriggerElementChanger.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/WebHookTriggerElementChanger.kt new file mode 100644 index 00000000000..181182740c3 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/WebHookTriggerElementChanger.kt @@ -0,0 +1,193 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.modelTransfer.pojo + +import com.tencent.devops.common.api.enums.RepositoryType +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGitWebHookTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGithubWebHookTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeTGitWebHookTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.enums.CodeEventType +import com.tencent.devops.common.pipeline.pojo.element.trigger.enums.PathFilterType +import io.swagger.annotations.ApiModelProperty + +data class WebHookTriggerElementChanger( + @ApiModelProperty("任务名称", required = true) + val name: String = "Git变更触发", + @ApiModelProperty("仓库ID", required = true) + val repositoryHashId: String? = null, + @ApiModelProperty("分支名称", required = false) + val branchName: String? = null, + @ApiModelProperty("用于排除的分支名", required = false) + val excludeBranchName: String? = null, + @ApiModelProperty("路径过滤类型", required = true) + val pathFilterType: PathFilterType? = PathFilterType.NamePrefixFilter, + @ApiModelProperty("用于包含的路径", required = false) + val includePaths: String? = null, + @ApiModelProperty("用于排除的路径", required = false) + val excludePaths: String? = null, + @ApiModelProperty("用户白名单", required = false) + val includeUsers: List? = null, + @ApiModelProperty("用于排除的user id", required = false) + val excludeUsers: List? = null, + @ApiModelProperty("事件类型", required = false) + val eventType: CodeEventType?, + @ApiModelProperty("是否为block", required = false) + val block: Boolean? = null, + @ApiModelProperty("新版的git原子的类型") + val repositoryType: RepositoryType? = null, + @ApiModelProperty("新版的git代码库名") + val repositoryName: String? = null, + @ApiModelProperty("tag名称", required = false) + val tagName: String? = null, + @ApiModelProperty("用于排除的tag名称", required = false) + val excludeTagName: String? = null, + @ApiModelProperty("tag从哪条分支创建", required = false) + val fromBranches: String? = null, + @ApiModelProperty("用于排除的源分支名称", required = false) + val excludeSourceBranchName: String? = null, + @ApiModelProperty("用于包含的源分支名称", required = false) + val includeSourceBranchName: String? = null, + @ApiModelProperty("webhook队列", required = false) + val webhookQueue: Boolean? = false, + @ApiModelProperty("code review 状态", required = false) + val includeCrState: List? = null, + @ApiModelProperty("code review 类型", required = false) + val includeCrTypes: List? = null, + @ApiModelProperty("code note comment", required = false) + val includeNoteComment: String? = null, + @ApiModelProperty("code note 类型", required = false) + val includeNoteTypes: List? = null, + @ApiModelProperty("是否启用回写") + val enableCheck: Boolean? = true, + @ApiModelProperty("issue事件action") + val includeIssueAction: List? = null, + @ApiModelProperty("mr事件action") + val includeMrAction: List? = null, + @ApiModelProperty("push事件action") + val includePushAction: List? = null, + @ApiModelProperty("是否启用第三方过滤") + val enableThirdFilter: Boolean? = false, + @ApiModelProperty("第三方应用地址") + val thirdUrl: String? = null, + @ApiModelProperty("第三方应用鉴权token") + val thirdSecretToken: String? = null +) { + constructor(data: CodeGitWebHookTriggerElement) : this( + name = data.name, + repositoryHashId = data.repositoryHashId, + branchName = data.branchName, + excludeBranchName = data.excludeBranchName, + pathFilterType = data.pathFilterType, + includePaths = data.includePaths, + excludePaths = data.excludePaths, + includeUsers = data.includeUsers, + excludeUsers = data.excludeUsers, + eventType = data.eventType, + block = data.block, + repositoryType = data.repositoryType, + repositoryName = data.repositoryName, + tagName = data.tagName, + excludeTagName = data.excludeTagName, + fromBranches = data.fromBranches, + excludeSourceBranchName = data.excludeSourceBranchName, + includeSourceBranchName = data.includeSourceBranchName, + webhookQueue = data.webhookQueue, + includeCrState = data.includeCrState, + includeCrTypes = data.includeCrTypes, + includeNoteComment = data.includeNoteComment, + includeNoteTypes = data.includeNoteTypes, + enableCheck = data.enableCheck, + includeIssueAction = data.includeIssueAction, + includeMrAction = data.includeMrAction, + includePushAction = data.includePushAction, + enableThirdFilter = data.enableThirdFilter, + thirdUrl = data.thirdUrl, + thirdSecretToken = data.thirdSecretToken + ) + + constructor(data: CodeTGitWebHookTriggerElement) : this( + name = data.name, + repositoryHashId = data.data.input.repositoryHashId, + branchName = data.data.input.branchName, + excludeBranchName = data.data.input.excludeBranchName, + pathFilterType = data.data.input.pathFilterType, + includePaths = data.data.input.includePaths, + excludePaths = data.data.input.excludePaths, + includeUsers = data.data.input.includeUsers, + excludeUsers = data.data.input.excludeUsers, + eventType = data.data.input.eventType, + block = data.data.input.block, + repositoryType = data.data.input.repositoryType, + repositoryName = data.data.input.repositoryName, + tagName = data.data.input.tagName, + excludeTagName = data.data.input.excludeTagName, + fromBranches = data.data.input.fromBranches, + excludeSourceBranchName = data.data.input.excludeSourceBranchName, + includeSourceBranchName = data.data.input.includeSourceBranchName, + webhookQueue = data.data.input.webhookQueue, + includeCrState = data.data.input.includeCrState, + includeCrTypes = data.data.input.includeCrTypes, + includeNoteComment = data.data.input.includeNoteComment, + includeNoteTypes = data.data.input.includeNoteTypes, + enableCheck = data.data.input.enableCheck, + includeIssueAction = data.data.input.includeIssueAction, + includeMrAction = data.data.input.includeMrAction, + includePushAction = data.data.input.includePushAction, + enableThirdFilter = data.data.input.enableThirdFilter + ) + + constructor(data: CodeGithubWebHookTriggerElement) : this( + name = data.name, + repositoryHashId = data.repositoryHashId, + branchName = data.branchName, + excludeBranchName = data.excludeBranchName, + pathFilterType = data.pathFilterType, + includePaths = data.includePaths, + excludePaths = data.excludePaths, + includeUsers = data.includeUsers, + excludeUsers = data.excludeUsers?.split(","), + eventType = data.eventType, + repositoryType = data.repositoryType, + repositoryName = data.repositoryName, + tagName = data.tagName, + excludeTagName = data.excludeTagName, + fromBranches = data.fromBranches, + excludeSourceBranchName = data.excludeSourceBranchName, + includeSourceBranchName = data.includeSourceBranchName, + webhookQueue = data.webhookQueue, + includeCrState = data.includeCrState, + includeCrTypes = data.includeCrTypes, + includeNoteComment = data.includeNoteComment, + includeNoteTypes = data.includeNoteTypes, + enableCheck = data.enableCheck, + includeIssueAction = data.includeIssueAction, + includeMrAction = data.includeMrAction, + includePushAction = data.includePushAction, + enableThirdFilter = data.enableThirdFilter + ) +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/YamlTransferInput.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/YamlTransferInput.kt new file mode 100644 index 00000000000..9bb2a0fe3d1 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/YamlTransferInput.kt @@ -0,0 +1,15 @@ +package com.tencent.devops.process.yaml.modelTransfer.pojo + +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.common.api.pojo.PipelineAsCodeSettings +import com.tencent.devops.process.pojo.BuildTemplateAcrossInfo +import com.tencent.devops.process.yaml.v2.models.IPreTemplateScriptBuildYaml + +data class YamlTransferInput( + val userId: String, + val projectCode: String, + val yaml: IPreTemplateScriptBuildYaml, + val defaultScmType: ScmType = ScmType.CODE_GIT, + val asCodeSettings: PipelineAsCodeSettings? = null, + val jobTemplateAcrossInfo: Map? = null +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/TemplatePath.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/TemplatePath.kt new file mode 100644 index 00000000000..fc85bfac630 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/TemplatePath.kt @@ -0,0 +1,37 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.pojo + +data class TemplatePath( + val path: String, + val ref: String? = null +) { + override fun toString(): String { + return path + if (ref != null) "[$ref]" else "" + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/YamlVersion.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/YamlVersion.kt new file mode 100644 index 00000000000..fe093956046 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/YamlVersion.kt @@ -0,0 +1,10 @@ +package com.tencent.devops.process.yaml.pojo + +interface YamlVersion { + enum class Version { + V2_0, + V3_0 + } + + fun yamlVersion(): Version +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/utils/StreamDispatchUtils.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/utils/StreamDispatchUtils.kt index a2fdb1bc4ed..d46973a14b7 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/utils/StreamDispatchUtils.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/utils/StreamDispatchUtils.kt @@ -48,8 +48,8 @@ import com.tencent.devops.process.yaml.v2.models.job.Container import com.tencent.devops.process.yaml.v2.models.job.Container2 import com.tencent.devops.process.yaml.v2.models.job.Job import com.tencent.devops.process.yaml.v2.models.job.JobRunsOnType -import javax.ws.rs.core.Response import org.slf4j.LoggerFactory +import javax.ws.rs.core.Response import com.tencent.devops.common.pipeline.type.agent.Credential as thirdPartDockerCredential @Suppress("ALL") diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/enums/TemplateType.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/enums/TemplateType.kt index 18a0da33cdd..1b7ad953631 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/enums/TemplateType.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/enums/TemplateType.kt @@ -31,6 +31,7 @@ package com.tencent.devops.process.yaml.v2.enums * 模板类型,text为展示内容,content为模板在Yaml中的关键字 */ enum class TemplateType(val text: String, val content: String) { + TRIGGER_ON("triggerOn", "on"), VARIABLE("variable", "variables"), STAGE("stage", "stages"), JOB("job", "jobs"), diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Extends.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Extends.kt index d445eba2043..baaba60c47a 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Extends.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Extends.kt @@ -29,6 +29,9 @@ package com.tencent.devops.process.yaml.v2.models import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude +import com.tencent.devops.process.yaml.v2.models.job.IPreJob +import com.tencent.devops.process.yaml.v2.models.stage.IPreStage +import com.tencent.devops.process.yaml.v2.models.step.IPreStep /** * model @@ -37,5 +40,6 @@ import com.fasterxml.jackson.annotation.JsonInclude @JsonIgnoreProperties(ignoreUnknown = true) data class Extends( val template: String, - val parameters: Map? -) + val parameters: Map?, + val ref: String? +) : IPreStep, IPreJob, IPreStage diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreScriptBuildYaml.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreScriptBuildYaml.kt index bafe1ba6a89..0c8b969847c 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreScriptBuildYaml.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreScriptBuildYaml.kt @@ -29,6 +29,8 @@ package com.tencent.devops.process.yaml.v2.models import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.process.yaml.pojo.YamlVersion import com.tencent.devops.process.yaml.v2.models.job.PreJob import com.tencent.devops.process.yaml.v2.models.on.PreTriggerOn import com.tencent.devops.process.yaml.v2.models.stage.PreStage @@ -38,11 +40,10 @@ import com.tencent.devops.process.yaml.v2.models.step.PreStep * PreScriptBuildYamlI 是PreScriptBuildYaml的拓展,方便再既不修改data class的特性情况下,其他类可以在继承新增字段 * 注:PreScriptBuildYaml 新增的字段需要在这里新增 */ -interface PreScriptBuildYamlI { +interface PreScriptBuildYamlI : YamlVersion { var version: String? var name: String? var label: List? - var triggerOn: PreTriggerOn? var variables: Map? var stages: List? var jobs: Map? @@ -65,7 +66,8 @@ data class PreScriptBuildYaml( override var version: String?, override var name: String?, override var label: List? = null, - override var triggerOn: PreTriggerOn?, + @JsonProperty("on") + var triggerOn: PreTriggerOn?, override var variables: Map? = null, override var stages: List? = null, override var jobs: Map? = null, @@ -75,4 +77,6 @@ data class PreScriptBuildYaml( override var notices: List?, override var finally: Map? = null, override val concurrency: Concurrency? = null -) : PreScriptBuildYamlI +) : PreScriptBuildYamlI { + override fun yamlVersion() = YamlVersion.Version.V2_0 +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt index a866f5a1a32..a2b3982069f 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt @@ -27,9 +27,52 @@ package com.tencent.devops.process.yaml.v2.models +import com.fasterxml.jackson.annotation.JsonIgnore import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.process.yaml.pojo.YamlVersion +import com.tencent.devops.process.yaml.v2.models.job.Job import com.tencent.devops.process.yaml.v2.models.on.PreTriggerOn +import com.tencent.devops.process.yaml.v2.models.on.TriggerOn +import com.tencent.devops.process.yaml.v2.models.stage.Stage +import com.tencent.devops.process.yaml.v2.utils.ScriptYmlUtils + +interface IPreTemplateScriptBuildYaml : YamlVersion { + val version: String? + val name: String? + val label: List? + val notices: List? + val concurrency: Concurrency? + + fun replaceTemplate(f: (param: ITemplateFilter) -> PreScriptBuildYamlI) + + fun formatVariables(): Map + + fun formatTriggerOn(default: ScmType): Map + + fun formatStages(): List + + fun formatFinallyStage(): List + + fun formatResources(): Resources? +} + +/* +* ITemplateFilter 为模板替换所需材料 +*/ +interface ITemplateFilter : YamlVersion { + val variables: Map? + val stages: List>? + val jobs: Map? + val steps: List>? + val extends: Extends? + val resources: Resources? + var finally: Map? + + fun initPreScriptBuildYamlI(): PreScriptBuildYamlI +} /** * model @@ -39,17 +82,67 @@ import com.tencent.devops.process.yaml.v2.models.on.PreTriggerOn @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class PreTemplateScriptBuildYaml( - val version: String?, - val name: String?, - val label: List? = null, + override val version: String?, + override val name: String?, + override val label: List? = null, + @JsonProperty("on") val triggerOn: PreTriggerOn?, - val variables: Map?, - val stages: List>?, - val jobs: Map? = null, - val steps: List>? = null, - val extends: Extends?, - val resources: Resources?, - val notices: List?, - var finally: Map?, - val concurrency: Concurrency? = null -) + override val variables: Map?, + override val stages: List>?, + override val jobs: Map? = null, + override val steps: List>? = null, + override val extends: Extends?, + override val resources: Resources?, + override val notices: List?, + override var finally: Map?, + override val concurrency: Concurrency? = null +) : IPreTemplateScriptBuildYaml, ITemplateFilter { + override fun yamlVersion() = YamlVersion.Version.V2_0 + + override fun initPreScriptBuildYamlI(): PreScriptBuildYamlI { + return PreScriptBuildYaml( + version = version, + name = name, + label = label, + triggerOn = triggerOn, + resources = resources, + notices = notices, + concurrency = concurrency + ) + } + + @JsonIgnore + lateinit var preYaml: PreScriptBuildYaml + + override fun replaceTemplate(f: (param: ITemplateFilter) -> PreScriptBuildYamlI) { + preYaml = f(this) as PreScriptBuildYaml + } + + override fun formatVariables(): Map { + checkInitialized() + return preYaml.variables ?: emptyMap() + } + + override fun formatTriggerOn(default: ScmType): Map { + return mapOf(default to ScriptYmlUtils.formatTriggerOn(triggerOn)) + } + + override fun formatStages(): List { + checkInitialized() + return ScriptYmlUtils.formatStage(preYaml) + } + + override fun formatFinallyStage(): List { + checkInitialized() + return ScriptYmlUtils.preJobs2Jobs(preYaml.finally) + } + + override fun formatResources(): Resources? { + checkInitialized() + return preYaml.resources + } + + private fun checkInitialized() { + if (!this::preYaml.isInitialized) throw RuntimeException("need replaceTemplate before") + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/ScriptBuildYaml.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/ScriptBuildYaml.kt index 7ad011153da..d35c59f4d6d 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/ScriptBuildYaml.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/ScriptBuildYaml.kt @@ -29,6 +29,8 @@ package com.tencent.devops.process.yaml.v2.models import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.process.yaml.pojo.YamlVersion import com.tencent.devops.process.yaml.v2.models.job.Job import com.tencent.devops.process.yaml.v2.models.on.TriggerOn import com.tencent.devops.process.yaml.v2.models.stage.Stage @@ -44,6 +46,7 @@ data class ScriptBuildYaml( val version: String?, val name: String?, val label: List?, + @JsonProperty("on") val triggerOn: TriggerOn?, val variables: Map?, val stages: List, @@ -52,4 +55,6 @@ data class ScriptBuildYaml( val notices: List?, var finally: List?, val concurrency: Concurrency? -) +) : YamlVersion { + override fun yamlVersion() = YamlVersion.Version.V2_0 +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Template.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Template.kt index 168ebff9ff8..aa23de7ed17 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Template.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Template.kt @@ -29,5 +29,6 @@ package com.tencent.devops.process.yaml.v2.models data class Template( val template: String, + val ref: String?, val parameters: Map? ) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Variable.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Variable.kt index 17a384c80a5..6bb16677283 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Variable.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Variable.kt @@ -30,6 +30,50 @@ package com.tencent.devops.process.yaml.v2.models import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.JsonGenerator +import com.fasterxml.jackson.core.JsonParser +import com.fasterxml.jackson.core.type.TypeReference +import com.fasterxml.jackson.databind.DeserializationContext +import com.fasterxml.jackson.databind.JsonNode +import com.fasterxml.jackson.databind.SerializerProvider +import com.fasterxml.jackson.databind.annotation.JsonDeserialize +import com.fasterxml.jackson.databind.deser.std.StdDeserializer +import com.fasterxml.jackson.databind.node.ArrayNode +import com.fasterxml.jackson.databind.node.ObjectNode +import com.fasterxml.jackson.databind.node.TextNode +import com.fasterxml.jackson.databind.ser.std.StdSerializer +import com.tencent.devops.common.api.util.JsonUtil + +//@JsonDeserialize(using = IVariableDeserializer::class) +interface IVariable +// +//class IVariableDeserializer : StdDeserializer(IVariable::class.java) { +// override fun deserialize(p: JsonParser, ctxt: DeserializationContext): IVariable { +// val node: JsonNode = p.codec.readTree(p) +// return when (node) { +// is ObjectNode -> Variable( +// value = node.get(Variable::value.name)?.asText(), +// readonly = node.get(Variable::readonly.name)?.asBoolean(), +// allowModifyAtStartup = node.get(Variable::allowModifyAtStartup.name)?.asBoolean(), +// props = JsonUtil.toOrNull( +// node.get(Variable::props.name)?.toString(), object : TypeReference() {}), +// ) +// is ArrayNode -> TemplateVariable(JsonUtil.to(node.toString(), object : TypeReference>() {})) +// is TextNode -> ShortVariable(node.toString()) +// else -> throw Exception("") +// } +// } +//} +// +//class IVariableSerializer : StdSerializer(IVariable::class.java) { +// override fun serialize(value: IVariable, gen: JsonGenerator, provider: SerializerProvider) { +// when (value) { +// is ShortVariable -> gen.writeString(value.value) +// is Variable -> gen.writeObject(value.toMap()) +// is TemplateVariable -> gen.writeObject(value.toList()) +// } +// } +//} /** * Variable model @@ -43,7 +87,11 @@ data class Variable( @JsonProperty("allow-modify-at-startup") val allowModifyAtStartup: Boolean? = false, val props: VariableProps? = null -) +) : IVariable + +data class ShortVariable(val value: String) : IVariable + +data class TemplateVariable(private val list: List) : List by list, IVariable /** * Variable 属性变量 diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/job/PreJob.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/job/PreJob.kt index 6426aad6809..473df9e2c8a 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/job/PreJob.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/job/PreJob.kt @@ -35,6 +35,8 @@ import com.tencent.devops.process.yaml.v2.models.YamlMetaData import com.tencent.devops.process.yaml.v2.models.step.PreStep import io.swagger.annotations.ApiModelProperty +interface IPreJob + /** * WARN: 请谨慎修改这个类 , 不要随意添加或者删除变量 , 否则可能导致依赖yaml的功能(gitci,prebuild等)异常 */ @@ -68,4 +70,4 @@ data class PreJob( @JsonProperty("depend-on") val dependOn: List? = null, override val yamlMetaData: MetaData? = null -) : YamlMetaData +) : YamlMetaData, IPreJob diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/MrRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/MrRule.kt index 84bea742b71..dc067a64d34 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/MrRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/MrRule.kt @@ -38,6 +38,10 @@ import io.swagger.annotations.ApiModelProperty @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class MrRule( + @ApiModelProperty(name = "source-branches") + @JsonProperty("source-branches") + val sourceBranches: List? = null, + @ApiModelProperty(name = "source-branches-ignore") @JsonProperty("source-branches-ignore") val sourceBranchesIgnore: List? = null, @@ -46,6 +50,10 @@ data class MrRule( @JsonProperty("target-branches") val targetBranches: List? = null, + @ApiModelProperty(name = "target-branches-ignore") + @JsonProperty("target-branches-ignore") + val targetBranchesIgnore: List? = null, + val paths: List? = null, @ApiModelProperty(name = "paths-ignore") @@ -58,5 +66,11 @@ data class MrRule( @ApiModelProperty(name = "users-ignore") @JsonProperty("users-ignore") - val usersIgnore: List? = null + val usersIgnore: List? = null, + + val block: Boolean? = null, + + val webhookQueue: Boolean? = null, + + val enableCheck: Boolean? = null ) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/NoteRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/NoteRule.kt index d2a26802890..dd0bef4f063 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/NoteRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/NoteRule.kt @@ -32,7 +32,7 @@ import com.fasterxml.jackson.annotation.JsonInclude @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -class NoteRule { - val types: List? = null +class NoteRule( + val types: List? = null, val comment: List? = null -} +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ReviewRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ReviewRule.kt index c9376760791..4a02ca2e007 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ReviewRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ReviewRule.kt @@ -32,7 +32,7 @@ import com.fasterxml.jackson.annotation.JsonInclude @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -class ReviewRule { - val types: List? = null +data class ReviewRule( + val types: List? = null, val states: List? = null -} +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TriggerOn.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TriggerOn.kt index b6b103a9718..4ba23f1c223 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TriggerOn.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TriggerOn.kt @@ -30,7 +30,9 @@ package com.tencent.devops.process.yaml.v2.models.on import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.process.yaml.pojo.YamlVersion import com.tencent.devops.process.yaml.v2.models.RepositoryHook +import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 import io.swagger.annotations.ApiModelProperty /** @@ -39,35 +41,90 @@ import io.swagger.annotations.ApiModelProperty @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class TriggerOn( - val push: PushRule?, - val tag: TagRule?, - val mr: MrRule?, - val schedules: SchedulesRule? = null, - val delete: DeleteRule? = null, - val issue: IssueRule? = null, - val review: ReviewRule? = null, - val note: NoteRule? = null, + var push: PushRule? = null, + var tag: TagRule? = null, + var mr: MrRule? = null, + var schedules: SchedulesRule? = null, + var delete: DeleteRule? = null, + var issue: IssueRule? = null, + var review: ReviewRule? = null, + var note: NoteRule? = null, @ApiModelProperty(name = "repo_hook") @JsonProperty("repo_hook") val repoHook: RepositoryHook? = null, val manual: String? = null, - val openapi: String? = null -) + val openapi: String? = null, + var name: String? = null, + @JsonProperty("repoId") + @ApiModelProperty(name = "repoId") + var repoHashId: String? = null, + var credentials: String? = null +) { + fun toPreV2() = PreTriggerOn( + push = push, + tag = tag, + mr = mr, + schedules = schedules, + delete = delete, + issue = issue, + review = review, + note = note, + // todo + repoHook = null, + manual = manual, + openapi = openapi + ) + + fun toPreV3() = PreTriggerOnV3( + name = name, + repoHashId = repoHashId, + type = null, + credentials = credentials, + push = push, + tag = tag, + mr = mr, + schedules = schedules, + delete = delete, + issue = issue, + review = review, + note = note, + // todo + repoHook = null, + manual = manual, + openapi = openapi + ) +} + +interface IPreTriggerOn : YamlVersion { + val push: Any? + val tag: Any? + val mr: Any? + val schedules: SchedulesRule? + val delete: DeleteRule? + val issue: IssueRule? + val review: ReviewRule? + val note: NoteRule? + val repoHook: List? + val manual: String? + val openapi: String? +} @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class PreTriggerOn( - val push: Any?, - val tag: Any?, - val mr: Any?, - val schedules: SchedulesRule?, - val delete: DeleteRule?, - val issue: IssueRule? = null, - val review: ReviewRule? = null, - val note: NoteRule? = null, + override val push: Any?, + override val tag: Any?, + override val mr: Any?, + override val schedules: SchedulesRule?, + override val delete: DeleteRule?, + override val issue: IssueRule? = null, + override val review: ReviewRule? = null, + override val note: NoteRule? = null, @ApiModelProperty(name = "repo_hook") @JsonProperty("repo_hook") - val repoHook: List? = null, - val manual: String? = null, - val openapi: String? = null -) + override val repoHook: List? = null, + override val manual: String? = null, + override val openapi: String? = null +) : IPreTriggerOn { + override fun yamlVersion() = YamlVersion.Version.V2_0 +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/stage/PreStage.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/stage/PreStage.kt index e7bea39d6c2..d6089c15d63 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/stage/PreStage.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/stage/PreStage.kt @@ -32,6 +32,8 @@ import com.tencent.devops.process.yaml.v2.models.job.PreJob import com.tencent.devops.process.yaml.v2.stageCheck.PreStageCheck import io.swagger.annotations.ApiModelProperty +interface IPreStage + /** * WARN: 请谨慎修改这个类 , 不要随意添加或者删除变量 , 否则可能导致依赖yaml的功能(gitci,prebuild等)异常 */ @@ -54,4 +56,4 @@ data class PreStage( @ApiModelProperty(name = "check-out") @JsonProperty("check-out") val checkOut: PreStageCheck? -) +) : IPreStage diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/step/PreStep.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/step/PreStep.kt index 94b22d650e6..20609ac79e9 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/step/PreStep.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/step/PreStep.kt @@ -34,6 +34,8 @@ import com.tencent.devops.process.yaml.v2.models.YAME_META_DATA_JSON_FILTER import com.tencent.devops.process.yaml.v2.models.YamlMetaData import io.swagger.annotations.ApiModelProperty +interface IPreStep + /** * 为了方便产生中间变量的过度类和Step一模一样 */ @@ -63,4 +65,4 @@ data class PreStep( val run: String?, val shell: String?, override val yamlMetaData: MetaData? = null -) : YamlMetaData +) : YamlMetaData, IPreStep diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/Constants.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/Constants.kt index ced07ddd6fc..d6f3b40ef5d 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/Constants.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/Constants.kt @@ -32,6 +32,7 @@ object Constants { // 引用模板的关键字 const val TEMPLATE_KEY = "template" + const val REF = "ref" // 模板变量关键字 const val PARAMETERS_KEY = "parameters" diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/ParametersExpressionParse.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/ParametersExpressionParse.kt index fb5f7da908c..2c5516fa6fd 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/ParametersExpressionParse.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/ParametersExpressionParse.kt @@ -18,6 +18,7 @@ import com.tencent.devops.common.expression.context.StringContextData import com.tencent.devops.common.expression.expression.FunctionInfo import com.tencent.devops.common.expression.expression.sdk.NamedValueInfo import com.tencent.devops.common.expression.expression.specialFuctions.hashFiles.HashFilesFunction +import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.exception.YamlFormatException import com.tencent.devops.process.yaml.v2.exception.YamlTemplateException import com.tencent.devops.process.yaml.v2.parameter.Parameters @@ -43,8 +44,8 @@ object ParametersExpressionParse { * @param parameters 引用模板文件时传入的参数 */ fun parseTemplateParameters( - fromPath: String, - path: String, + fromPath: TemplatePath, + path: TemplatePath, template: String, templateParameters: MutableList?, parameters: Map? @@ -57,7 +58,7 @@ object ParametersExpressionParse { templateParameters.forEachIndexed { index, param -> if (param.name.contains(".")) { throw error( - Constants.PARAMETER_FORMAT_ERROR.format(path, "parameter name ${param.name} not allow contains '.'") + Constants.PARAMETER_FORMAT_ERROR.format(path.toString(), "parameter name ${param.name} not allow contains '.'") ) } @@ -74,8 +75,8 @@ object ParametersExpressionParse { if (!param.values.isNullOrEmpty() && !param.values.contains(newValue)) { throw error( Constants.VALUE_NOT_IN_ENUM.format( - fromPath, - path, + fromPath.toString(), + path.toString(), valueName, newValue, param.values.joinToString(",") @@ -99,7 +100,7 @@ object ParametersExpressionParse { if (param.default !is Iterable<*>) { throw error( Constants.PARAMETER_FORMAT_ERROR.format( - path, "parameter ${param.name} type is ${param.type} but value not" + path.toString(), "parameter ${param.name} type is ${param.type} but value not" ) ) } @@ -123,30 +124,30 @@ object ParametersExpressionParse { else -> throw error( Constants.PARAMETER_FORMAT_ERROR.format( - path, "parameter ${param.name} type ${param.type} not support" + path.toString(), "parameter ${param.name} type ${param.type} not support" ) ) } } - return parseParameterValue(path, template, expNameValues, expContext) + return parseParameterValue(path.toString(), template, expNameValues, expContext) } // 因为array的里面可能嵌套array所以先转成json再转成array - fun fromJsonToArrayContext(path: String, parameterName: String, value: Iterable<*>): ArrayContextData { + fun fromJsonToArrayContext(path: TemplatePath, parameterName: String, value: Iterable<*>): ArrayContextData { val jsonTree = try { JsonUtil.getObjectMapper().readTree(JsonUtil.toJson(value)) } catch (e: Throwable) { throw error( Constants.PARAMETER_FORMAT_ERROR.format( - path, "array parameter $parameterName value [$value] can't to json." + path.toString(), "array parameter $parameterName value [$value] can't to json." ) ) } if (!jsonTree.isArray) { throw error( Constants.PARAMETER_FORMAT_ERROR.format( - path, "array parameter $parameterName value [$value] json type [${jsonTree.nodeType}] not array." + path.toString(), "array parameter $parameterName value [$value] json type [${jsonTree.nodeType}] not array." ) ) } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/TemplateLibrary.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/TemplateLibrary.kt index d0eac425e5e..8535aa794d9 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/TemplateLibrary.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/TemplateLibrary.kt @@ -27,6 +27,7 @@ package com.tencent.devops.process.yaml.v2.parsers.template +import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.enums.TemplateType import com.tencent.devops.process.yaml.v2.models.Repositories import com.tencent.devops.process.yaml.v2.parsers.template.models.GetTemplateParam @@ -43,13 +44,13 @@ data class TemplateLibrary( // 从模板库中获得数据,如果有直接取出,没有则根据保存的库信息从远程仓库拉取,再没有则报错 fun TemplateLibrary.getTemplate( - path: String, + path: TemplatePath, templateType: TemplateType?, nowRepo: Repositories?, toRepo: Repositories? ): String { - if (templates[path] != null) { - return templates[path]!! + if (templates[path.toString()] != null) { + return templates[path.toString()]!! } // 没有库信息说明是触发库 val template = if (toRepo == null) { @@ -74,9 +75,9 @@ fun TemplateLibrary.getTemplate( ) } setTemplate(path, template) - return templates[path]!! + return templates[path.toString()]!! } -fun TemplateLibrary.setTemplate(path: String, template: String) { - templates[path] = template +fun TemplateLibrary.setTemplate(path: TemplatePath, template: String) { + templates[path.toString()] = template } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/TemplateYamlUtil.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/TemplateYamlUtil.kt index fcf0c7e0c64..9ba08b4e12c 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/TemplateYamlUtil.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/TemplateYamlUtil.kt @@ -27,6 +27,7 @@ package com.tencent.devops.process.yaml.v2.parsers.template +import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.enums.TemplateType import com.tencent.devops.process.yaml.v2.exception.YamlFormatException import com.tencent.devops.process.yaml.v2.models.Repositories @@ -43,10 +44,10 @@ object TemplateYamlUtil { // 检查是否具有重复的ID,job,variable中使用 fun checkDuplicateKey( - filePath: String, + filePath: TemplatePath, keys: Set, newKeys: Set, - toPath: String? = null + toPath: TemplatePath? = null ): Boolean { val interSet = newKeys intersect keys return if (interSet.isEmpty() || (interSet.size == 1 && interSet.last() == Constants.TEMPLATE_KEY)) { @@ -55,7 +56,7 @@ object TemplateYamlUtil { if (toPath == null) { throw error( Constants.TEMPLATE_ROOT_ID_DUPLICATE.format( - filePath, + filePath.toString(), interSet.filter { it != Constants.TEMPLATE_KEY } ) ) @@ -63,8 +64,8 @@ object TemplateYamlUtil { throw error( Constants.TEMPLATE_ID_DUPLICATE.format( interSet.filter { it != Constants.TEMPLATE_KEY }, - filePath, - toPath + filePath.toString(), + toPath.toString() ) ) } @@ -73,7 +74,7 @@ object TemplateYamlUtil { // 校验当前模板的远程库信息,每个文件只可以使用当前文件下引用的远程库 fun checkAndGetRepo( - fromPath: String, + fromPath: TemplatePath, repoName: String, templateType: TemplateType, templateLib: TemplateLibrary, @@ -111,8 +112,8 @@ object TemplateYamlUtil { */ @Deprecated("旧版本,只是为了兼容,非必要不要使用") fun parseTemplateParametersOld( - fromPath: String, - path: String, + fromPath: TemplatePath, + path: TemplatePath, template: String, templateParameters: MutableList?, parameters: Map? @@ -127,8 +128,8 @@ object TemplateYamlUtil { if (!param.values.isNullOrEmpty() && !param.values!!.contains(newValue)) { throw error( Constants.VALUE_NOT_IN_ENUM.format( - fromPath, - path, + fromPath.toString(), + path.toString(), valueName, newValue.toString(), param.values.joinToString(",") diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlObjects.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlObjects.kt index 84035513ccb..db1b000478e 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlObjects.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlObjects.kt @@ -29,8 +29,10 @@ package com.tencent.devops.process.yaml.v2.parsers.template import com.fasterxml.jackson.core.type.TypeReference import com.tencent.devops.common.api.constant.CommonMessageCode.ERROR_YAML_FORMAT_EXCEPTION_NEED_PARAM +import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.pipeline.type.agent.DockerOptions import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.enums.TemplateType import com.tencent.devops.process.yaml.v2.exception.YamlFormatException import com.tencent.devops.process.yaml.v2.models.GitNotices @@ -54,10 +56,15 @@ import com.tencent.devops.process.yaml.v2.models.step.PreStep import com.tencent.devops.process.yaml.v2.parameter.Parameters import com.tencent.devops.process.yaml.v2.parsers.template.models.TemplateDeepTreeNode import com.tencent.devops.process.yaml.v2.utils.StreamEnvUtils +import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 object YamlObjects { - fun getVariable(fromPath: String, key: String, variable: Map): Variable { + fun getTriggerOnV3(triggerOn: Map): PreTriggerOnV3 { + return JsonUtil.anyTo(triggerOn, object : TypeReference() {}) + } + + fun getVariable(fromPath: TemplatePath, key: String, variable: Map): Variable { val va = Variable( value = variable["value"]?.toString(), readonly = getNullValue("readonly", variable)?.toBoolean(), @@ -99,7 +106,7 @@ object YamlObjects { return va } - private fun getVarProps(fromPath: String, props: Any): VariableProps { + private fun getVarProps(fromPath: TemplatePath, props: Any): VariableProps { val propsMap = transValue>(fromPath, "props", props) val po = VariableProps( label = getNullValue("label", propsMap), @@ -118,7 +125,7 @@ object YamlObjects { return po } - private fun getVarPropOptions(fromPath: String, options: Any?): List? { + private fun getVarPropOptions(fromPath: TemplatePath, options: Any?): List? { if (options == null) { return null } @@ -134,7 +141,7 @@ object YamlObjects { } } - private fun getVarPropDataSource(fromPath: String, datasource: Any?): VariableDatasource? { + private fun getVarPropDataSource(fromPath: TemplatePath, datasource: Any?): VariableDatasource? { if (datasource == null) { return null } @@ -152,7 +159,7 @@ object YamlObjects { ) } - fun getStep(fromPath: String, step: Map, repo: TemplateInfo?): PreStep { + fun getStep(fromPath: TemplatePath, step: Map, repo: TemplateInfo?): PreStep { val preStep = PreStep( name = step["name"]?.toString(), id = step["id"]?.toString(), @@ -189,7 +196,7 @@ object YamlObjects { throw YamlFormatException( I18nUtil.getCodeLanMessage( messageCode = ERROR_YAML_FORMAT_EXCEPTION_NEED_PARAM, - params = arrayOf(fromPath) + params = arrayOf(fromPath.toString()) ) ) } @@ -199,7 +206,7 @@ object YamlObjects { return preStep } - fun getResourceExclusiveDeclaration(fromPath: String, resource: Any): Mutex { + fun getResourceExclusiveDeclaration(fromPath: TemplatePath, resource: Any): Mutex { val resourceMap = transValue>(fromPath, "mutex", resource) return Mutex( label = getNotNullValue(key = "label", mapName = "mutex", map = resourceMap), @@ -208,7 +215,7 @@ object YamlObjects { ) } - fun getService(fromPath: String, service: Any): Map { + fun getService(fromPath: TemplatePath, service: Any): Map { val serviceMap = transValue>(fromPath, "services", service) val newServiceMap = mutableMapOf() serviceMap.forEach { (key, value) -> @@ -228,7 +235,7 @@ object YamlObjects { return newServiceMap } - fun getContainer(fromPath: String, container: Any): Container { + fun getContainer(fromPath: TemplatePath, container: Any): Container { val containerMap = transValue>(fromPath, "container", container) return Container( image = getNotNullValue(key = "image", mapName = "Container", map = containerMap), @@ -265,7 +272,7 @@ object YamlObjects { ) } - fun getStrategy(fromPath: String, strategy: Any?): Strategy? { + fun getStrategy(fromPath: TemplatePath, strategy: Any?): Strategy? { val strategyMap = transValue>(fromPath, "strategy", strategy) val matrix = strategyMap["matrix"] ?: return null return Strategy( @@ -275,7 +282,7 @@ object YamlObjects { ) } - fun getNotice(fromPath: String, notice: Map): GitNotices { + fun getNotice(fromPath: TemplatePath, notice: Map): GitNotices { return GitNotices( type = notice["type"].toString(), title = notice["title"]?.toString(), @@ -299,7 +306,7 @@ object YamlObjects { ) } - fun getYamlMetaData(fromPath: String, yamlMetaData: Any): MetaData { + fun getYamlMetaData(fromPath: TemplatePath, yamlMetaData: Any): MetaData { val metaData = transValue>(fromPath, "yamlMetaData", yamlMetaData) if (metaData["templateInfo"] == null) { return MetaData(templateInfo = null) @@ -313,7 +320,7 @@ object YamlObjects { ) } - fun getParameter(fromPath: String, param: Map): Parameters { + fun getParameter(fromPath: TemplatePath, param: Map): Parameters { return Parameters( name = getNotNullValue(key = "name", mapName = TemplateType.PARAMETERS.text, map = param), type = getNotNullValue(key = "type", mapName = TemplateType.PARAMETERS.text, map = param), @@ -326,7 +333,7 @@ object YamlObjects { ) } - fun getResourcePools(fromPath: String, resources: Any): List { + fun getResourcePools(fromPath: TemplatePath, resources: Any): List { val resourcesD = transValue>(fromPath, "resources", resources) if (resourcesD["pools"] == null) { return emptyList() @@ -340,33 +347,33 @@ object YamlObjects { } } - inline fun getObjectFromYaml(path: String, template: String): T { + inline fun getObjectFromYaml(path: TemplatePath, template: String): T { return try { TemplateYamlMapper.getObjectMapper().readValue(template, object : TypeReference() {}) } catch (e: Exception) { - throw YamlFormatException(Constants.YAML_FORMAT_ERROR.format(path, e.message)) + throw YamlFormatException(Constants.YAML_FORMAT_ERROR.format("${path.path} ${path.ref ?: ""}", e.message)) } } - inline fun transValue(file: String, type: String, value: Any?): T { + inline fun transValue(file: TemplatePath, type: String, value: Any?): T { if (value == null) { - throw YamlFormatException(Constants.TRANS_AS_ERROR.format(file, type)) + throw YamlFormatException(Constants.TRANS_AS_ERROR.format(file.toString(), type)) } return try { value as T } catch (e: Exception) { - throw YamlFormatException(Constants.TRANS_AS_ERROR.format(file, type)) + throw YamlFormatException(Constants.TRANS_AS_ERROR.format(file.toString(), type)) } } - inline fun transNullValue(file: String, type: String, key: String, map: Map): T? { + inline fun transNullValue(file: TemplatePath, type: String, key: String, map: Map): T? { return if (map[key] == null) { null } else { return try { map[key] as T } catch (e: Exception) { - throw YamlFormatException(Constants.TRANS_AS_ERROR.format(file, type)) + throw YamlFormatException(Constants.TRANS_AS_ERROR.format(file.toString(), type)) } } } @@ -396,7 +403,11 @@ object YamlObjects { } } -fun YamlTemplate.getStage(fromPath: String, stage: Map, deepTree: TemplateDeepTreeNode): PreStage { +fun YamlTemplate.getStage( + fromPath: TemplatePath, + stage: Map, + deepTree: TemplateDeepTreeNode +): PreStage { return PreStage( name = stage["name"]?.toString(), label = stage["label"], @@ -445,7 +456,7 @@ fun YamlTemplate.getStage(fromPath: String, stage: Map, deep } // 构造对象,因为未保存远程库的template信息,所以在递归回溯时无法通过yaml文件直接生成,故手动构造 -fun YamlTemplate.getJob(fromPath: String, job: Map, deepTree: TemplateDeepTreeNode): PreJob { +fun YamlTemplate.getJob(fromPath: TemplatePath, job: Map, deepTree: TemplateDeepTreeNode): PreJob { val preJob = PreJob( name = job["name"]?.toString(), runsOn = job["runs-on"], diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlTemplate.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlTemplate.kt index 92909e596a4..120241ad291 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlTemplate.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlTemplate.kt @@ -30,11 +30,14 @@ package com.tencent.devops.process.yaml.v2.parsers.template import com.fasterxml.jackson.core.JsonProcessingException import com.tencent.devops.common.api.constant.CommonMessageCode.ERROR_YAML_FORMAT_EXCEPTION_LENGTH_LIMIT_EXCEEDED import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.process.yaml.pojo.TemplatePath +import com.tencent.devops.process.yaml.pojo.YamlVersion import com.tencent.devops.process.yaml.v2.enums.TemplateType import com.tencent.devops.process.yaml.v2.exception.YamlFormatException import com.tencent.devops.process.yaml.v2.models.Extends import com.tencent.devops.process.yaml.v2.models.GitNotices -import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYaml +import com.tencent.devops.process.yaml.v2.models.ITemplateFilter +import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYamlI import com.tencent.devops.process.yaml.v2.models.PreTemplateScriptBuildYaml import com.tencent.devops.process.yaml.v2.models.Repositories import com.tencent.devops.process.yaml.v2.models.ResourcesPools @@ -54,15 +57,17 @@ import com.tencent.devops.process.yaml.v2.stageCheck.Gate import com.tencent.devops.process.yaml.v2.stageCheck.GateTemplate import com.tencent.devops.process.yaml.v2.stageCheck.PreStageCheck import com.tencent.devops.process.yaml.v2.stageCheck.PreTemplateStageCheck +import com.tencent.devops.process.yaml.v3.models.PreScriptBuildYamlV3 +import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 @Suppress("ALL") class YamlTemplate( val extraParameters: T, // 当前文件 - var filePath: String, + var filePath: TemplatePath, // 文件对象 - var yamlObject: PreTemplateScriptBuildYaml?, + var yamlObject: ITemplateFilter?, // 当前库信息 val nowRepo: Repositories?, // 目标库信息(发起库没有库信息) @@ -75,7 +80,7 @@ class YamlTemplate( val conf: YamlTemplateConf = YamlTemplateConf(), // 来自文件 - private val fileFromPath: String? = null, + private val fileFromPath: TemplatePath? = null, // 远程模板类型(用来校验远程打平的模板的格式) private val resTemplateType: TemplateType? = null, @@ -105,11 +110,11 @@ class YamlTemplate( ) fun replace( parameters: Map? = null - ): PreScriptBuildYaml { + ): PreScriptBuildYamlI { // 针对远程库进行打平替换时,根文件没有被替换Parameters val newYamlObject = if (repo != null) { val template = parseTemplateParameters( - fromPath = fileFromPath ?: "", + fromPath = fileFromPath ?: TemplatePath(""), path = filePath, template = templateLib.getTemplate( path = filePath, @@ -126,34 +131,24 @@ class YamlTemplate( } else { templateLib.setTemplate(filePath, TemplateYamlMapper.toYaml(yamlObject!!)) yamlObject - } + } ?: throw RuntimeException("yamlObject cannot be null") - val preYamlObject = with(newYamlObject!!) { - PreScriptBuildYaml( - version = version, - name = name, - label = label, - triggerOn = triggerOn, - resources = resources, - notices = notices, - concurrency = concurrency - ) - } + val preYamlObject = newYamlObject.initPreScriptBuildYamlI() if (newYamlObject.extends != null) { - replaceExtends(newYamlObject.extends, preYamlObject, rootDeepTree) + replaceExtends(newYamlObject.extends!!, preYamlObject, rootDeepTree) } if (newYamlObject.variables != null) { - replaceVariables(newYamlObject.variables, preYamlObject, rootDeepTree) + replaceVariables(newYamlObject.variables!!, preYamlObject, rootDeepTree) } if (newYamlObject.stages != null) { - replaceStages(newYamlObject.stages, preYamlObject, rootDeepTree) + replaceStages(newYamlObject.stages!!, preYamlObject, rootDeepTree) } if (newYamlObject.jobs != null) { - replaceJobs(newYamlObject.jobs, preYamlObject, rootDeepTree) + replaceJobs(newYamlObject.jobs!!, preYamlObject, rootDeepTree) } if (newYamlObject.steps != null) { - replaceSteps(newYamlObject.steps, preYamlObject, rootDeepTree) + replaceSteps(newYamlObject.steps!!, preYamlObject, rootDeepTree) } if (newYamlObject.finally != null) { replaceFinally(newYamlObject.finally!!, preYamlObject, rootDeepTree) @@ -164,16 +159,28 @@ class YamlTemplate( private fun replaceExtends( extend: Extends, - preYamlObject: PreScriptBuildYaml, + preYamlObject: PreScriptBuildYamlI, deepTree: TemplateDeepTreeNode ) { - val toPath = extend.template + val toPath = TemplatePath(extend.template, extend.ref) val parameters = extend.parameters // 根据远程模板获取 val templateObject = replaceResAndParam(TemplateType.EXTEND, toPath, parameters, filePath, deepTree) // 获取extends模板后filePath就为被替换的文件了 this.filePath = toPath // 需要替换模板的的递归替换 + if (templateObject[TemplateType.TRIGGER_ON.content] != null) { + replaceTriggerOn( + triggerOn = YamlObjects.transValue( + file = filePath, + type = TemplateType.TRIGGER_ON.text, + value = templateObject[TemplateType.TRIGGER_ON.content] + ), + preYamlObject = preYamlObject, + deepTree = deepTree + ) + } + if (templateObject[TemplateType.VARIABLE.content] != null) { replaceVariables( variables = YamlObjects.transValue( @@ -239,9 +246,22 @@ class YamlTemplate( } } + private fun replaceTriggerOn( + triggerOn: List>, + preYamlObject: PreScriptBuildYamlI, + deepTree: TemplateDeepTreeNode + ) { + if (preYamlObject.yamlVersion() != YamlVersion.Version.V3_0) return + val triggerOnV3s = mutableListOf() + triggerOn.forEach { value -> + triggerOnV3s.add(YamlObjects.getTriggerOnV3(value)) + } + (preYamlObject as PreScriptBuildYamlV3).triggerOn = triggerOnV3s + } + private fun replaceVariables( variables: Map, - preYamlObject: PreScriptBuildYaml, + preYamlObject: PreScriptBuildYamlI, deepTree: TemplateDeepTreeNode ) { val variableMap = mutableMapOf() @@ -262,7 +282,7 @@ class YamlTemplate( private fun replaceStages( stages: List>, - preYamlObject: PreScriptBuildYaml, + preYamlObject: PreScriptBuildYamlI, deepTree: TemplateDeepTreeNode ) { val stageList = mutableListOf() @@ -274,7 +294,7 @@ class YamlTemplate( private fun replaceJobs( jobs: Map, - preYamlObject: PreScriptBuildYaml, + preYamlObject: PreScriptBuildYamlI, deepTree: TemplateDeepTreeNode ) { val jobMap = mutableMapOf() @@ -291,7 +311,7 @@ class YamlTemplate( private fun replaceSteps( steps: List>, - preYamlObject: PreScriptBuildYaml, + preYamlObject: PreScriptBuildYamlI, deepTree: TemplateDeepTreeNode ) { val stepList = mutableListOf() @@ -303,7 +323,7 @@ class YamlTemplate( private fun replaceFinally( finally: Map, - preYamlObject: PreScriptBuildYaml, + preYamlObject: PreScriptBuildYamlI, deepTree: TemplateDeepTreeNode ) { // finally: 与jobs: 的结构相同 @@ -322,7 +342,7 @@ class YamlTemplate( // 进行模板替换 private fun replaceVariableTemplate( variables: Map, - fromPath: String, + fromPath: TemplatePath, deepTree: TemplateDeepTreeNode ): Map { val variableMap = mutableMapOf() @@ -332,9 +352,13 @@ class YamlTemplate( val toPathList = YamlObjects.transValue>>(fromPath, TemplateType.VARIABLE.text, value) toPathList.forEach { item -> - val toPath = item[Constants.OBJECT_TEMPLATE_PATH].toString() + val toPath = TemplatePath( + item[Constants.OBJECT_TEMPLATE_PATH].toString(), item[Constants.REF]?.toString() + ) // 保存并检查是否存在循环引用模板 - templateGraph.saveAndCheckCyclicTemplate(fromPath, toPath, TemplateType.VARIABLE) + templateGraph.saveAndCheckCyclicTemplate( + fromPath.toString(), toPath.toString(), TemplateType.VARIABLE + ) // 获取需要替换的变量 val parameters = YamlObjects.transNullValue>( file = fromPath, @@ -382,14 +406,16 @@ class YamlTemplate( private fun replaceStageTemplate( stages: List>, - fromPath: String, + fromPath: TemplatePath, deepTree: TemplateDeepTreeNode ): List { val stageList = mutableListOf() stages.forEach { stage -> if (Constants.TEMPLATE_KEY in stage.keys) { - val toPath = stage[Constants.TEMPLATE_KEY].toString() - templateGraph.saveAndCheckCyclicTemplate(fromPath, toPath, TemplateType.STAGE) + val toPath = TemplatePath( + stage[Constants.TEMPLATE_KEY].toString(), stage[Constants.REF]?.toString() + ) + templateGraph.saveAndCheckCyclicTemplate(fromPath.toString(), toPath.toString(), TemplateType.STAGE) val parameters = YamlObjects.transNullValue>( file = fromPath, @@ -419,7 +445,7 @@ class YamlTemplate( fun replaceJobTemplate( jobs: Map, - fromPath: String, + fromPath: TemplatePath, deepTree: TemplateDeepTreeNode ): Map { val jobMap = mutableMapOf() @@ -427,8 +453,10 @@ class YamlTemplate( if (key == Constants.TEMPLATE_KEY) { val toPathList = YamlObjects.transValue>>(fromPath, TemplateType.JOB.text, value) toPathList.forEach { item -> - val toPath = item[Constants.OBJECT_TEMPLATE_PATH].toString() - templateGraph.saveAndCheckCyclicTemplate(fromPath, toPath, TemplateType.JOB) + val toPath = TemplatePath( + item[Constants.OBJECT_TEMPLATE_PATH].toString(), item[Constants.REF]?.toString() + ) + templateGraph.saveAndCheckCyclicTemplate(fromPath.toString(), toPath.toString(), TemplateType.JOB) val parameters = YamlObjects.transNullValue>( file = fromPath, @@ -462,7 +490,7 @@ class YamlTemplate( throw YamlFormatException( I18nUtil.getCodeLanMessage( messageCode = ERROR_YAML_FORMAT_EXCEPTION_LENGTH_LIMIT_EXCEEDED, - params = arrayOf(fromPath, key) + params = arrayOf(fromPath.toString(), key) ) ) } @@ -474,15 +502,17 @@ class YamlTemplate( fun replaceStepTemplate( steps: List>, - fromPath: String, + fromPath: TemplatePath, deepTree: TemplateDeepTreeNode ): List { val stepList = mutableListOf() steps.forEach { step -> if (Constants.TEMPLATE_KEY in step.keys) { - val toPath = step[Constants.TEMPLATE_KEY].toString() + val toPath = TemplatePath( + step[Constants.TEMPLATE_KEY].toString(), step[Constants.REF]?.toString() + ) - templateGraph.saveAndCheckCyclicTemplate(fromPath, toPath, TemplateType.STEP) + templateGraph.saveAndCheckCyclicTemplate(fromPath.toString(), toPath.toString(), TemplateType.STEP) val parameters = YamlObjects.transNullValue>( file = fromPath, @@ -525,7 +555,7 @@ class YamlTemplate( fun replaceStageCheckTemplate( stageName: String, check: Map?, - fromPath: String, + fromPath: TemplatePath, deepTree: TemplateDeepTreeNode ): PreStageCheck? { if (check == null) { @@ -550,7 +580,7 @@ class YamlTemplate( YamlObjects.getObjectFromYaml(fromPath, TemplateYamlMapper.toYaml(check)) checkObject.gates?.forEach { gate -> - val toPath = gate.template + val toPath = TemplatePath(gate.template, gate.ref) val templateObject = replaceResAndParam( templateType = TemplateType.GATE, toPath = toPath, @@ -582,25 +612,28 @@ class YamlTemplate( // 替换远程库和参数信息 private fun replaceResAndParam( templateType: TemplateType, - toPath: String, + toPath: TemplatePath, parameters: Map?, - fromPath: String, + fromPath: TemplatePath, deepTree: TemplateDeepTreeNode ): Map { // 判断是否为远程库,如果是远程库将其远程库文件打平进行替换 - var newTemplate = if (toPath.contains(Constants.FILE_REPO_SPLIT)) { + var newTemplate = if (toPath.path.contains(Constants.FILE_REPO_SPLIT)) { // 针对没有循环嵌套做特殊处理 if (templateType == TemplateType.GATE || templateType == TemplateType.PARAMETERS) { templateLib.getTemplate( - path = toPath.split(Constants.FILE_REPO_SPLIT).first(), + path = TemplatePath( + path = toPath.path.split(Constants.FILE_REPO_SPLIT).first(), + ref = toPath.ref + ), nowRepo = repo, toRepo = TemplateYamlUtil.checkAndGetRepo( fromPath = fromPath, - repoName = toPath.split(Constants.FILE_REPO_SPLIT)[1], + repoName = toPath.path.split(Constants.FILE_REPO_SPLIT)[1], templateType = templateType, templateLib = templateLib, nowRepo = nowRepo, - toRepo = repo + toRepo = repo, ), templateType = templateType ) @@ -611,7 +644,7 @@ class YamlTemplate( parameters = parameters, toRepo = TemplateYamlUtil.checkAndGetRepo( fromPath = fromPath, - repoName = toPath.split(Constants.FILE_REPO_SPLIT)[1], + repoName = toPath.path.split(Constants.FILE_REPO_SPLIT)[1], templateType = templateType, templateLib = templateLib, nowRepo = nowRepo, @@ -652,18 +685,20 @@ class YamlTemplate( // 对远程仓库中的模板进行远程仓库替换 private fun replaceResTemplateFile( templateType: TemplateType, - toPath: String, + toPath: TemplatePath, parameters: Map?, toRepo: Repositories, deepTree: TemplateDeepTreeNode ): String { // 判断是否有库之间的循环依赖 - templateGraph.saveAndCheckCyclicRepo(fromPath = filePath, repo = repo, toRepo = toRepo) + templateGraph.saveAndCheckCyclicRepo(fromPath = filePath.toString(), repo = repo, toRepo = toRepo) val resYamlObject = YamlTemplate( yamlObject = null, fileFromPath = filePath, - filePath = toPath.split(Constants.FILE_REPO_SPLIT)[0], + filePath = TemplatePath( + toPath.path.split(Constants.FILE_REPO_SPLIT)[0], toPath.path + ), extraParameters = extraParameters, nowRepo = repo, repo = toRepo, @@ -687,8 +722,8 @@ class YamlTemplate( // 在parameters替换前做统一处理,例如替换模板 private fun parseTemplateParameters( - fromPath: String, - path: String, + fromPath: TemplatePath, + path: TemplatePath, template: String, parameters: Map?, deepTree: TemplateDeepTreeNode @@ -701,7 +736,9 @@ class YamlTemplate( preTemplateParam?.forEach { preParam -> if (Constants.TEMPLATE_KEY in preParam) { - val toPath = preParam[Constants.TEMPLATE_KEY].toString() + val toPath = TemplatePath( + preParam[Constants.TEMPLATE_KEY].toString(), preParam[Constants.REF]?.toString() + ) // 因为这里是替换模板的模板参数,所以frompath需要使用模板文件而不是来源文件 val templateObject = replaceResAndParam( templateType = TemplateType.PARAMETERS, diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/models/GetTemplateParam.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/models/GetTemplateParam.kt index 5194dc4c950..e3cad38f828 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/models/GetTemplateParam.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/models/GetTemplateParam.kt @@ -27,6 +27,7 @@ package com.tencent.devops.process.yaml.v2.parsers.template.models +import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.enums.TemplateType import com.tencent.devops.process.yaml.v2.models.Repositories @@ -39,7 +40,7 @@ import com.tencent.devops.process.yaml.v2.models.Repositories * @param extraParameters 额外参数,由各个服务具体定义 */ data class GetTemplateParam( - val path: String, + val path: TemplatePath, val templateType: TemplateType?, val nowRepoId: String?, val targetRepo: Repositories?, diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/models/TemplateDeepTreeNode.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/models/TemplateDeepTreeNode.kt index c6412e1868a..369e4293aba 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/models/TemplateDeepTreeNode.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/models/TemplateDeepTreeNode.kt @@ -27,10 +27,11 @@ package com.tencent.devops.process.yaml.v2.parsers.template.models +import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.exception.YamlFormatException class TemplateDeepTreeNode( - val path: String, + val path: TemplatePath, val parent: TemplateDeepTreeNode?, val children: MutableList ) { @@ -45,7 +46,7 @@ class TemplateDeepTreeNode( "[%s]The template nesting depth exceeds the threshold [$MAX_TEMPLATE_DEEP}]" } - fun add(nodePath: String): TemplateDeepTreeNode { + fun add(nodePath: TemplatePath): TemplateDeepTreeNode { val node = TemplateDeepTreeNode( path = nodePath, parent = this, diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/ScriptYmlUtils.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/ScriptYmlUtils.kt index ed74c8e3599..f58cf291ecb 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/ScriptYmlUtils.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/ScriptYmlUtils.kt @@ -50,11 +50,13 @@ import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.api.util.UUIDUtil import com.tencent.devops.common.api.util.YamlUtil import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.process.yaml.modelTransfer.TransferMapper import com.tencent.devops.process.yaml.v2.enums.StreamMrEventAction import com.tencent.devops.process.yaml.v2.enums.TemplateType import com.tencent.devops.process.yaml.v2.exception.YamlFormatException import com.tencent.devops.process.yaml.v2.models.PreRepositoryHook import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYaml +import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYamlI import com.tencent.devops.process.yaml.v2.models.RepositoryHook import com.tencent.devops.process.yaml.v2.models.ScriptBuildYaml import com.tencent.devops.process.yaml.v2.models.YamlTransferData @@ -69,6 +71,7 @@ import com.tencent.devops.process.yaml.v2.models.job.RunsOn import com.tencent.devops.process.yaml.v2.models.job.Service import com.tencent.devops.process.yaml.v2.models.on.DeleteRule import com.tencent.devops.process.yaml.v2.models.on.EnableType +import com.tencent.devops.process.yaml.v2.models.on.IPreTriggerOn import com.tencent.devops.process.yaml.v2.models.on.IssueRule import com.tencent.devops.process.yaml.v2.models.on.MrRule import com.tencent.devops.process.yaml.v2.models.on.NoteRule @@ -88,12 +91,13 @@ import com.tencent.devops.process.yaml.v2.stageCheck.Flow import com.tencent.devops.process.yaml.v2.stageCheck.PreStageCheck import com.tencent.devops.process.yaml.v2.stageCheck.StageCheck import com.tencent.devops.process.yaml.v2.stageCheck.StageReviews +import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 +import org.apache.commons.text.StringEscapeUtils +import org.slf4j.LoggerFactory import java.io.BufferedReader import java.io.StringReader import java.util.Random import java.util.regex.Pattern -import org.apache.commons.text.StringEscapeUtils -import org.slf4j.LoggerFactory @Suppress("MaximumLineLength", "ComplexCondition") object ScriptYmlUtils { @@ -116,9 +120,9 @@ object ScriptYmlUtils { @Throws(JsonProcessingException::class) fun formatYaml(yamlStr: String): String { // replace custom tag - val yamlNormal = formatYamlCustom(yamlStr) +// val yamlNormal = formatYamlCustom(yamlStr) // replace anchor tag - return YamlUtil.loadYamlRetryOnAccident(yamlNormal) + return TransferMapper.formatYaml(yamlStr) } fun parseVersion(yamlStr: String?): YmlVersion? { @@ -288,7 +292,7 @@ object ScriptYmlUtils { return sb.toString() } - fun formatStage(preScriptBuildYaml: PreScriptBuildYaml, transferData: YamlTransferData?): List { + fun formatStage(preScriptBuildYaml: PreScriptBuildYamlI, transferData: YamlTransferData? = null): List { return when { preScriptBuildYaml.steps != null -> { val jobId = randomString(jobNamespace) @@ -324,7 +328,7 @@ object ScriptYmlUtils { } } - fun preJobs2Jobs(preJobs: Map?, transferData: YamlTransferData?): List { + fun preJobs2Jobs(preJobs: Map?, transferData: YamlTransferData? = null): List { if (preJobs == null) { return emptyList() } @@ -452,32 +456,38 @@ object ScriptYmlUtils { // 检测step env合法性 StreamEnvUtils.checkEnv(preStep.env) - val taskId = "e-${UUIDUtil.generate()}" stepList.add( - Step( - name = preStep.name, - id = preStep.id, - ifFiled = preStep.ifFiled, - ifModify = preStep.ifModify, - uses = preStep.uses, - with = preStep.with, - timeoutMinutes = preStep.timeoutMinutes, - continueOnError = preStep.continueOnError, - retryTimes = preStep.retryTimes, - env = preStep.env, - run = preStep.run, - runAdditionalOptions = mapOf("shell" to preStep.shell), - checkout = preStep.checkout, - taskId = taskId - ) + preStepToStep(preStep, transferData) ) - - transferData?.add(taskId, TemplateType.STEP, preStep.yamlMetaData?.templateInfo?.remoteTemplateProjectId) } return stepList } + fun preStepToStep( + preStep: PreStep, + transferData: YamlTransferData? = null + ): Step { + val taskId = "e-${UUIDUtil.generate()}" + transferData?.add(taskId, TemplateType.STEP, preStep.yamlMetaData?.templateInfo?.remoteTemplateProjectId) + return Step( + name = preStep.name, + id = preStep.id, + ifFiled = preStep.ifFiled, + ifModify = preStep.ifModify, + uses = preStep.uses, + with = preStep.with, + timeoutMinutes = preStep.timeoutMinutes, + continueOnError = preStep.continueOnError, + retryTimes = preStep.retryTimes, + env = preStep.env, + run = preStep.run, + runAdditionalOptions = mapOf("shell" to preStep.shell), + checkout = preStep.checkout, + taskId = taskId + ) + } + private fun preStages2Stages(preStageList: List?, transferData: YamlTransferData?): List { if (preStageList == null) { return emptyList() @@ -595,14 +605,14 @@ object ScriptYmlUtils { ) } - fun formatRepoHookTriggerOn(preTriggerOn: PreTriggerOn?, name: String?): TriggerOn? { + fun formatRepoHookTriggerOn(preTriggerOn: IPreTriggerOn?, name: String?): TriggerOn? { if (preTriggerOn?.repoHook == null) { return null } val repositoryHookList = try { YamlUtil.getObjectMapper().readValue( - JsonUtil.toJson(preTriggerOn.repoHook), + JsonUtil.toJson(preTriggerOn.repoHook!!), object : TypeReference>() {} ) } catch (e: MismatchedInputException) { @@ -655,7 +665,7 @@ object ScriptYmlUtils { return null } - fun formatTriggerOn(preTriggerOn: PreTriggerOn?): TriggerOn { + fun formatTriggerOn(preTriggerOn: IPreTriggerOn?): TriggerOn { if (preTriggerOn == null) { return TriggerOn( @@ -675,8 +685,7 @@ object ScriptYmlUtils { ) ) } - - return TriggerOn( + val res = TriggerOn( push = pushRule(preTriggerOn), tag = tagRule(preTriggerOn), mr = mrRule(preTriggerOn), @@ -688,6 +697,13 @@ object ScriptYmlUtils { manual = manualRule(preTriggerOn), openapi = openapiRule(preTriggerOn) ) + + if (preTriggerOn is PreTriggerOnV3) { + res.name = preTriggerOn.name + res.credentials = preTriggerOn.credentials + } + + return res } fun repoHookRule( @@ -728,7 +744,7 @@ object ScriptYmlUtils { } private fun manualRule( - preTriggerOn: PreTriggerOn + preTriggerOn: IPreTriggerOn ): String? { if (preTriggerOn.manual == null) { return null @@ -742,7 +758,7 @@ object ScriptYmlUtils { } private fun openapiRule( - preTriggerOn: PreTriggerOn + preTriggerOn: IPreTriggerOn ): String? { if (preTriggerOn.openapi == null) { return null @@ -756,10 +772,10 @@ object ScriptYmlUtils { } private fun noteRule( - preTriggerOn: PreTriggerOn + preTriggerOn: IPreTriggerOn ): NoteRule? { if (preTriggerOn.note != null) { - val note = preTriggerOn.note + val note = preTriggerOn.note!! return try { YamlUtil.getObjectMapper().readValue( JsonUtil.toJson(note), @@ -773,10 +789,10 @@ object ScriptYmlUtils { } private fun reviewRule( - preTriggerOn: PreTriggerOn + preTriggerOn: IPreTriggerOn ): ReviewRule? { if (preTriggerOn.review != null) { - val issues = preTriggerOn.review + val issues = preTriggerOn.review!! return try { YamlUtil.getObjectMapper().readValue( JsonUtil.toJson(issues), @@ -790,10 +806,10 @@ object ScriptYmlUtils { } private fun issueRule( - preTriggerOn: PreTriggerOn + preTriggerOn: IPreTriggerOn ): IssueRule? { if (preTriggerOn.issue != null) { - val issues = preTriggerOn.issue + val issues = preTriggerOn.issue!! return try { YamlUtil.getObjectMapper().readValue( JsonUtil.toJson(issues), @@ -807,10 +823,10 @@ object ScriptYmlUtils { } private fun deleteRule( - preTriggerOn: PreTriggerOn + preTriggerOn: IPreTriggerOn ): DeleteRule? { if (preTriggerOn.delete != null) { - val delete = preTriggerOn.delete + val delete = preTriggerOn.delete!! return try { YamlUtil.getObjectMapper().readValue( JsonUtil.toJson(delete), @@ -824,10 +840,10 @@ object ScriptYmlUtils { } private fun schedulesRule( - preTriggerOn: PreTriggerOn + preTriggerOn: IPreTriggerOn ): SchedulesRule? { if (preTriggerOn.schedules != null) { - val schedules = preTriggerOn.schedules + val schedules = preTriggerOn.schedules!! return try { YamlUtil.getObjectMapper().readValue( JsonUtil.toJson(schedules), @@ -841,10 +857,10 @@ object ScriptYmlUtils { } private fun mrRule( - preTriggerOn: PreTriggerOn + preTriggerOn: IPreTriggerOn ): MrRule? { if (preTriggerOn.mr != null) { - val mr = preTriggerOn.mr + val mr = preTriggerOn.mr!! return try { YamlUtil.getObjectMapper().readValue( JsonUtil.toJson(mr), @@ -874,10 +890,10 @@ object ScriptYmlUtils { } private fun tagRule( - preTriggerOn: PreTriggerOn + preTriggerOn: IPreTriggerOn ): TagRule? { if (preTriggerOn.tag != null) { - val tag = preTriggerOn.tag + val tag = preTriggerOn.tag!! return try { YamlUtil.getObjectMapper().readValue( JsonUtil.toJson(tag), @@ -906,10 +922,10 @@ object ScriptYmlUtils { } private fun pushRule( - preTriggerOn: PreTriggerOn + preTriggerOn: IPreTriggerOn ): PushRule? { if (preTriggerOn.push != null) { - val push = preTriggerOn.push + val push = preTriggerOn.push!! return try { YamlUtil.getObjectMapper().readValue( JsonUtil.toJson(push), diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/StreamEnvUtils.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/StreamEnvUtils.kt index 43977e8841a..31c3b4bd06d 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/StreamEnvUtils.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/StreamEnvUtils.kt @@ -30,10 +30,11 @@ package com.tencent.devops.process.yaml.v2.utils import com.tencent.devops.common.api.constant.CommonMessageCode.ERROR_YAML_FORMAT_EXCEPTION_ENV_QUANTITY_LIMIT_EXCEEDED import com.tencent.devops.common.api.constant.CommonMessageCode.ERROR_YAML_FORMAT_EXCEPTION_ENV_VARIABLE_LENGTH_LIMIT_EXCEEDED import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.exception.YamlFormatException object StreamEnvUtils { - fun checkEnv(env: Map?, fileName: String? = null): Boolean { + fun checkEnv(env: Map?, fileName: TemplatePath? = null): Boolean { if (env != null) { if (env.size > 100) { throw YamlFormatException( diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreScriptBuildYamlV3.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreScriptBuildYamlV3.kt new file mode 100644 index 00000000000..f01aecdf956 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreScriptBuildYamlV3.kt @@ -0,0 +1,69 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.process.yaml.pojo.YamlVersion +import com.tencent.devops.process.yaml.v2.models.Concurrency +import com.tencent.devops.process.yaml.v2.models.Extends +import com.tencent.devops.process.yaml.v2.models.GitNotices +import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYamlI +import com.tencent.devops.process.yaml.v2.models.Resources +import com.tencent.devops.process.yaml.v2.models.Variable +import com.tencent.devops.process.yaml.v2.models.job.PreJob +import com.tencent.devops.process.yaml.v2.models.stage.PreStage +import com.tencent.devops.process.yaml.v2.models.step.PreStep +import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 + +/** + * model + * + * WARN: 请谨慎修改这个类 , 不要随意添加或者删除变量 , 否则可能导致依赖yaml的功能(stream,prebuild等)异常 + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class PreScriptBuildYamlV3( + override var version: String?, + override var name: String?, + override var label: List? = null, + @JsonProperty("on") + var triggerOn: List?, + override var variables: Map? = null, + override var stages: List? = null, + override var jobs: Map? = null, + override var steps: List? = null, + override var extends: Extends? = null, + override var resources: Resources?, + override var notices: List?, + override var finally: Map? = null, + override val concurrency: Concurrency? = null +) : PreScriptBuildYamlI { + override fun yamlVersion() = YamlVersion.Version.V3_0 +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYamlV3.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYamlV3.kt new file mode 100644 index 00000000000..68b3480d317 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYamlV3.kt @@ -0,0 +1,120 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +import com.fasterxml.jackson.annotation.JsonIgnore +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.process.yaml.pojo.YamlVersion +import com.tencent.devops.process.yaml.v2.models.Concurrency +import com.tencent.devops.process.yaml.v2.models.Extends +import com.tencent.devops.process.yaml.v2.models.GitNotices +import com.tencent.devops.process.yaml.v2.models.IPreTemplateScriptBuildYaml +import com.tencent.devops.process.yaml.v2.models.ITemplateFilter +import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYamlI +import com.tencent.devops.process.yaml.v2.models.Resources +import com.tencent.devops.process.yaml.v2.models.Variable +import com.tencent.devops.process.yaml.v2.models.YamlTransferData +import com.tencent.devops.process.yaml.v2.models.job.Job +import com.tencent.devops.process.yaml.v2.models.on.TriggerOn +import com.tencent.devops.process.yaml.v2.models.stage.Stage +import com.tencent.devops.process.yaml.v2.utils.ScriptYmlUtils +import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class PreTemplateScriptBuildYamlV3( + override val version: String?, + override val name: String?, + override val label: List? = null, + @JsonProperty("on") + var triggerOn: List?, + override val variables: Map?, + override val stages: List>?, + override val jobs: Map? = null, + override val steps: List>? = null, + override val extends: Extends?, + override val resources: Resources?, + override val notices: List?, + override var finally: Map?, + override val concurrency: Concurrency? = null +) : IPreTemplateScriptBuildYaml, ITemplateFilter { + override fun yamlVersion() = YamlVersion.Version.V3_0 + + override fun initPreScriptBuildYamlI(): PreScriptBuildYamlI { + return PreScriptBuildYamlV3( + version = version, + name = name, + label = label, + triggerOn = triggerOn, + resources = resources, + notices = notices, + concurrency = concurrency + ) + } + + @JsonIgnore + lateinit var preYaml: PreScriptBuildYamlV3 + + @JsonIgnore + val transferData: YamlTransferData = YamlTransferData() + + override fun replaceTemplate(f: (param: ITemplateFilter) -> PreScriptBuildYamlI) { + preYaml = f(this) as PreScriptBuildYamlV3 + } + + override fun formatVariables(): Map { + checkInitialized() + return preYaml.variables ?: emptyMap() + } + + override fun formatTriggerOn(default: ScmType): Map { + return triggerOn?.associateBy({ it.type ?: default }, { ScriptYmlUtils.formatTriggerOn(it) }) ?: emptyMap() + } + + override fun formatStages(): List { + checkInitialized() + return ScriptYmlUtils.formatStage(preYaml, transferData) + } + + override fun formatFinallyStage(): List { + checkInitialized() + return ScriptYmlUtils.preJobs2Jobs(preYaml.finally, transferData) + } + + override fun formatResources(): Resources? { + checkInitialized() + return preYaml.resources + } + + private fun checkInitialized() { + if (!this::preYaml.isInitialized) throw RuntimeException("need replaceTemplate before") + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/ScriptBuildYamlV3.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/ScriptBuildYamlV3.kt new file mode 100644 index 00000000000..b47ce07f1ad --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/ScriptBuildYamlV3.kt @@ -0,0 +1,63 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.tencent.devops.process.yaml.pojo.YamlVersion +import com.tencent.devops.process.yaml.v2.models.Concurrency +import com.tencent.devops.process.yaml.v2.models.Extends +import com.tencent.devops.process.yaml.v2.models.GitNotices +import com.tencent.devops.process.yaml.v2.models.Resources +import com.tencent.devops.process.yaml.v2.models.Variable +import com.tencent.devops.process.yaml.v2.models.job.Job +import com.tencent.devops.process.yaml.v2.models.on.TriggerOn +import com.tencent.devops.process.yaml.v2.models.stage.Stage + +/** + * model + * + * WARN: 请谨慎修改这个类 , 不要随意添加或者删除变量 , 否则可能导致依赖yaml的功能(gitci,prebuild等)异常 + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class ScriptBuildYamlV3( + val version: String?, + val name: String?, + val label: List?, + val triggerOn: List?, + val variables: Map?, + val stages: List, + val extends: Extends?, + val resource: Resources?, + val notices: List?, + var finally: List?, + val concurrency: Concurrency? +) : YamlVersion { + override fun yamlVersion() = YamlVersion.Version.V3_0 +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PreTriggerOnV3.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PreTriggerOnV3.kt new file mode 100644 index 00000000000..b8a4c91e4f4 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PreTriggerOnV3.kt @@ -0,0 +1,65 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.on + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.process.yaml.pojo.YamlVersion +import com.tencent.devops.process.yaml.v2.models.on.DeleteRule +import com.tencent.devops.process.yaml.v2.models.on.IPreTriggerOn +import com.tencent.devops.process.yaml.v2.models.on.IssueRule +import com.tencent.devops.process.yaml.v2.models.on.NoteRule +import com.tencent.devops.process.yaml.v2.models.on.ReviewRule +import com.tencent.devops.process.yaml.v2.models.on.SchedulesRule +import io.swagger.annotations.ApiModelProperty + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class PreTriggerOnV3( + val name: String?, + var repoHashId: String?, + var type: ScmType?, + val credentials: String?, + override val push: Any?, + override val tag: Any?, + override val mr: Any?, + override val schedules: SchedulesRule?, + override val delete: DeleteRule?, + override val issue: IssueRule? = null, + override val review: ReviewRule? = null, + override val note: NoteRule? = null, + @ApiModelProperty(name = "repo_hook") + @JsonProperty("repo_hook") + override val repoHook: List? = null, + override val manual: String? = null, + override val openapi: String? = null +) : IPreTriggerOn { + override fun yamlVersion() = YamlVersion.Version.V3_0 +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/kotlin/com/tencent/devops/process/yaml/modelTransfer/MergeYamlTest.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/test/kotlin/com/tencent/devops/process/yaml/modelTransfer/MergeYamlTest.kt new file mode 100644 index 00000000000..b3fbf570495 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/kotlin/com/tencent/devops/process/yaml/modelTransfer/MergeYamlTest.kt @@ -0,0 +1,55 @@ +package com.tencent.devops.process.yaml.modelTransfer + +import org.junit.jupiter.api.Assertions +import org.junit.jupiter.api.Test +import org.junit.jupiter.params.ParameterizedTest +import org.junit.jupiter.params.provider.ValueSource +import org.springframework.core.io.ClassPathResource +import java.io.BufferedReader +import java.io.InputStream +import java.io.InputStreamReader + +class MergeYamlTest { + private fun yamlPath(p: String) = "TransferYaml/$p" + + private fun getStrFromResource(testYaml: String): String { + val classPathResource = ClassPathResource(testYaml) + val inputStream: InputStream = classPathResource.inputStream + val isReader = InputStreamReader(inputStream) + + val reader = BufferedReader(isReader) + val sb = StringBuffer() + var str: String? + while (reader.readLine().also { str = it } != null) { + sb.append(str).append("\n") + } + inputStream.close() + return sb.toString() + } + + @ParameterizedTest + @ValueSource( + strings = [ + "base-1", + "base-2" + ] + ) + fun base(value: String) { + val new = getStrFromResource(yamlPath("$value/new.yml")) + val old = getStrFromResource(yamlPath("$value/old.yml")) + val out = getStrFromResource(yamlPath("$value/out.yml")) + + val m = TransferMapper.mergeYaml(old, new) + Assertions.assertEquals(m, out) + } + + @Test + fun base2() { + val new = getStrFromResource(yamlPath("base-2/new.yml")) + val old = getStrFromResource(yamlPath("base-2/old.yml")) + val out = getStrFromResource(yamlPath("base-2/out.yml")) + + val m = TransferMapper.mergeYaml(old, new) + Assertions.assertEquals(m, out) + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/kotlin/com/tencent/devops/process/yaml/parsers/template/YamlTemplateTest.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/test/kotlin/com/tencent/devops/process/yaml/parsers/template/YamlTemplateTest.kt index 2f73a12452a..bb80f2aae54 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/test/kotlin/com/tencent/devops/process/yaml/parsers/template/YamlTemplateTest.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/kotlin/com/tencent/devops/process/yaml/parsers/template/YamlTemplateTest.kt @@ -28,7 +28,8 @@ package com.tencent.devops.process.yaml.parsers.template import com.tencent.devops.common.api.util.JsonUtil -import com.tencent.devops.common.api.util.YamlUtil +import com.tencent.devops.process.yaml.modelTransfer.TransferMapper +import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.exception.YamlFormatException import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYaml import com.tencent.devops.process.yaml.v2.models.PreTemplateScriptBuildYaml @@ -267,9 +268,9 @@ variables: } else { getStrFromResource( "compared/${ - file.removePrefix("samples") - .replace("_old.yml", ".yml") - .replace(".yml", "_old.yml") + file.removePrefix("samples") + .replace("_old.yml", ".yml") + .replace(".yml", "_old.yml") }" ) } @@ -313,12 +314,14 @@ variables: val sb = yamlContent ?: getStrFromResource(testYaml!!) val yaml = ScriptYmlUtils.formatYaml(sb) - val preTemplateYamlObject = YamlUtil.getObjectMapper().readValue(yaml, PreTemplateScriptBuildYaml::class.java) + val preTemplateYamlObject = TransferMapper.getObjectMapper().readValue( + yaml, PreTemplateScriptBuildYaml::class.java + ) preTemplateYamlObject.resources?.pools?.forEach { pool -> resourceExt?.put(pool.format(), pool) } val preScriptBuildYaml = YamlTemplate( - filePath = "", + filePath = TemplatePath(""), yamlObject = preTemplateYamlObject, extraParameters = null, getTemplateMethod = ::getTestTemplate, @@ -326,12 +329,12 @@ variables: repo = null, resourcePoolMapExt = resourceExt, conf = YamlTemplateConf(useOldParametersExpression = useOldParametersExpression) - ).replace() + ).replace() as PreScriptBuildYaml if (!normalized) { return preScriptBuildYaml } val (normalOb, trans) = ScriptYmlUtils.normalizeGitCiYaml(preScriptBuildYaml, "") - val yamls = YamlUtil.toYaml(normalOb) + val yamls = TransferMapper.toYaml(normalOb) println("------------ Trans -----------") println(JsonUtil.toJson(trans)) println("------------------------") @@ -342,11 +345,12 @@ variables: param: GetTemplateParam ): String { val newPath = if (param.targetRepo == null) { - "templates/${param.path}" + "templates/${param.path.path}" } else { - "templates/${param.targetRepo!!.repository}/templates/${param.path}" + "templates/${param.targetRepo!!.repository}/templates/${param.path.path}" } val sb = getStrFromResource(newPath) + println(newPath) return ScriptYmlUtils.formatYaml(sb) } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/ParametersExpressionParseTest.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/test/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/ParametersExpressionParseTest.kt index 62366dfc03a..f86faa90dc7 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/test/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/ParametersExpressionParseTest.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/ParametersExpressionParseTest.kt @@ -37,6 +37,7 @@ import com.tencent.devops.common.expression.context.ExpressionContextData import com.tencent.devops.common.expression.context.NumberContextData import com.tencent.devops.common.expression.context.StringContextData import com.tencent.devops.common.expression.expression.sdk.NamedValueInfo +import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.parsers.template.models.ExpressionBlock import org.junit.jupiter.api.Assertions import org.junit.jupiter.api.BeforeAll @@ -75,7 +76,7 @@ internal class ParametersExpressionParseTest { } ) } - val result = ParametersExpressionParse.fromJsonToArrayContext("", "lll", testData) + val result = ParametersExpressionParse.fromJsonToArrayContext(TemplatePath(""), "lll", testData) Assertions.assertTrue(expectDate.toJson() == result.toJson()) } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-1/new.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-1/new.yml new file mode 100644 index 00000000000..c4fd777fab7 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-1/new.yml @@ -0,0 +1,21 @@ +a: +- sad +- run: | + asdasd \n + asdsd + +db1: + port: 3306 + name: admin + pwd: 123456ssssdasd改变 + pwd改变: 123456ssssd改变 +db2: + port: 3307 + name: admin + pwd: 123456ssssdasd改变 + pwd改变: 123456ssssd改变 +db23: + port2: 3308 + name: admin2 + pwd: 123456ssssdasd改变 + pwd改变: 123456ssssd改变 \ No newline at end of file diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-1/old.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-1/old.yml new file mode 100644 index 00000000000..08638de8aaa --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-1/old.yml @@ -0,0 +1,23 @@ +# ttttttt1 +a: &d2 +- run: | + asdasd \n + asdsd +- run: asdasdasd #sdasdasd4 + # ttttttt5 +- asd +- - - sad + +b: *d2 + +# ttttttt6 +db1: &d1-confs + port: 3306 # ttttttt7 + name: admin + # ttttttt8 + pwd: 123456 +# ttttttt9 +db2: # ttttttt10 + port: 3307 + # ttttttt11 + <<: *d1-confs \ No newline at end of file diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-1/out.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-1/out.yml new file mode 100644 index 00000000000..4ec423645cf --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-1/out.yml @@ -0,0 +1,25 @@ +# ttttttt1 +a: &d2 +- sad +- run: | + asdasd \n + asdsd +#sdasdasd4 +# ttttttt5 + +# ttttttt6 +db1: &d1-confs + port: 3306 # ttttttt7 + name: admin + # ttttttt8 + pwd: 123456ssssdasd改变 + pwd改变: 123456ssssd改变 +# ttttttt9 +db2: # ttttttt10 + port: 3307 + <<: *d1-confs +db23: + port2: 3308 + name: admin2 + pwd: 123456ssssdasd改变 + pwd改变: 123456ssssd改变 \ No newline at end of file diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-2/new.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-2/new.yml new file mode 100644 index 00000000000..1edb64fc0ad --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-2/new.yml @@ -0,0 +1,9 @@ +type: Example config改 +components: +- name: First component + description: Some short description of the first component改 +- name: Second component + description: Some short description of the second component改 +- - first/possible/place + - second/possible/place改 +- { jsonStyle: [ { x: y改 }, { x: z } ] } \ No newline at end of file diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-2/old.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-2/old.yml new file mode 100644 index 00000000000..af6e929a328 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-2/old.yml @@ -0,0 +1,15 @@ +type: Example config + + +components: +- name: First component + description: Some short description of the first component + +- # Comment for the second component + name: Second component + description: Some short description of the second component + +# A list of possible places the third component could be got from +- - first/possible/place + - second/possible/place +- { jsonStyle: [ { x: y }, { x: z } ] } \ No newline at end of file diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-2/out.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-2/out.yml new file mode 100644 index 00000000000..1f070290b03 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/TransferYaml/base-2/out.yml @@ -0,0 +1,15 @@ +type: Example config改 + + +components: +- name: First component + description: Some short description of the first component改 +- +# Comment for the second component + name: Second component + description: Some short description of the second component改 +- - +# A list of possible places the third component could be got from + first/possible/place + - second/possible/place改 +- {jsonStyle: [{x: y改}, {x: z}]} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/all/all.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/all/all.yml index aa68ac0d6c7..268a99e85db 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/all/all.yml +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/all/all.yml @@ -1,77 +1,56 @@ --- -version: "v2.0" +version: v2.0 name: "" label: [] -triggerOn: +on: push: branches: - - "*" + - '*' tag: tags: - - "*" + - '*' mr: target-branches: - - "*" + - '*' action: - - "open" - - "reopen" - - "push-update" + - open + - reopen + - push-update stages: -- name: "stage-1" +- name: stage-1 label: [] - if: null fast-kill: false jobs: - - id: "job_1" - name: null - mutex: null + - id: job_1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: + - with: sourceMirrorTicketPair: - host: 11 username: 111 - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"hello 1\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: "腾讯代码分析(官方-代码分析工作组)" - id: "check" - if: "(true == true)" - if-modify: null - uses: "CodeccCheckAtomDebug@4.*" + run: | + echo "hello 1" + runAdditionalOptions: {} + - name: 腾讯代码分析(官方-代码分析工作组) + id: check + if: (true == true) + uses: CodeccCheckAtomDebug@4.* with: beAutoLang: false - checkerSetType: "normal" - toolScanType: "1" + checkerSetType: normal + toolScanType: 1 languages: - - "C_CPP" + - C_CPP tools: "" languageRuleSetMap: C_CPP_RULE: - - "standard_cpp" - - "codecc_fast_cpp" - - "pecker_cpp" - - "codecc_default_coverity_cpp" + - standard_cpp + - codecc_fast_cpp + - pecker_cpp + - codecc_default_coverity_cpp JAVA_RULE: [] C_SHARP_RULE: [] JS_RULE: [] @@ -87,176 +66,93 @@ stages: LUA_RULE: [] DART_RULE: [] SOLIDITY_RULE: [] - pyVersion: "py3" + pyVersion: py3 goPath: "" - scriptType: "SHELL" - script: "cd src\nmkdir build\ncd build\ncmake -DLIB_LEGO_DIR=${{ ci.workspace }}/tmp/liblego ..\nmake -j`nproc`" - newDefectJudgeFromDate: "2021-11-01" + scriptType: SHELL + script: |- + cd src + mkdir build + cd build + cmake -DLIB_LEGO_DIR=${{ ci.workspace }}/tmp/liblego .. + make -j`nproc` + newDefectJudgeFromDate: 2021-11-01 rtxReceiverType: 4 rtxReceiverList: [] instantReportStatus: 1 emailReceiverType: 4 emailReceiverList: [] emailCCReceiverList: [] - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "all-job-1" - name: "all-job-1" - mutex: null + runAdditionalOptions: {} + - id: all-job-1 + name: all-job-1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "123" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null + - run: 123 + runAdditionalOptions: {} env: output_content: "all-job-1 [基本语法] 执行完成" - continue-on-error: null - strategy: null - depend-on: null - - id: "all-job-1-2" - name: "互斥组放弃测试" + - id: all-job-1-2 + name: 互斥组放弃测试 mutex: - label: "mutex-1" - queue-length: null - timeout-minutes: null + label: mutex-1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo 123\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null + - run: | + echo 123 + runAdditionalOptions: {} continue-on-error: true - strategy: null - depend-on: null - - id: "all-job-1-3" - name: "互斥组等待测试" + - id: all-job-1-3 + name: 互斥组等待测试 mutex: - label: "mutex-2" + label: mutex-2 queue-length: 3 timeout-minutes: 10 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo 123\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null + - run: | + echo 123 + runAdditionalOptions: {} continue-on-error: true - strategy: null - depend-on: null - if-modify: null check-in: reviews: flows: - - name: "审批组1" + - name: 审批组1 reviewers: - "${{ci.actor}}" - - name: "审批组2" + - name: 审批组2 reviewers: - "${{ci.actor}}" variables: var_1: - label: "中文" - type: "SELECTOR" + label: 中文 + type: SELECTOR default: 1 values: - 1 - 2 - 3 - 4 - description: null - description: "说明下如何审核\n参数var_1如何取值\n" + description: | + 说明下如何审核 + 参数var_1如何取值 gates: - - name: "gate-1" + - name: gate-1 rule: - - "CodeccCheckAtomDebug.coverity_serious_defect <= 3" - - "CodeccCheckAtomDebug.sensitive_defect < 2" + - CodeccCheckAtomDebug.coverity_serious_defect <= 3 + - CodeccCheckAtomDebug.sensitive_defect < 2 notify-on-fail: - - type: "wework-message" + - type: wework-message receivers: - - "ruotiantang" + - ruotiantang - "${{ci.actor}}" - continue-on-fail: null timeout-hours: 10 - check-out: null finally: [] diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/all/all_old.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/all/all_old.yml index e3e95c68377..b1c3c7ee944 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/all/all_old.yml +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/all/all_old.yml @@ -1,77 +1,56 @@ --- -version: "v2.0" +version: v2.0 name: "" label: [] -triggerOn: +on: push: branches: - - "*" + - '*' tag: tags: - - "*" + - '*' mr: target-branches: - - "*" + - '*' action: - - "open" - - "reopen" - - "push-update" + - open + - reopen + - push-update stages: -- name: "stage-1" +- name: stage-1 label: [] - if: null fast-kill: false jobs: - - id: "job_1" - name: null - mutex: null + - id: job_1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: + - with: sourceMirrorTicketPair: - host: 11 username: 111 - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"hello 1\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: "腾讯代码分析(官方-代码分析工作组)" - id: "check" - if: "true == true" - if-modify: null - uses: "CodeccCheckAtomDebug@4.*" + run: | + echo "hello 1" + runAdditionalOptions: {} + - name: 腾讯代码分析(官方-代码分析工作组) + id: check + if: true == true + uses: CodeccCheckAtomDebug@4.* with: beAutoLang: false - checkerSetType: "normal" - toolScanType: "1" + checkerSetType: normal + toolScanType: 1 languages: - - "C_CPP" + - C_CPP tools: "${{ parameters.tools }}" languageRuleSetMap: C_CPP_RULE: - - "standard_cpp" - - "codecc_fast_cpp" - - "pecker_cpp" - - "codecc_default_coverity_cpp" + - standard_cpp + - codecc_fast_cpp + - pecker_cpp + - codecc_default_coverity_cpp JAVA_RULE: [] C_SHARP_RULE: [] JS_RULE: [] @@ -87,176 +66,93 @@ stages: LUA_RULE: [] DART_RULE: [] SOLIDITY_RULE: [] - pyVersion: "py3" + pyVersion: py3 goPath: "" - scriptType: "SHELL" - script: "cd src\nmkdir build\ncd build\ncmake -DLIB_LEGO_DIR=${{ ci.workspace }}/tmp/liblego ..\nmake -j`nproc`" - newDefectJudgeFromDate: "2021-11-01" + scriptType: SHELL + script: |- + cd src + mkdir build + cd build + cmake -DLIB_LEGO_DIR=${{ ci.workspace }}/tmp/liblego .. + make -j`nproc` + newDefectJudgeFromDate: 2021-11-01 rtxReceiverType: 4 rtxReceiverList: [] instantReportStatus: 1 emailReceiverType: 4 emailReceiverList: [] emailCCReceiverList: [] - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "all-job-1" - name: "all-job-1" - mutex: null + runAdditionalOptions: {} + - id: all-job-1 + name: all-job-1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "123" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null + - run: 123 + runAdditionalOptions: {} env: output_content: "all-job-1 [基本语法] 执行完成" - continue-on-error: null - strategy: null - depend-on: null - - id: "all-job-1-2" - name: "互斥组放弃测试" + - id: all-job-1-2 + name: 互斥组放弃测试 mutex: - label: "mutex-1" - queue-length: null - timeout-minutes: null + label: mutex-1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo 123\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null + - run: | + echo 123 + runAdditionalOptions: {} continue-on-error: true - strategy: null - depend-on: null - - id: "all-job-1-3" - name: "互斥组等待测试" + - id: all-job-1-3 + name: 互斥组等待测试 mutex: - label: "mutex-2" + label: mutex-2 queue-length: 3 timeout-minutes: 10 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo 123\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null + - run: | + echo 123 + runAdditionalOptions: {} continue-on-error: true - strategy: null - depend-on: null - if-modify: null check-in: reviews: flows: - - name: "审批组1" + - name: 审批组1 reviewers: - "${{ci.actor}}" - - name: "审批组2" + - name: 审批组2 reviewers: - "${{ci.actor}}" variables: var_1: - label: "中文" - type: "SELECTOR" + label: 中文 + type: SELECTOR default: 1 values: - 1 - 2 - 3 - 4 - description: null - description: "说明下如何审核\n参数var_1如何取值\n" + description: | + 说明下如何审核 + 参数var_1如何取值 gates: - - name: "gate-1" + - name: gate-1 rule: - - "CodeccCheckAtomDebug.coverity_serious_defect <= 3" - - "CodeccCheckAtomDebug.sensitive_defect < 2" + - CodeccCheckAtomDebug.coverity_serious_defect <= 3 + - CodeccCheckAtomDebug.sensitive_defect < 2 notify-on-fail: - - type: "wework-message" + - type: wework-message receivers: - - "ruotiantang" + - ruotiantang - "${{ci.actor}}" - continue-on-fail: null timeout-hours: 10 - check-out: null finally: [] diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/extends/extends.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/extends/extends.yml index dfee86389d3..950d10d273e 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/extends/extends.yml +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/extends/extends.yml @@ -1,666 +1,288 @@ --- -version: "v2.0" +version: v2.0 name: "" label: [] -triggerOn: +on: push: branches: - - "*" + - '*' tag: tags: - - "*" + - '*' mr: target-branches: - - "*" + - '*' action: - - "open" - - "reopen" - - "push-update" + - open + - reopen + - push-update variables: DEPLOY_TYPE: - value: "dev" + value: dev APPROVE: value: "${{ sss }}_${{ approve22 }}" GIT_USERNAME: - value: "user1" + value: user1 readonly: true RES_REPOA_VAR1_USERNAME: - value: "RES_VARIABLE" + value: RES_VARIABLE RES_REPOA_VAR2_USERNAME: - value: "aaa" + value: aaa stages: -- name: "root_stage_id_1" +- name: root_stage_id_1 label: [] - if: "('world' == world)" + if: ('world' == world) fast-kill: false jobs: - - id: "root_job_id_1" - name: "root_job_id_1" - mutex: null + - id: root_job_id_1 + name: root_job_id_1 runs-on: self-hosted: false pool-name: "[docker-on-vm]" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null services: - - serviceId: "mysql1" - image: "mysql:8.0" + - serviceId: mysql1 + image: mysql:8.0 with: - password: "123456" - if: "('world' == world)" + password: 123456 + if: ('world' == world) steps: - - name: "root_step_1" - id: "root_step_1" - if: "('world' == world)" - if-modify: null - uses: "UploadArtifactory@1.*" + - name: root_step_1 + id: root_step_1 + if: ('world' == world) + uses: UploadArtifactory@1.* with: - path: "test.txt" + path: test.txt timeout-minutes: 480 continue-on-error: false retry-times: 0 - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: "(steps.world1.xxx.outputs == world)" - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"root_step_1\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null + runAdditionalOptions: {} + - if: (steps.world1.xxx.outputs == world) + run: | + echo "root_step_1" + runAdditionalOptions: {} timeout-minutes: 480 - env: null continue-on-error: false - strategy: null depend-on: - - "job1" - - "job2" - - id: "root_job_id_2" - name: "root_job_id_2" - mutex: null + - job1 + - job2 + - id: root_job_id_2 + name: root_job_id_2 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: "${{steps.world1.outputs.xxx == world}}" - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"root_stage_id_1, root_job_id_2\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null + - if: "${{steps.world1.outputs.xxx == world}}" + run: | + echo "root_stage_id_1, root_job_id_2" + runAdditionalOptions: {} depend-on: - - "job_id_1" - - id: "res_repoA_job_id_1" - name: "res_repoA_job_id_1" - mutex: null + - job_id_1 + - id: res_repoA_job_id_1 + name: res_repoA_job_id_1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_job_id_1\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "res_repoB_job_id_2" - name: "res_repoB_job_id_2" - mutex: null + - run: | + echo "res_repoA_job_id_1" + runAdditionalOptions: {} + - id: res_repoB_job_id_2 + name: res_repoB_job_id_2 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoB_job_id_2\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "res_repoB_job_id_3" - name: "res_repoB_job_id_3" - mutex: null + - run: | + echo "res_repoB_job_id_2" + runAdditionalOptions: {} + - id: res_repoB_job_id_3 + name: res_repoB_job_id_3 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoB_job_id_3 username RES_REPOB_JOB3\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "res_repoA_job_id_3" - name: "res_repoA_job_id_3" - mutex: null + - run: | + echo "res_repoB_job_id_3 username RES_REPOB_JOB3" + runAdditionalOptions: {} + - id: res_repoA_job_id_3 + name: res_repoA_job_id_3 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_job_id_3\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "res_repoA_job_id_2" - name: "res_repoA_job_id_2" - mutex: null + - run: | + echo "res_repoA_job_id_3" + runAdditionalOptions: {} + - id: res_repoA_job_id_2 + name: res_repoA_job_id_2 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_job_id_2 username RES_JOB!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_job_id_2 jobname JOBNAME again!\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null + - run: | + echo "res_repoA_job_id_2 username RES_JOB!" + runAdditionalOptions: {} + - run: | + echo "res_repoA_job_id_2 jobname JOBNAME again!" + runAdditionalOptions: {} check-in: reviews: flows: - - name: "审批组1" + - name: 审批组1 reviewers: - "${{ ci.actor }}" - - name: "审批组2" + - name: 审批组2 reviewers: - "${{ ci.actor }}" - variables: null - description: null gates: - - name: "gate-1" + - name: gate-1 rule: - - "CodeccCheckAtomDebug.coverity_serious_defect <= 3" - - "CodeccCheckAtomDebug.sensitive_defect < 2" + - CodeccCheckAtomDebug.coverity_serious_defect <= 3 + - CodeccCheckAtomDebug.sensitive_defect < 2 notify-on-fail: - - type: "wework-message" + - type: wework-message receivers: - - "ruotiantang" - continue-on-fail: null - timeout-hours: null - check-out: null -- name: "res_stage_id_1" + - ruotiantang +- name: res_stage_id_1 label: [] - if: null fast-kill: false jobs: - - id: "res_repoA_stage_id_1_job_id_1" - name: "res_repoA_stage_id_1_job_id_1" - mutex: null + - id: res_repoA_stage_id_1_job_id_1 + name: res_repoA_stage_id_1_job_id_1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_stage_id_1_job_id_1 username RES_STAGE\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "res_repoA_stage_id_1_job_id_2" - name: "res_repoA_stage_id_1_job_id_2" - mutex: null + - run: | + echo "res_repoA_stage_id_1_job_id_1 username RES_STAGE" + runAdditionalOptions: {} + - id: res_repoA_stage_id_1_job_id_2 + name: res_repoA_stage_id_1_job_id_2 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_stage_id_1_job_id_2 stagename STAGENAME\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: - - "asd/**" - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_step_id_4 username RES_REPOA_STAGE1_JOB2_STEP3!\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null + - run: | + echo "res_repoA_stage_id_1_job_id_2 stagename STAGENAME" + runAdditionalOptions: {} + - if-modify: + - asd/** + run: | + echo "res_repoA_step_id_4 username RES_REPOA_STAGE1_JOB2_STEP3!" + runAdditionalOptions: {} check-in: - reviews: null gates: - - name: "gate-1" + - name: gate-1 rule: - - "CodeccCheckAtomDebug.coverity_serious_defect <= 2" - - "CodeccCheckAtomDebug.sensitive_defect < 1" + - CodeccCheckAtomDebug.coverity_serious_defect <= 2 + - CodeccCheckAtomDebug.sensitive_defect < 1 notify-on-fail: - - type: "wework-message" + - type: wework-message receivers: - "${{ ci.actor }}" - continue-on-fail: null - timeout-hours: null - check-out: null -- name: "res_stage_id_2" +- name: res_stage_id_2 label: [] - if: null fast-kill: false jobs: - - id: "res_repoA_stage_id_2_job_id_1" - name: "res_repoA_stage_id_2_job_id_1" - mutex: null + - id: res_repoA_stage_id_2_job_id_1 + name: res_repoA_stage_id_2_job_id_1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_stage_id_2_job_id_1 username RES_PEPOA_STAGE1\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "res_repoA_stage_id_2_job_id_2" - name: "res_repoA_stage_id_2_job_id_2" - mutex: null + - run: | + echo "res_repoA_stage_id_2_job_id_1 username RES_PEPOA_STAGE1" + runAdditionalOptions: {} + - id: res_repoA_stage_id_2_job_id_2 + name: res_repoA_stage_id_2_job_id_2 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_stage_id_2_job_id_2 stagename STAGENAME\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: - - "asd/**" - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_step_id_4 username RES_REPOA_STAGE2_JOB2_STEP3!\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null -- name: "res_repoB_stage_id_1" + - run: | + echo "res_repoA_stage_id_2_job_id_2 stagename STAGENAME" + runAdditionalOptions: {} + - if-modify: + - asd/** + run: | + echo "res_repoA_step_id_4 username RES_REPOA_STAGE2_JOB2_STEP3!" + runAdditionalOptions: {} +- name: res_repoB_stage_id_1 label: [] - if: null fast-kill: false jobs: - - id: "res_repoB_stage_id_1_job_id_1" - name: "res_repoB_stage_id_1_job_id_1" - mutex: null + - id: res_repoB_stage_id_1_job_id_1 + name: res_repoB_stage_id_1_job_id_1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoB_stage_id_1_job_id_1 username RES_PEPOA_STAGE1\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null -- name: "res_repoB_stage_id_2" + - run: | + echo "res_repoB_stage_id_1_job_id_1 username RES_PEPOA_STAGE1" + runAdditionalOptions: {} +- name: res_repoB_stage_id_2 label: [] - if: null fast-kill: false jobs: - - id: "res_repoB_stage_id_2_job_id_1" - name: "res_repoB_stage_id_2_job_id_1" - mutex: null + - id: res_repoB_stage_id_2_job_id_1 + name: res_repoB_stage_id_2_job_id_1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoB_stage_id_2_job_id_1 username RES_PEPOB_STAGE2\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null + - run: | + echo "res_repoB_stage_id_2_job_id_1 username RES_PEPOB_STAGE2" + runAdditionalOptions: {} notices: -- type: "email" +- type: email receivers: - - "user1" - - "user2" - title: "this is a email notice" + - user1 + - user2 + title: this is a email notice content: "this is a email notice,content is hello." ccs: - - "user3" - if: "SUCCESS" -- type: "wework-message" + - user3 + if: SUCCESS +- type: wework-message receivers: - - "user1" - - "user2" - title: "this is a wework-message notice" + - user1 + - user2 + title: this is a wework-message notice content: "this is a wework-message notice,content is hello." -- type: "wework-chat" +- type: wework-chat content: "this is a wework-chat notice,content is hello." chat-id: - - "xxxxxxxx" -- type: "email" + - xxxxxxxx +- type: email receivers: - - "ruotiantang" + - ruotiantang - "${{ci.actor}}" title: "${{ variables.EVENT }}触发 STREAM-TEST环境-全部语法测试(模板) 测试失败" content: "${{ variables.EVENT }}触发 STREAM-TEST环境-全部语法测试(模板) 测试失败" ccs: - - "ruotiantang" + - ruotiantang - "${{ci.actor}}" - if: "FAILURE" -- type: "wework-message" + if: FAILURE +- type: wework-message receivers: - "${{ci.actor}}" content: "${{ variables.EVENT }}触发 STREAM-TEST环境-全部语法测试(模板) 测试失败" - if: "FAILURE" -- type: "wework-chat" + if: FAILURE +- type: wework-chat content: "${{ variables.EVENT }}触发 STREAM-TEST环境-全部语法测试(模板) 测试失败" - if: "FAILURE" + if: FAILURE chat-id: - "${{ci.actor}}" finally: [] diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/extends/extends_old.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/extends/extends_old.yml index 8b769924a95..b24a6158858 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/extends/extends_old.yml +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/extends/extends_old.yml @@ -1,666 +1,288 @@ --- -version: "v2.0" +version: v2.0 name: "" label: [] -triggerOn: +on: push: branches: - - "*" + - '*' tag: tags: - - "*" + - '*' mr: target-branches: - - "*" + - '*' action: - - "open" - - "reopen" - - "push-update" + - open + - reopen + - push-update variables: DEPLOY_TYPE: - value: "dev" + value: dev APPROVE: value: "${{ sss }}_${{ approve22 }}" GIT_USERNAME: - value: "user1" + value: user1 readonly: true RES_REPOA_VAR1_USERNAME: - value: "RES_VARIABLE" + value: RES_VARIABLE RES_REPOA_VAR2_USERNAME: - value: "aaa" + value: aaa stages: -- name: "root_stage_id_1" +- name: root_stage_id_1 label: [] - if: "world == world" + if: world == world fast-kill: false jobs: - - id: "root_job_id_1" - name: "root_job_id_1" - mutex: null + - id: root_job_id_1 + name: root_job_id_1 runs-on: self-hosted: false pool-name: "[docker-on-vm]" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null services: - - serviceId: "mysql1" - image: "mysql:8.0" + - serviceId: mysql1 + image: mysql:8.0 with: - password: "123456" - if: "world == world" + password: 123456 + if: world == world steps: - - name: "root_step_1" - id: "root_step_1" - if: "world == world" - if-modify: null - uses: "UploadArtifactory@1.*" + - name: root_step_1 + id: root_step_1 + if: if world == world + uses: UploadArtifactory@1.* with: - path: "test.txt" + path: test.txt timeout-minutes: 480 continue-on-error: false retry-times: 0 - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: "steps.world1.xxx.outputs == world" - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"root_step_1\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null + runAdditionalOptions: {} + - if: steps.world1.xxx.outputs == world + run: | + echo "root_step_1" + runAdditionalOptions: {} timeout-minutes: 480 - env: null continue-on-error: false - strategy: null depend-on: - - "job1" - - "job2" - - id: "root_job_id_2" - name: "root_job_id_2" - mutex: null + - job1 + - job2 + - id: root_job_id_2 + name: root_job_id_2 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: "steps.world1.outputs.xxx == world" - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"root_stage_id_1, root_job_id_2\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null + - if: steps.world1.outputs.xxx == world + run: | + echo "root_stage_id_1, root_job_id_2" + runAdditionalOptions: {} depend-on: - - "job_id_1" - - id: "res_repoA_job_id_1" - name: "res_repoA_job_id_1" - mutex: null + - job_id_1 + - id: res_repoA_job_id_1 + name: res_repoA_job_id_1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_job_id_1\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "res_repoB_job_id_2" - name: "res_repoB_job_id_2" - mutex: null + - run: | + echo "res_repoA_job_id_1" + runAdditionalOptions: {} + - id: res_repoB_job_id_2 + name: res_repoB_job_id_2 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoB_job_id_2\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "res_repoB_job_id_3" - name: "res_repoB_job_id_3" - mutex: null + - run: | + echo "res_repoB_job_id_2" + runAdditionalOptions: {} + - id: res_repoB_job_id_3 + name: res_repoB_job_id_3 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoB_job_id_3 username RES_REPOB_JOB3\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "res_repoA_job_id_3" - name: "res_repoA_job_id_3" - mutex: null + - run: | + echo "res_repoB_job_id_3 username RES_REPOB_JOB3" + runAdditionalOptions: {} + - id: res_repoA_job_id_3 + name: res_repoA_job_id_3 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_job_id_3\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "res_repoA_job_id_2" - name: "res_repoA_job_id_2" - mutex: null + - run: | + echo "res_repoA_job_id_3" + runAdditionalOptions: {} + - id: res_repoA_job_id_2 + name: res_repoA_job_id_2 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_job_id_2 username RES_JOB!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_job_id_2 jobname JOBNAME again!\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null + - run: | + echo "res_repoA_job_id_2 username RES_JOB!" + runAdditionalOptions: {} + - run: | + echo "res_repoA_job_id_2 jobname JOBNAME again!" + runAdditionalOptions: {} check-in: reviews: flows: - - name: "审批组1" + - name: 审批组1 reviewers: - "${{ci.actor}}" - - name: "审批组2" + - name: 审批组2 reviewers: - "${{ci.actor}}" - variables: null - description: null gates: - - name: "gate-1" + - name: gate-1 rule: - - "CodeccCheckAtomDebug.coverity_serious_defect <= 3" - - "CodeccCheckAtomDebug.sensitive_defect < 2" + - CodeccCheckAtomDebug.coverity_serious_defect <= 3 + - CodeccCheckAtomDebug.sensitive_defect < 2 notify-on-fail: - - type: "wework-message" + - type: wework-message receivers: - - "ruotiantang" - continue-on-fail: null - timeout-hours: null - check-out: null -- name: "res_stage_id_1" + - ruotiantang +- name: res_stage_id_1 label: [] - if: null fast-kill: false jobs: - - id: "res_repoA_stage_id_1_job_id_1" - name: "res_repoA_stage_id_1_job_id_1" - mutex: null + - id: res_repoA_stage_id_1_job_id_1 + name: res_repoA_stage_id_1_job_id_1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_stage_id_1_job_id_1 username RES_STAGE\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "res_repoA_stage_id_1_job_id_2" - name: "res_repoA_stage_id_1_job_id_2" - mutex: null + - run: | + echo "res_repoA_stage_id_1_job_id_1 username RES_STAGE" + runAdditionalOptions: {} + - id: res_repoA_stage_id_1_job_id_2 + name: res_repoA_stage_id_1_job_id_2 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_stage_id_1_job_id_2 stagename STAGENAME\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: - - "asd/**" - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_step_id_4 username RES_REPOA_STAGE1_JOB2_STEP3!\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null + - run: | + echo "res_repoA_stage_id_1_job_id_2 stagename STAGENAME" + runAdditionalOptions: {} + - if-modify: + - asd/** + run: | + echo "res_repoA_step_id_4 username RES_REPOA_STAGE1_JOB2_STEP3!" + runAdditionalOptions: {} check-in: - reviews: null gates: - - name: "gate-1" + - name: gate-1 rule: - - "CodeccCheckAtomDebug.coverity_serious_defect <= 2" - - "CodeccCheckAtomDebug.sensitive_defect < 1" + - CodeccCheckAtomDebug.coverity_serious_defect <= 2 + - CodeccCheckAtomDebug.sensitive_defect < 1 notify-on-fail: - - type: "wework-message" + - type: wework-message receivers: - "${{ ci.actor }}" - continue-on-fail: null - timeout-hours: null - check-out: null -- name: "res_stage_id_2" +- name: res_stage_id_2 label: [] - if: null fast-kill: false jobs: - - id: "res_repoA_stage_id_2_job_id_1" - name: "res_repoA_stage_id_2_job_id_1" - mutex: null + - id: res_repoA_stage_id_2_job_id_1 + name: res_repoA_stage_id_2_job_id_1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_stage_id_2_job_id_1 username RES_PEPOA_STAGE1\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "res_repoA_stage_id_2_job_id_2" - name: "res_repoA_stage_id_2_job_id_2" - mutex: null + - run: | + echo "res_repoA_stage_id_2_job_id_1 username RES_PEPOA_STAGE1" + runAdditionalOptions: {} + - id: res_repoA_stage_id_2_job_id_2 + name: res_repoA_stage_id_2_job_id_2 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_stage_id_2_job_id_2 stagename STAGENAME\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: - - "asd/**" - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_step_id_4 username RES_REPOA_STAGE2_JOB2_STEP3!\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null -- name: "res_repoB_stage_id_1" + - run: | + echo "res_repoA_stage_id_2_job_id_2 stagename STAGENAME" + runAdditionalOptions: {} + - if-modify: + - asd/** + run: | + echo "res_repoA_step_id_4 username RES_REPOA_STAGE2_JOB2_STEP3!" + runAdditionalOptions: {} +- name: res_repoB_stage_id_1 label: [] - if: null fast-kill: false jobs: - - id: "res_repoB_stage_id_1_job_id_1" - name: "res_repoB_stage_id_1_job_id_1" - mutex: null + - id: res_repoB_stage_id_1_job_id_1 + name: res_repoB_stage_id_1_job_id_1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoB_stage_id_1_job_id_1 username RES_PEPOA_STAGE1\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null -- name: "res_repoB_stage_id_2" + - run: | + echo "res_repoB_stage_id_1_job_id_1 username RES_PEPOA_STAGE1" + runAdditionalOptions: {} +- name: res_repoB_stage_id_2 label: [] - if: null fast-kill: false jobs: - - id: "res_repoB_stage_id_2_job_id_1" - name: "res_repoB_stage_id_2_job_id_1" - mutex: null + - id: res_repoB_stage_id_2_job_id_1 + name: res_repoB_stage_id_2_job_id_1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoB_stage_id_2_job_id_1 username RES_PEPOB_STAGE2\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null + - run: | + echo "res_repoB_stage_id_2_job_id_1 username RES_PEPOB_STAGE2" + runAdditionalOptions: {} notices: -- type: "email" +- type: email receivers: - - "user1" - - "user2" - title: "this is a email notice" + - user1 + - user2 + title: this is a email notice content: "this is a email notice,content is hello." ccs: - - "user3" - if: "SUCCESS" -- type: "wework-message" + - user3 + if: if SUCCESS +- type: wework-message receivers: - - "user1" - - "user2" - title: "this is a wework-message notice" + - user1 + - user2 + title: this is a wework-message notice content: "this is a wework-message notice,content is hello." -- type: "wework-chat" +- type: wework-chat content: "this is a wework-chat notice,content is hello." chat-id: - - "xxxxxxxx" -- type: "email" + - xxxxxxxx +- type: email receivers: - - "ruotiantang" + - ruotiantang - "${{ci.actor}}" title: "${{ variables.EVENT }}触发 STREAM-TEST环境-全部语法测试(模板) 测试失败" content: "${{ variables.EVENT }}触发 STREAM-TEST环境-全部语法测试(模板) 测试失败" ccs: - - "ruotiantang" + - ruotiantang - "${{ci.actor}}" - if: "FAILURE" -- type: "wework-message" + if: if FAILURE +- type: wework-message receivers: - "${{ci.actor}}" content: "${{ variables.EVENT }}触发 STREAM-TEST环境-全部语法测试(模板) 测试失败" - if: "FAILURE" -- type: "wework-chat" + if: if FAILURE +- type: wework-chat content: "${{ variables.EVENT }}触发 STREAM-TEST环境-全部语法测试(模板) 测试失败" - if: "FAILURE" + if: if FAILURE chat-id: - "${{ci.actor}}" finally: [] diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/jobs/jobs.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/jobs/jobs.yml index a55bf1a8acc..a9fa944dea4 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/jobs/jobs.yml +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/jobs/jobs.yml @@ -1,469 +1,147 @@ --- -version: "v2.0" +version: v2.0 name: "" label: [] -triggerOn: +on: push: branches: - - "*" + - '*' tag: tags: - - "*" + - '*' mr: target-branches: - - "*" + - '*' action: - - "open" - - "reopen" - - "push-update" + - open + - reopen + - push-update stages: -- name: "stage_1" +- name: stage_1 label: [] - if: null fast-kill: false jobs: - - id: "root_job_id_1" - name: null + - id: root_job_id_1 mutex: - label: "mutex-3" - queue-length: null - timeout-minutes: null + label: mutex-3 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"template_step_id_1 username world!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"cyc_step_id_1 username CYC_STEP1!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"cyc_step_id_3 username STEP6!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"cyc_step_id_2 username CYC_STEP4!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"cyc_step_id_6 username STEP6!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"cyc_step_id_5 username CYC_STEP5!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"root_step_1\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "root_job_id_2" - name: "root_job_id_2" + - run: | + echo "template_step_id_1 username world!" + runAdditionalOptions: {} + - run: | + echo "cyc_step_id_1 username CYC_STEP1!" + runAdditionalOptions: {} + - run: | + echo "cyc_step_id_3 username STEP6!" + runAdditionalOptions: {} + - run: | + echo "cyc_step_id_2 username CYC_STEP4!" + runAdditionalOptions: {} + - run: | + echo "cyc_step_id_6 username STEP6!" + runAdditionalOptions: {} + - run: | + echo "cyc_step_id_5 username CYC_STEP5!" + runAdditionalOptions: {} + - run: | + echo "root_step_1" + runAdditionalOptions: {} + - id: root_job_id_2 + name: root_job_id_2 mutex: - label: "mutex-3" + label: mutex-3 queue-length: 0 timeout-minutes: 10 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"root_stage_id_1, root_job_id_2\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_step_id_1 username RES_STEP!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoB_step_id_6 username STEP6!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoB_step_id_1 username RES_REPOA_STEP1!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_step_id_3 username RES_REPOA_STEP1_STEP3!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoB_step_id_6 username STEP6!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoB_step_id_1 username RES_REPOA_STEP3!\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null + - run: | + echo "root_stage_id_1, root_job_id_2" + runAdditionalOptions: {} + - run: | + echo "res_repoA_step_id_1 username RES_STEP!" + runAdditionalOptions: {} + - run: | + echo "res_repoB_step_id_6 username STEP6!" + runAdditionalOptions: {} + - run: | + echo "res_repoB_step_id_1 username RES_REPOA_STEP1!" + runAdditionalOptions: {} + - run: | + echo "res_repoA_step_id_3 username RES_REPOA_STEP1_STEP3!" + runAdditionalOptions: {} + - run: | + echo "res_repoB_step_id_6 username STEP6!" + runAdditionalOptions: {} + - run: | + echo "res_repoB_step_id_1 username RES_REPOA_STEP3!" + runAdditionalOptions: {} depend-on: - - "job_id_1" - - id: "res_repoA_job_id_1" - name: "res_repoA_job_id_1" - mutex: null + - job_id_1 + - id: res_repoA_job_id_1 + name: res_repoA_job_id_1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_job_id_1\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "res_repoB_job_id_2" - name: "res_repoB_job_id_2" - mutex: null + - run: | + echo "res_repoA_job_id_1" + runAdditionalOptions: {} + - id: res_repoB_job_id_2 + name: res_repoB_job_id_2 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoB_job_id_2\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "res_repoB_job_id_3" - name: "res_repoB_job_id_3" - mutex: null + - run: | + echo "res_repoB_job_id_2" + runAdditionalOptions: {} + - id: res_repoB_job_id_3 + name: res_repoB_job_id_3 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoB_job_id_3 username RES_REPOB_JOB3\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "res_repoA_job_id_3" - name: "res_repoA_job_id_3" - mutex: null + - run: | + echo "res_repoB_job_id_3 username RES_REPOB_JOB3" + runAdditionalOptions: {} + - id: res_repoA_job_id_3 + name: res_repoA_job_id_3 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_job_id_3\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "res_repoA_job_id_2" - name: "res_repoA_job_id_2" - mutex: null + - run: | + echo "res_repoA_job_id_3" + runAdditionalOptions: {} + - id: res_repoA_job_id_2 + name: res_repoA_job_id_2 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_job_id_2 username RES_JOB!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"res_repoA_job_id_2 jobname JOBNAME again!\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null + - run: | + echo "res_repoA_job_id_2 username RES_JOB!" + runAdditionalOptions: {} + - run: | + echo "res_repoA_job_id_2 jobname JOBNAME again!" + runAdditionalOptions: {} resource: repositories: - - repository: "repoA" - name: "repoA" - ref: "master" + - repository: repoA + name: repoA + ref: master credentials: - personal-access-token: "xxx" + personal-access-token: xxx finally: [] diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/parameters/parameters.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/parameters/parameters.yml index 0f74bb7ccdd..9802349ff9f 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/parameters/parameters.yml +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/parameters/parameters.yml @@ -1,132 +1,53 @@ --- -version: "v2.0" +version: v2.0 name: "" label: [] -triggerOn: +on: push: branches: - - "*" + - '*' tag: tags: - - "*" + - '*' mr: target-branches: - - "*" + - '*' action: - - "open" - - "reopen" - - "push-update" + - open + - reopen + - push-update variables: VAR1: - value: "123" + value: 123 readonly: false allow-modify-at-startup: false VAR2: - value: "local-VAR2" + value: local-VAR2 readonly: false allow-modify-at-startup: false VAR3: - value: "intput-VAR3" + value: intput-VAR3 readonly: false allow-modify-at-startup: false stages: -- name: "stage-1" +- name: stage-1 label: [] - if: null fast-kill: false jobs: - - id: "job-1" - name: null - mutex: null + - id: job-1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo 123" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "input-STEP1" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "LOCAL-STEP2" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "input-STEP4" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null + - run: echo 123 + runAdditionalOptions: {} + - run: input-STEP1 + runAdditionalOptions: {} + - run: LOCAL-STEP2 + runAdditionalOptions: {} + - run: "" + runAdditionalOptions: {} + - run: input-STEP4 + runAdditionalOptions: {} finally: [] diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/parameters/parameters_old.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/parameters/parameters_old.yml index 4cbf02783dd..75d15de394e 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/parameters/parameters_old.yml +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/parameters/parameters_old.yml @@ -1,132 +1,53 @@ --- -version: "v2.0" +version: v2.0 name: "" label: [] -triggerOn: +on: push: branches: - - "*" + - '*' tag: tags: - - "*" + - '*' mr: target-branches: - - "*" + - '*' action: - - "open" - - "reopen" - - "push-update" + - open + - reopen + - push-update variables: VAR1: - value: "123" + value: 123 readonly: false allow-modify-at-startup: false VAR2: - value: "local-VAR2" + value: local-VAR2 readonly: false allow-modify-at-startup: false VAR3: - value: "intput-VAR3" + value: intput-VAR3 readonly: false allow-modify-at-startup: false stages: -- name: "stage-1" +- name: stage-1 label: [] - if: null fast-kill: false jobs: - - id: "job-1" - name: null - mutex: null + - id: job-1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo 123" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "input-STEP1" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "LOCAL-STEP2" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "${{ parameters.STEP3 }}" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "input-STEP4" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null + - run: echo 123 + runAdditionalOptions: {} + - run: input-STEP1 + runAdditionalOptions: {} + - run: LOCAL-STEP2 + runAdditionalOptions: {} + - run: "${{ parameters.STEP3 }}" + runAdditionalOptions: {} + - run: input-STEP4 + runAdditionalOptions: {} finally: [] diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/specials/longParametersTest.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/specials/longParametersTest.yml index 68e5f168c75..72b08c8f031 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/specials/longParametersTest.yml +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/specials/longParametersTest.yml @@ -1,75 +1,54 @@ --- -version: "v2.0" -name: "log_download代码质量扫描" +version: v2.0 +name: log_download代码质量扫描 label: [] -triggerOn: +on: push: branches: - - "master" + - master mr: target-branches: - - "master" + - master stages: -- name: "腾讯代码质量扫描" +- name: 腾讯代码质量扫描 label: [] - if: null fast-kill: false jobs: - - id: "job_tcoder_codecc_new" - name: "腾讯代码质量扫描" - mutex: null + - id: job_tcoder_codecc_new + name: 腾讯代码质量扫描 runs-on: self-hosted: false - pool-name: "docker" + pool-name: docker container: - image: "mirrors.tencent.com/ci/tlinux3_ci:latest" - credentials: null - options: null - image-pull-policy: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + image: mirrors.tencent.com/ci/tlinux3_ci:latest services: [] - if: null steps: - - name: "代码拉取" - id: "step-1" - if: null - if-modify: null - uses: null + - name: 代码拉取 + id: step-1 with: - strategy: "FRESH_CHECKOUT" + strategy: FRESH_CHECKOUT enableVirtualMergeBranch: true enableSubmodule: true enableSubmoduleRecursive: true - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: "self" - - name: "腾讯代码分析(官方-代码分析工作组)" - id: "check" - if: "(false == true)" - if-modify: null - uses: "CodeccCheckAtomDebug@4.*" + runAdditionalOptions: {} + checkout: self + - name: 腾讯代码分析(官方-代码分析工作组) + id: check + if: (false == true) + uses: CodeccCheckAtomDebug@4.* with: beAutoLang: false - checkerSetType: "normal" - toolScanType: "1" + checkerSetType: normal + toolScanType: 1 languages: - - "C_CPP" + - C_CPP tools: "" languageRuleSetMap: C_CPP_RULE: - - "standard_cpp" - - "codecc_fast_cpp" - - "pecker_cpp" - - "codecc_default_coverity_cpp" + - standard_cpp + - codecc_fast_cpp + - pecker_cpp + - codecc_default_coverity_cpp JAVA_RULE: [] C_SHARP_RULE: [] JS_RULE: [] @@ -85,52 +64,33 @@ stages: LUA_RULE: [] DART_RULE: [] SOLIDITY_RULE: [] - pyVersion: "py3" + pyVersion: py3 goPath: "" - scriptType: "SHELL" - script: "cd src\nmkdir build\ncd build\ncmake -DLIB_LEGO_DIR=${{ ci.workspace }}/tmp/liblego ..\nmake -j`nproc`\necho \"213123123 ${{ ci.actor }}\"\necho '123123123 ${{ ci.actor }}'" - newDefectJudgeFromDate: "2021-11-01" + scriptType: SHELL + script: |- + cd src + mkdir build + cd build + cmake -DLIB_LEGO_DIR=${{ ci.workspace }}/tmp/liblego .. + make -j`nproc` + echo "213123123 ${{ ci.actor }}" + echo '123123123 ${{ ci.actor }}' + newDefectJudgeFromDate: 2021-11-01 rtxReceiverType: 4 rtxReceiverList: [] instantReportStatus: 1 emailReceiverType: 4 emailReceiverList: [] emailCCReceiverList: [] - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: "123123123" + runAdditionalOptions: {} + - id: 123123123 if: "('[\"${{ variables.xxx }}\",\"JS\"]' == fromJSON('[\"PYTHON\"]'))" - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo ${{ (join('[\"${{ variables.xxx }}\",\"JS\"]') == join(fromJSON('[\"JAVA\", \"JS\"]'))) }}\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null + run: | + echo ${{ (join('[\"${{ variables.xxx }}\",\"JS\"]') == join(fromJSON('["JAVA", "JS"]'))) }} + runAdditionalOptions: {} resource: repositories: - - repository: "sissicchen/log_download" - name: "tcoder" - ref: "refs/heads/master" - credentials: null + - repository: sissicchen/log_download + name: tcoder + ref: refs/heads/master finally: [] diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/specials/longParametersTest_old.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/specials/longParametersTest_old.yml index f0035d2ff9c..b47ac5828be 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/specials/longParametersTest_old.yml +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/specials/longParametersTest_old.yml @@ -1,75 +1,54 @@ --- -version: "v2.0" -name: "log_download代码质量扫描" +version: v2.0 +name: log_download代码质量扫描 label: [] -triggerOn: +on: push: branches: - - "master" + - master mr: target-branches: - - "master" + - master stages: -- name: "腾讯代码质量扫描" +- name: 腾讯代码质量扫描 label: [] - if: null fast-kill: false jobs: - - id: "job_tcoder_codecc_new" - name: "腾讯代码质量扫描" - mutex: null + - id: job_tcoder_codecc_new + name: 腾讯代码质量扫描 runs-on: self-hosted: false - pool-name: "docker" + pool-name: docker container: - image: "mirrors.tencent.com/ci/tlinux3_ci:latest" - credentials: null - options: null - image-pull-policy: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + image: mirrors.tencent.com/ci/tlinux3_ci:latest services: [] - if: null steps: - - name: "代码拉取" - id: "step-1" - if: null - if-modify: null - uses: null + - name: 代码拉取 + id: step-1 with: - strategy: "FRESH_CHECKOUT" + strategy: FRESH_CHECKOUT enableVirtualMergeBranch: true enableSubmodule: true enableSubmoduleRecursive: true - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: "self" - - name: "腾讯代码分析(官方-代码分析工作组)" - id: "check" - if: "false == true" - if-modify: null - uses: "CodeccCheckAtomDebug@4.*" + runAdditionalOptions: {} + checkout: self + - name: 腾讯代码分析(官方-代码分析工作组) + id: check + if: false == true + uses: CodeccCheckAtomDebug@4.* with: beAutoLang: false - checkerSetType: "normal" - toolScanType: "1" + checkerSetType: normal + toolScanType: 1 languages: - - "C_CPP" + - C_CPP tools: "${{ parameters.tools }}" languageRuleSetMap: C_CPP_RULE: - - "standard_cpp" - - "codecc_fast_cpp" - - "pecker_cpp" - - "codecc_default_coverity_cpp" + - standard_cpp + - codecc_fast_cpp + - pecker_cpp + - codecc_default_coverity_cpp JAVA_RULE: [] C_SHARP_RULE: [] JS_RULE: [] @@ -85,52 +64,33 @@ stages: LUA_RULE: [] DART_RULE: [] SOLIDITY_RULE: [] - pyVersion: "py3" + pyVersion: py3 goPath: "" - scriptType: "SHELL" - script: "cd src\nmkdir build\ncd build\ncmake -DLIB_LEGO_DIR=${{ ci.workspace }}/tmp/liblego ..\nmake -j`nproc`\necho \"213123123 ${{ ci.actor }}\"\necho '123123123 ${{ ci.actor }}'" - newDefectJudgeFromDate: "2021-11-01" + scriptType: SHELL + script: |- + cd src + mkdir build + cd build + cmake -DLIB_LEGO_DIR=${{ ci.workspace }}/tmp/liblego .. + make -j`nproc` + echo "213123123 ${{ ci.actor }}" + echo '123123123 ${{ ci.actor }}' + newDefectJudgeFromDate: 2021-11-01 rtxReceiverType: 4 rtxReceiverList: [] instantReportStatus: 1 emailReceiverType: 4 emailReceiverList: [] emailCCReceiverList: [] - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: "123123123" + runAdditionalOptions: {} + - id: 123123123 if: "[JAVA, JS] == [PYTHON]" - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo 123\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null + run: | + echo 123 + runAdditionalOptions: {} resource: repositories: - - repository: "sissicchen/log_download" - name: "tcoder" - ref: "refs/heads/master" - credentials: null + - repository: sissicchen/log_download + name: tcoder + ref: refs/heads/master finally: [] diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/specials/user.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/specials/user.yml index fdbc6cc09f5..993ddb42cba 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/specials/user.yml +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/specials/user.yml @@ -1,11 +1,11 @@ --- -version: "v2.0" -name: "POST_MASTER" +version: v2.0 +name: POST_MASTER label: [] -triggerOn: +on: push: branches: - - "master" + - master branches-ignore: - "" paths: @@ -14,45 +14,45 @@ triggerOn: - "" tag: tags: - - "*" + - '*' tags-ignore: - "" delete: types: - - "branch" + - branch issue: action: - - "open" + - open review: types: - - "merge_request" + - merge_request variables: "123_GIT_KEY": - value: "xxxxxx" + value: xxxxxx readonly: false allow-modify-at-startup: false "123_USERNAME": - value: "xxxxxxxxxx" + value: xxxxxxxxxx readonly: false allow-modify-at-startup: false "123_MAKE_PATH": - value: "./" + value: ./ readonly: false allow-modify-at-startup: false "123_SERVER": - value: "test" + value: test readonly: false allow-modify-at-startup: false "123_APP": - value: "xxxxxxxxxx" + value: xxxxxxxxxx readonly: false allow-modify-at-startup: false APP_NAME: - value: "myProject" + value: myProject readonly: false allow-modify-at-startup: false CODELIB_ALIAS: - value: "xxxxxxxxxx/myProject" + value: xxxxxxxxxx/myProject readonly: false allow-modify-at-startup: false COV_ID: @@ -76,84 +76,46 @@ variables: readonly: false allow-modify-at-startup: false stages: -- name: "前置信息收集" +- name: 前置信息收集 label: - - "28ee946a59f64949a74f3dee40a1bda4" - if: null + - 28ee946a59f64949a74f3dee40a1bda4 fast-kill: false jobs: - - id: "job_FxM" - name: "构建环境-LINUX" - mutex: null + - id: job_FxM + name: 构建环境-LINUX runs-on: self-hosted: false - pool-name: "docker" + pool-name: docker container: - image: "mirrors.tencent.com/ci/tlinux_ci:3.5.1" - credentials: null - options: null - image-pull-policy: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + image: mirrors.tencent.com/ci/tlinux_ci:3.5.1 services: [] - if: null steps: - - name: "参数预处理" - id: "step_5" - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"打印相关变量哈\"\necho ${{ BK_CI_PIPELINE_NAME }}\necho ${{ BK_CI_PROJECT_NAME }}\necho ${{ BK_CI_PROJECT_NAME_CN }}\necho \"打印所有环境变量哈\"\nenv|sort\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null -- name: "单元测试和代码扫描" + - name: 参数预处理 + id: step_5 + run: | + echo "打印相关变量哈" + echo ${{ BK_CI_PIPELINE_NAME }} + echo ${{ BK_CI_PROJECT_NAME }} + echo ${{ BK_CI_PROJECT_NAME_CN }} + echo "打印所有环境变量哈" + env|sort + runAdditionalOptions: {} +- name: 单元测试和代码扫描 label: - - "d0a06f6986fa4670af65ccad7bb49d3a" - if: null + - d0a06f6986fa4670af65ccad7bb49d3a fast-kill: false jobs: - - id: "job_0YD" - name: "PCG安全扫描" - mutex: null + - id: job_0YD + name: PCG安全扫描 runs-on: self-hosted: false - pool-name: "docker" + pool-name: docker container: - image: "mirrors.tencent.com/ci/tlinux_ci:3.5.1" - credentials: null - options: null - image-pull-policy: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + image: mirrors.tencent.com/ci/tlinux_ci:3.5.1 services: [] - if: null steps: - - name: "拉取Git代码" - id: "step_download-code_1" - if: null - if-modify: null - uses: null + - name: 拉取Git代码 + id: step_download-code_1 with: autoCrlf: "false" refName: "${{ ci.branch }}" @@ -165,66 +127,32 @@ stages: fetchDepth: "" includePath: "" localPath: "${{ variables.APP_NAME }}" - pullType: "BRANCH" - strategy: "REVERT_UPDATE" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null + pullType: BRANCH + strategy: REVERT_UPDATE + runAdditionalOptions: {} checkout: "http://xxxxx/${{ variables.CODELIB_ALIAS }}.git" - - name: "代码安全扫描" - id: "step_codeSecurity" - if: null - if-modify: null - uses: "CodeSecurityScan@2.*" + - name: 代码安全扫描 + id: step_codeSecurity + uses: CodeSecurityScan@2.* with: code_path: "${{ variables.APP_NAME }}" - code_lang: "go" - no_scan_path: "go" + code_lang: go + no_scan_path: go focuser: "" qywxg_id: "" - only_vul_notify: "1" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "job_7mD" - name: "腾讯代码规范分析" - mutex: null + only_vul_notify: 1 + runAdditionalOptions: {} + - id: job_7mD + name: 腾讯代码规范分析 runs-on: self-hosted: false - pool-name: "docker" + pool-name: docker container: - image: "mirrors.tencent.com/ci/tlinux_ci:3.5.1" - credentials: null - options: null - image-pull-policy: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + image: mirrors.tencent.com/ci/tlinux_ci:3.5.1 services: [] - if: null steps: - - name: "拉取Git代码" - id: "step_download-code_2" - if: null - if-modify: null - uses: null + - name: 拉取Git代码 + id: step_download-code_2 with: autoCrlf: "false" refName: "${{ ci.branch }}" @@ -236,51 +164,48 @@ stages: fetchDepth: "" includePath: "" localPath: "${{ variables.APP_NAME }}" - pullType: "BRANCH" - strategy: "REVERT_UPDATE" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null + pullType: BRANCH + strategy: REVERT_UPDATE + runAdditionalOptions: {} checkout: "http://xxxxx/${{ variables.CODELIB_ALIAS }}.git" - - name: "CCK-腾讯代码分析(最新)" - id: "step_codecc" - if: null - if-modify: null - uses: "CodeccCheckAtomDebug@4.*" + - name: CCK-腾讯代码分析(最新) + id: step_codecc + uses: CodeccCheckAtomDebug@4.* with: languages: - - "GOLANG" - checkerSetType: "openScan" + - GOLANG + checkerSetType: openScan tools: - - "GOML" + - GOML asyncTask: false asyncTaskId: "" goPath: "" - pyVersion: "py3" - scriptType: "SHELL" - script: "# Coverity/Klocwork将通过调用编译脚本来编译您的代码,以追踪深层次的缺陷\n# 请使用依赖的构建工具如maven/cmake等写一个编译脚本build.sh\n# 确保build.sh能够编译代码\n# cd path/to/build.sh\n# sh build.sh" + pyVersion: py3 + scriptType: SHELL + script: |- + # Coverity/Klocwork将通过调用编译脚本来编译您的代码,以追踪深层次的缺陷 + # 请使用依赖的构建工具如maven/cmake等写一个编译脚本build.sh + # 确保build.sh能够编译代码 + # cd path/to/build.sh + # sh build.sh languageRuleSetMap: GOLANG_RULE: - - "standard_go" + - standard_go C_CPP_RULE: [] - rtxReceiverType: "0" + rtxReceiverType: 0 rtxReceiverList: [] botWebhookUrl: "" - botRemindRange: "1" - botRemindSeverity: "7" + botRemindRange: 1 + botRemindSeverity: 7 botRemaindTools: [] - emailReceiverType: "0" + emailReceiverType: 0 emailReceiverList: [] emailCCReceiverList: [] - instantReportStatus: "2" + instantReportStatus: 2 reportDate: [] reportTime: "" reportTools: [] - toolScanType: "1" + toolScanType: 1 mrCommentEnable: true newDefectJudgeFromDate: "" transferAuthorList: [] @@ -288,53 +213,27 @@ stages: customPath: [] openScanPrj: false GOLANG_RULE: - - "codecc_default_go" + - codecc_default_go GOLANG_TOOL: - toolList: - - "CLOC" - - "SENSITIVE" - - "DUPC" - - "CCN" + - CLOC + - SENSITIVE + - DUPC + - CCN - toolList: - - "GOML" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "job_jtd" - name: "同源单元测试" - mutex: null + - GOML + runAdditionalOptions: {} + - id: job_jtd + name: 同源单元测试 runs-on: self-hosted: false - pool-name: "docker" + pool-name: docker container: - image: "mirrors.tencent.com/ci/tlinux_ci:3.5.1" - credentials: null - options: null - image-pull-policy: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + image: mirrors.tencent.com/ci/tlinux_ci:3.5.1 services: [] - if: null steps: - - name: "拉取Git代码" - id: "step_download-code_3" - if: null - if-modify: null - uses: null + - name: 拉取Git代码 + id: step_download-code_3 with: autoCrlf: "false" refName: "${{ ci.branch }}" @@ -346,26 +245,18 @@ stages: fetchDepth: "" includePath: "" localPath: "${{ variables.APP_NAME }}" - pullType: "BRANCH" - strategy: "REVERT_UPDATE" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null + pullType: BRANCH + strategy: REVERT_UPDATE + runAdditionalOptions: {} checkout: "http://xxxxx/${{ variables.CODELIB_ALIAS }}.git" - - name: "覆盖率-前置信息采集" - id: "step_covPreInfo" - if: null - if-modify: null - uses: "covPreInfo@5.*" + - name: 覆盖率-前置信息采集 + id: step_covPreInfo + uses: covPreInfo@5.* with: baseCommitEnv: "" - baseCommitPlugSel: "lastcommit" - baseCommitType: "plugSel" - chooseConfigType: "pluginConfigFilter" + baseCommitPlugSel: lastcommit + baseCommitType: plugSel + chooseConfigType: pluginConfigFilter codePath: "${{ ci.workspace }}" covProductId: "" epBranchName: "" @@ -373,7 +264,7 @@ stages: epMonthFlag: "${{ ep_month_flag }}" fileBothFilterBlack: "${{ ci.workspace }}/${{ variables.APP_NAME }}/cov.blacklist" fileBothFilterWhite: "" - fileSuffix: ".go" + fileSuffix: .go gitMrNumber: "${{ git_mr_number }}" gitPullFromType: "" gitSubmodule: false @@ -382,234 +273,139 @@ stages: multiGitFlagSwitch: false pathBothFilterBlack: "" pathBothFilterWhite: "" - pathFilterType: "pathBothFilter" + pathFilterType: pathBothFilter preMRCheck: false - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - - name: "UT-单元测试覆盖率" - id: "step_8" - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "# 您可以通过setEnv函数设置插件间传递的参数\n# echo \"::set-output name=FILENAME::package.zip\"\n# 然后在后续的插件的表单中使用${{ FILENAME }}引用这个变量\n\n# 您可以在质量红线中创建自定义指标,然后通过setGateValue函数设置指标值\n# setGateValue \"CodeCoverage\" $myValue\n# 然后在质量红线选择相应指标和阈值。若不满足,流水线在执行时将会被卡住\n\n# cd ${{ ci.workspace }} 可进入当前工作空间目录\n\n#执行覆盖率并生成产物\ncd ${{ ci.workspace }}/${{ variables.APP_NAME }}\n\ngo test -gcflags=all=-l -v -covermode=count -coverprofile=coverprofile.cov ./... &>report.out\n\ncat report.out\n\nif [ $? -gt 0 ]; then\n exit 1\nfi\n\ncp coverprofile.cov ${{ steps.step_7.outputs.COV_TMP_PATH }}\ncp report.out ${{ steps.step_7.outputs.COV_TMP_PATH }}\nzip -q ${{ ci.build_id }}_test.zip ${{ steps.step_7.outputs.COV_TMP_PATH }}/*\n" - runAdditionalOptions: - shell: null - checkout: null - - name: "单元测试产物归档" - id: "step_9" - if: null - if-modify: null - uses: "UploadArtifactory@1.*" + runAdditionalOptions: {} + - name: UT-单元测试覆盖率 + id: step_8 + run: | + # 您可以通过setEnv函数设置插件间传递的参数 + # echo "::set-output name=FILENAME::package.zip" + # 然后在后续的插件的表单中使用${{ FILENAME }}引用这个变量 + + # 您可以在质量红线中创建自定义指标,然后通过setGateValue函数设置指标值 + # setGateValue "CodeCoverage" $myValue + # 然后在质量红线选择相应指标和阈值。若不满足,流水线在执行时将会被卡住 + + # cd ${{ ci.workspace }} 可进入当前工作空间目录 + + #执行覆盖率并生成产物 + cd ${{ ci.workspace }}/${{ variables.APP_NAME }} + + go test -gcflags=all=-l -v -covermode=count -coverprofile=coverprofile.cov ./... &>report.out + + cat report.out + + if [ $? -gt 0 ]; then + exit 1 + fi + + cp coverprofile.cov ${{ steps.step_7.outputs.COV_TMP_PATH }} + cp report.out ${{ steps.step_7.outputs.COV_TMP_PATH }} + zip -q ${{ ci.build_id }}_test.zip ${{ steps.step_7.outputs.COV_TMP_PATH }}/* + runAdditionalOptions: {} + - name: 单元测试产物归档 + id: step_9 + uses: UploadArtifactory@1.* with: filePath: "${{ ci.workspace }}/${{ variables.APP_NAME }}/${{ ci.build_id }}_test.zip,${{ ci.workspace }}/${{ variables.APP_NAME }}/report.out" isCustomize: false - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - - name: "覆盖率-后置信息处理" - id: "step_covParseData" - if: null - if-modify: null - uses: "covParseData@5.*" + runAdditionalOptions: {} + - name: 覆盖率-后置信息处理 + id: step_covParseData + uses: covParseData@5.* with: - codeLanguage: "golang" + codeLanguage: golang codePath: "${{ ci.workspace }}" covProduct: "" covRobotId: "" - fileFromType: "local" + fileFromType: local filePath: "${{ ci.workspace }}/coverprofile.cov" - fileTypeGoLang: "out" + fileTypeGoLang: out localPreMr: false multiGitFlagSwitch: false needMerge: 1 - needReport: "need" + needReport: need needRobot: false - testFromType: "local" - testType: "unit_test" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null -- name: "测试产物解析" + testFromType: local + testType: unit_test + runAdditionalOptions: {} +- name: 测试产物解析 label: - - "d0a06f6986fa4670af65ccad7bb49d3a" - if: null + - d0a06f6986fa4670af65ccad7bb49d3a fast-kill: false jobs: - - id: "job_zPm" - name: "注册同源" - mutex: null + - id: job_zPm + name: 注册同源 runs-on: self-hosted: false - pool-name: "docker" + pool-name: docker container: - image: "mirrors.tencent.com/ci/tlinux_ci:3.5.1" - credentials: null - options: null - image-pull-policy: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + image: mirrors.tencent.com/ci/tlinux_ci:3.5.1 services: [] - if: null steps: - - name: "用例稳定性测试-上报注册" - id: "step_11" - if: null - if-modify: null - uses: "caseStabilityRegister@1.*" + - name: 用例稳定性测试-上报注册 + id: step_11 + uses: caseStabilityRegister@1.* with: case_stability_mode: 1 git_url: "${{ BK_CI_GIT_REPO_URL }}" - is_stable: "1" - lang_type: "go" + is_stable: 1 + lang_type: go pipeline_id: "${{ BK_CI_PIPELINE_ID }}" pipeline_name: "${{ BK_CI_PIPELINE_NAME }}" project_name: "${{ BK_CI_PROJECT_NAME }}" project_readable_name: "${{ BK_CI_PROJECT_NAME_CN }}" - sub_eps_biz: "自动关联-无需填写" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "job_EDT" - name: "单元测试结果上报" - mutex: null + sub_eps_biz: 自动关联-无需填写 + runAdditionalOptions: {} + - id: job_EDT + name: 单元测试结果上报 runs-on: self-hosted: false - pool-name: "agentless" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: agentless services: [] - if: null steps: - - name: "同源-单元测试产物解析" - id: "step_12" - if: null - if-modify: null - uses: "ngtestUnitTest@7.*" + - name: 同源-单元测试产物解析 + id: step_12 + uses: ngtestUnitTest@7.* with: api_dir: "" branch_name: "" commit_id: "" git_url: "" is_static_scan: true - test_type: "0" + test_type: 0 unit_namespace: "" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - - name: "同源后台质量红线" - id: "step_13" - if: null - if-modify: null - uses: "ngtestQuality@1.*" + runAdditionalOptions: {} + - name: 同源后台质量红线 + id: step_13 + uses: ngtestQuality@1.* with: custom_group_key: "" - data_type: "all" - env_type: "formal" + data_type: all + env_type: formal is_use_apiTest: "${{ is_use_apiTest }}" is_use_report: "${{ is_use_report }}" is_use_unitTest: "${{ is_use_unitTest }}" - poll_time: "5" - test_type: "unitest" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null -- name: "编译" + poll_time: 5 + test_type: unitest + runAdditionalOptions: {} +- name: 编译 label: - - "28ee946a59f64949a74f3dee40a1bda4" - if: null + - 28ee946a59f64949a74f3dee40a1bda4 fast-kill: false jobs: - - id: "job_aGC" - name: "编译" - mutex: null + - id: job_aGC + name: 编译 runs-on: self-hosted: false - pool-name: "docker" + pool-name: docker container: - image: "mirrors.tencent.com/ci/tlinux_ci:3.5.1" - credentials: null - options: null - image-pull-policy: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + image: mirrors.tencent.com/ci/tlinux_ci:3.5.1 services: [] - if: null steps: - - name: "拉取Git代码" - id: "step_download-code_4" - if: null - if-modify: null - uses: null + - name: 拉取Git代码 + id: step_download-code_4 with: autoCrlf: "false" refName: "${{ ci.branch }}" @@ -621,116 +417,76 @@ stages: fetchDepth: "" includePath: "" localPath: "${{ variables.APP_NAME }}" - pullType: "BRANCH" - strategy: "REVERT_UPDATE" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null + pullType: BRANCH + strategy: REVERT_UPDATE + runAdditionalOptions: {} checkout: "http://xxxxx/${{ variables.CODELIB_ALIAS }}.git" - - name: "tRPC编译" - id: "step_trpc_compile" - if: null - if-modify: null - uses: "TrpcCompile@1.*" + - name: tRPC编译 + id: step_trpc_compile + uses: TrpcCompile@1.* with: - id: "step_trpc_compile" + id: step_trpc_compile app: "${{ variables.123_APP }}" code_path: "${{ steps.step_download-code_4.outputs.BK_CI_GIT_REPO_URL }}" code_tag: "${{ ci.branch }}" fileName: "${{ variables.APP_NAME }}" git_key: "${{ variables.123_GIT_KEY }}" - language: "golang" + language: golang make_path: "${{ variables.123_MAKE_PATH }}" - platEnv: "formal" + platEnv: formal resetGitConfig: "TRUE" server: "${{ variables.123_SERVER }}" stageList: - - "pull" - - "compile" - - "tar" + - pull + - compile + - tar user: "${{ variables.123_USERNAME }}" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - - name: "归档构件" - id: "step_23" - if: null - if-modify: null - uses: "UploadArtifactory@1.*" + runAdditionalOptions: {} + - name: 归档构件 + id: step_23 + uses: UploadArtifactory@1.* with: filePath: "${{ steps.step_trpc_compile.outputs.make_path_abs }}/${{ steps.step_trpc_compile.outputs.file_name }}" isCustomize: false - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - - name: "Docker构建预处理" - id: "step_24" - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "# 通过./xxx.sh的方式执行脚本\n# 即若脚本中未指定解释器,则使用系统默认的shell\n\n# 您可以通过setEnv函数设置插件间传递的参数\n# echo \"::set-output name=FILENAME::package.zip\"\n# 然后在后续的插件的表单中使用${{ FILENAME }}引用这个变量\n\n# 您可以在质量红线中创建自定义指标,然后通过setGateValue函数设置指标值\n# setGateValue \"CodeCoverage\" $myValue\n# 然后在质量红线选择相应指标和阈值。若不满足,流水线在执行时将会被卡住\n\n# cd ${{ ci.workspace }} 可进入当前工作空间目录\n\ncp ${{ steps.step_trpc_compile.outputs.make_path_abs }}/${{ steps.step_trpc_compile.outputs.file_name }} ${{ ci.workspace }}/${{ variables.APP_NAME }}/scripts/app" - runAdditionalOptions: - shell: null - checkout: null - - name: "构建并推送Docker镜像" - id: "step_25" - if: null - if-modify: null - uses: "DockerBuildAndPushImage@3.*" + runAdditionalOptions: {} + - name: Docker构建预处理 + id: step_24 + run: |- + # 通过./xxx.sh的方式执行脚本 + # 即若脚本中未指定解释器,则使用系统默认的shell + + # 您可以通过setEnv函数设置插件间传递的参数 + # echo "::set-output name=FILENAME::package.zip" + # 然后在后续的插件的表单中使用${{ FILENAME }}引用这个变量 + + # 您可以在质量红线中创建自定义指标,然后通过setGateValue函数设置指标值 + # setGateValue "CodeCoverage" $myValue + # 然后在质量红线选择相应指标和阈值。若不满足,流水线在执行时将会被卡住 + + # cd ${{ ci.workspace }} 可进入当前工作空间目录 + + cp ${{ steps.step_trpc_compile.outputs.make_path_abs }}/${{ steps.step_trpc_compile.outputs.file_name }} ${{ ci.workspace }}/${{ variables.APP_NAME }}/scripts/app + runAdditionalOptions: {} + - name: 构建并推送Docker镜像 + id: step_25 + uses: DockerBuildAndPushImage@3.* with: dockerBuildArgs: "" dockerBuildDir: "${{ variables.APP_NAME }}/scripts" dockerFilePath: "${{ variables.APP_NAME }}/scripts/Dockerfile" enableProxy: false sourceMirrorTicketPair: - - key: "mirrors.tencent.com" - value: "mirrors_docker" + - key: mirrors.tencent.com + value: mirrors_docker sourceRepoItemsStr: [] targetImage: "mirrors.tencent.com/xxxxxxxxxx/${{ variables.APP_NAME }}" targetImageName: "" - targetImageTag: "v1.0.0" + targetImageTag: v1.0.0 targetRepoItemStr: [] - targetTicketId: "mirrors_docker" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null + targetTicketId: mirrors_docker + runAdditionalOptions: {} resource: repositories: - - repository: "pcg/stream-ci-template" - name: "stream-ci-template" - ref: null - credentials: null -finally: [] + - repository: pcg/stream-ci-template + name: stream-ci-template +finally: [] \ No newline at end of file diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/stages/stages.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/stages/stages.yml index c628000ccbb..60e9c4fc010 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/stages/stages.yml +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/stages/stages.yml @@ -1,184 +1,72 @@ --- -version: "v2.0" +version: v2.0 name: "" label: [] -triggerOn: +on: push: branches: - - "*" + - '*' tag: tags: - - "*" + - '*' mr: target-branches: - - "*" + - '*' action: - - "open" - - "reopen" - - "push-update" + - open + - reopen + - push-update stages: -- name: "template_stage_id_1" +- name: template_stage_id_1 label: [] - if: null fast-kill: false jobs: - - id: "template_stage_id_1_job_id_1" - name: "template_stage_id_1_job_id_1" - mutex: null + - id: template_stage_id_1_job_id_1 + name: template_stage_id_1_job_id_1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"template_stage_id_1_job_id_1 username world\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - - id: "template_stage_id_1_job_id_2" - name: "template_stage_id_1_job_id_1" - mutex: null + - run: | + echo "template_stage_id_1_job_id_1 username world" + runAdditionalOptions: {} + - id: template_stage_id_1_job_id_2 + name: template_stage_id_1_job_id_1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"template_stage_id_1_job_id_2 stagename STAGENAME\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null -- name: "stage_template_2" + - run: | + echo "template_stage_id_1_job_id_2 stagename STAGENAME" + runAdditionalOptions: {} +- name: stage_template_2 label: [] - if: null fast-kill: false jobs: - - id: "cyc_stage_id_1_job_id_1" - name: "cyc_stage_id_1_job_id_1" - mutex: null + - id: cyc_stage_id_1_job_id_1 + name: cyc_stage_id_1_job_id_1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"cyc_stage_id_1_job_id_1 username CYC_STAGE2\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null -- name: "stage_template_1" + - run: | + echo "cyc_stage_id_1_job_id_1 username CYC_STAGE2" + runAdditionalOptions: {} +- name: stage_template_1 label: [] - if: null fast-kill: false jobs: - - id: "cyc_stage_id_1_job_id_1" - name: "cyc_stage_id_1_job_id_1" - mutex: null + - id: cyc_stage_id_1_job_id_1 + name: cyc_stage_id_1_job_id_1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null + pool-name: docker services: [] - if: null steps: - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"cyc_stage_id_1_job_id_1 username CYC_STAGE1\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null - timeout-minutes: null - env: null - continue-on-error: null - strategy: null - depend-on: null - if-modify: null - check-in: null - check-out: null + - run: | + echo "cyc_stage_id_1_job_id_1 username CYC_STAGE1" + runAdditionalOptions: {} finally: [] diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/steps/stepss.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/steps/stepss.yml index 4fd33f02df3..098265f5a52 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/steps/stepss.yml +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/compared/steps/stepss.yml @@ -1,50 +1,37 @@ --- -version: "v2.0" +version: v2.0 name: "" label: [] -triggerOn: +on: push: branches: - - "*" + - '*' tag: tags: - - "*" + - '*' mr: target-branches: - - "*" + - '*' action: - - "open" - - "reopen" - - "push-update" + - open + - reopen + - push-update stages: -- name: "stage_1" +- name: stage_1 label: [] - if: null fast-kill: false jobs: - - id: "job-rGD3LLJ" - name: "job1" - mutex: null + - id: job-QkcEIsS + name: job1 runs-on: self-hosted: false - pool-name: "docker" - container: null - agent-selector: null - workspace: null - xcode: null - queue-timeout-minutes: null - needs: null - services: null - if: null + pool-name: docker steps: - - name: "拉取Git代码" - id: "1" - if: null - if-modify: null - uses: null + - name: 拉取Git代码 + id: 1 with: autoCrlf: "false" - refName: "master" + refName: master enableAutoCrlf: "false" enableGitLfs: "true" enableSubmodule: "true" @@ -53,51 +40,48 @@ stages: fetchDepth: "" includePath: "" localPath: "" - pullType: "BRANCH" - strategy: "REVERT_UPDATE" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null + pullType: BRANCH + strategy: REVERT_UPDATE + runAdditionalOptions: {} checkout: "" - - name: "CCK-腾讯代码分析(最新)" - id: "2" - if: null - if-modify: null - uses: "CodeccCheckAtomDebug@4.*" + - name: CCK-腾讯代码分析(最新) + id: 2 + uses: CodeccCheckAtomDebug@4.* with: languages: - - "GOLANG" - checkerSetType: "openScan" + - GOLANG + checkerSetType: openScan tools: - - "GOML" + - GOML asyncTask: false asyncTaskId: "" goPath: "" - pyVersion: "py3" - scriptType: "SHELL" - script: "# Coverity/Klocwork将通过调用编译脚本来编译您的代码,以追踪深层次的缺陷\n# 请使用依赖的构建工具如maven/cmake等写一个编译脚本build.sh\n# 确保build.sh能够编译代码\n# cd path/to/build.sh\n# sh build.sh" + pyVersion: py3 + scriptType: SHELL + script: |- + # Coverity/Klocwork将通过调用编译脚本来编译您的代码,以追踪深层次的缺陷 + # 请使用依赖的构建工具如maven/cmake等写一个编译脚本build.sh + # 确保build.sh能够编译代码 + # cd path/to/build.sh + # sh build.sh languageRuleSetMap: GOLANG_RULE: - - "standard_go" + - standard_go C_CPP_RULE: [] - rtxReceiverType: "0" + rtxReceiverType: 0 rtxReceiverList: [] botWebhookUrl: "" - botRemindRange: "1" - botRemindSeverity: "7" + botRemindRange: 1 + botRemindSeverity: 7 botRemaindTools: [] - emailReceiverType: "0" + emailReceiverType: 0 emailReceiverList: [] emailCCReceiverList: [] - instantReportStatus: "2" + instantReportStatus: 2 reportDate: [] reportTime: "" reportTools: [] - toolScanType: "1" + toolScanType: 1 mrCommentEnable: true newDefectJudgeFromDate: "" transferAuthorList: [] @@ -105,58 +89,54 @@ stages: customPath: [] openScanPrj: false GOLANG_RULE: - - "codecc_default_go" + - codecc_default_go GOLANG_TOOL: - toolList: - - "CLOC" - - "SENSITIVE" - - "DUPC" - - "CCN" + - CLOC + - SENSITIVE + - DUPC + - CCN - toolList: - - "GOML" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - - name: "CCK-腾讯代码分析(最新)" - id: "3" - if: null - if-modify: null - uses: "CodeccCheckAtomDebug@4.*" + - GOML + runAdditionalOptions: {} + - name: CCK-腾讯代码分析(最新) + id: 3 + uses: CodeccCheckAtomDebug@4.* with: languages: - - "GOLANG" - checkerSetType: "openScan" + - GOLANG + checkerSetType: openScan tools: - - "GOML" + - GOML asyncTask: false asyncTaskId: "" goPath: "" - pyVersion: "py3" - scriptType: "SHELL" - script: "# Coverity/Klocwork将通过调用编译脚本来编译您的代码,以追踪深层次的缺陷\n# 请使用依赖的构建工具如maven/cmake等写一个编译脚本build.sh\n# 确保build.sh能够编译代码\n# cd path/to/build.sh\n# sh build.sh" + pyVersion: py3 + scriptType: SHELL + script: |- + # Coverity/Klocwork将通过调用编译脚本来编译您的代码,以追踪深层次的缺陷 + # 请使用依赖的构建工具如maven/cmake等写一个编译脚本build.sh + # 确保build.sh能够编译代码 + # cd path/to/build.sh + # sh build.sh languageRuleSetMap: GOLANG_RULE: - - "standard_go" + - standard_go C_CPP_RULE: [] - rtxReceiverType: "0" + rtxReceiverType: 0 rtxReceiverList: [] botWebhookUrl: "" - botRemindRange: "1" - botRemindSeverity: "7" + botRemindRange: 1 + botRemindSeverity: 7 botRemaindTools: [] - emailReceiverType: "0" + emailReceiverType: 0 emailReceiverList: [] emailCCReceiverList: [] - instantReportStatus: "2" + instantReportStatus: 2 reportDate: [] reportTime: "" reportTools: [] - toolScanType: "1" + toolScanType: 1 mrCommentEnable: true newDefectJudgeFromDate: "" transferAuthorList: [] @@ -164,58 +144,54 @@ stages: customPath: [] openScanPrj: false GOLANG_RULE: - - "codecc_default_go" + - codecc_default_go GOLANG_TOOL: - toolList: - - "CLOC" - - "SENSITIVE" - - "DUPC" - - "CCN" + - CLOC + - SENSITIVE + - DUPC + - CCN - toolList: - - "GOML" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - - name: "CCK-腾讯代码分析(最新)" - id: "4" - if: null - if-modify: null - uses: "CodeccCheckAtomDebug@4.*" + - GOML + runAdditionalOptions: {} + - name: CCK-腾讯代码分析(最新) + id: 4 + uses: CodeccCheckAtomDebug@4.* with: languages: - - "GOLANG" - checkerSetType: "openScan" + - GOLANG + checkerSetType: openScan tools: - - "GOML" + - GOML asyncTask: false asyncTaskId: "" goPath: "" - pyVersion: "py3" - scriptType: "SHELL" - script: "# Coverity/Klocwork将通过调用编译脚本来编译您的代码,以追踪深层次的缺陷\n# 请使用依赖的构建工具如maven/cmake等写一个编译脚本build.sh\n# 确保build.sh能够编译代码\n# cd path/to/build.sh\n# sh build.sh" + pyVersion: py3 + scriptType: SHELL + script: |- + # Coverity/Klocwork将通过调用编译脚本来编译您的代码,以追踪深层次的缺陷 + # 请使用依赖的构建工具如maven/cmake等写一个编译脚本build.sh + # 确保build.sh能够编译代码 + # cd path/to/build.sh + # sh build.sh languageRuleSetMap: GOLANG_RULE: - - "standard_go" + - standard_go C_CPP_RULE: [] - rtxReceiverType: "0" + rtxReceiverType: 0 rtxReceiverList: [] botWebhookUrl: "" - botRemindRange: "1" - botRemindSeverity: "7" + botRemindRange: 1 + botRemindSeverity: 7 botRemaindTools: [] - emailReceiverType: "0" + emailReceiverType: 0 emailReceiverList: [] emailCCReceiverList: [] - instantReportStatus: "2" + instantReportStatus: 2 reportDate: [] reportTime: "" reportTools: [] - toolScanType: "1" + toolScanType: 1 mrCommentEnable: true newDefectJudgeFromDate: "" transferAuthorList: [] @@ -223,58 +199,54 @@ stages: customPath: [] openScanPrj: false GOLANG_RULE: - - "codecc_default_go" + - codecc_default_go GOLANG_TOOL: - toolList: - - "CLOC" - - "SENSITIVE" - - "DUPC" - - "CCN" + - CLOC + - SENSITIVE + - DUPC + - CCN - toolList: - - "GOML" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - - name: "CCK-腾讯代码分析(最新)" - id: "5" - if: null - if-modify: null - uses: "CodeccCheckAtomDebug@4.*" + - GOML + runAdditionalOptions: {} + - name: CCK-腾讯代码分析(最新) + id: 5 + uses: CodeccCheckAtomDebug@4.* with: languages: - - "GOLANG" - checkerSetType: "openScan" + - GOLANG + checkerSetType: openScan tools: - - "GOML" + - GOML asyncTask: false asyncTaskId: "" goPath: "" - pyVersion: "py3" - scriptType: "SHELL" - script: "# Coverity/Klocwork将通过调用编译脚本来编译您的代码,以追踪深层次的缺陷\n# 请使用依赖的构建工具如maven/cmake等写一个编译脚本build.sh\n# 确保build.sh能够编译代码\n# cd path/to/build.sh\n# sh build.sh" + pyVersion: py3 + scriptType: SHELL + script: |- + # Coverity/Klocwork将通过调用编译脚本来编译您的代码,以追踪深层次的缺陷 + # 请使用依赖的构建工具如maven/cmake等写一个编译脚本build.sh + # 确保build.sh能够编译代码 + # cd path/to/build.sh + # sh build.sh languageRuleSetMap: GOLANG_RULE: - - "standard_go" + - standard_go C_CPP_RULE: [] - rtxReceiverType: "0" + rtxReceiverType: 0 rtxReceiverList: [] botWebhookUrl: "" - botRemindRange: "1" - botRemindSeverity: "7" + botRemindRange: 1 + botRemindSeverity: 7 botRemaindTools: [] - emailReceiverType: "0" + emailReceiverType: 0 emailReceiverList: [] emailCCReceiverList: [] - instantReportStatus: "2" + instantReportStatus: 2 reportDate: [] reportTime: "" reportTools: [] - toolScanType: "1" + toolScanType: 1 mrCommentEnable: true newDefectJudgeFromDate: "" transferAuthorList: [] @@ -282,58 +254,54 @@ stages: customPath: [] openScanPrj: false GOLANG_RULE: - - "codecc_default_go" + - codecc_default_go GOLANG_TOOL: - toolList: - - "CLOC" - - "SENSITIVE" - - "DUPC" - - "CCN" + - CLOC + - SENSITIVE + - DUPC + - CCN - toolList: - - "GOML" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - - name: "CCK-腾讯代码分析(最新)" - id: "6" - if: null - if-modify: null - uses: "CodeccCheckAtomDebug@4.*" + - GOML + runAdditionalOptions: {} + - name: CCK-腾讯代码分析(最新) + id: 6 + uses: CodeccCheckAtomDebug@4.* with: languages: - - "GOLANG" - checkerSetType: "openScan" + - GOLANG + checkerSetType: openScan tools: - - "GOML" + - GOML asyncTask: false asyncTaskId: "" goPath: "" - pyVersion: "py3" - scriptType: "SHELL" - script: "# Coverity/Klocwork将通过调用编译脚本来编译您的代码,以追踪深层次的缺陷\n# 请使用依赖的构建工具如maven/cmake等写一个编译脚本build.sh\n# 确保build.sh能够编译代码\n# cd path/to/build.sh\n# sh build.sh" + pyVersion: py3 + scriptType: SHELL + script: |- + # Coverity/Klocwork将通过调用编译脚本来编译您的代码,以追踪深层次的缺陷 + # 请使用依赖的构建工具如maven/cmake等写一个编译脚本build.sh + # 确保build.sh能够编译代码 + # cd path/to/build.sh + # sh build.sh languageRuleSetMap: GOLANG_RULE: - - "standard_go" + - standard_go C_CPP_RULE: [] - rtxReceiverType: "0" + rtxReceiverType: 0 rtxReceiverList: [] botWebhookUrl: "" - botRemindRange: "1" - botRemindSeverity: "7" + botRemindRange: 1 + botRemindSeverity: 7 botRemaindTools: [] - emailReceiverType: "0" + emailReceiverType: 0 emailReceiverList: [] emailCCReceiverList: [] - instantReportStatus: "2" + instantReportStatus: 2 reportDate: [] reportTime: "" reportTools: [] - toolScanType: "1" + toolScanType: 1 mrCommentEnable: true newDefectJudgeFromDate: "" transferAuthorList: [] @@ -341,58 +309,54 @@ stages: customPath: [] openScanPrj: false GOLANG_RULE: - - "codecc_default_go" + - codecc_default_go GOLANG_TOOL: - toolList: - - "CLOC" - - "SENSITIVE" - - "DUPC" - - "CCN" + - CLOC + - SENSITIVE + - DUPC + - CCN - toolList: - - "GOML" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - - name: "CCK-腾讯代码分析(最新)" - id: "7" - if: null - if-modify: null - uses: "CodeccCheckAtomDebug@4.*" + - GOML + runAdditionalOptions: {} + - name: CCK-腾讯代码分析(最新) + id: 7 + uses: CodeccCheckAtomDebug@4.* with: languages: - - "GOLANG" - checkerSetType: "openScan" + - GOLANG + checkerSetType: openScan tools: - - "GOML" + - GOML asyncTask: false asyncTaskId: "" goPath: "" - pyVersion: "py3" - scriptType: "SHELL" - script: "# Coverity/Klocwork将通过调用编译脚本来编译您的代码,以追踪深层次的缺陷\n# 请使用依赖的构建工具如maven/cmake等写一个编译脚本build.sh\n# 确保build.sh能够编译代码\n# cd path/to/build.sh\n# sh build.sh" + pyVersion: py3 + scriptType: SHELL + script: |- + # Coverity/Klocwork将通过调用编译脚本来编译您的代码,以追踪深层次的缺陷 + # 请使用依赖的构建工具如maven/cmake等写一个编译脚本build.sh + # 确保build.sh能够编译代码 + # cd path/to/build.sh + # sh build.sh languageRuleSetMap: GOLANG_RULE: - - "standard_go" + - standard_go C_CPP_RULE: [] - rtxReceiverType: "0" + rtxReceiverType: 0 rtxReceiverList: [] botWebhookUrl: "" - botRemindRange: "1" - botRemindSeverity: "7" + botRemindRange: 1 + botRemindSeverity: 7 botRemaindTools: [] - emailReceiverType: "0" + emailReceiverType: 0 emailReceiverList: [] emailCCReceiverList: [] - instantReportStatus: "2" + instantReportStatus: 2 reportDate: [] reportTime: "" reportTools: [] - toolScanType: "1" + toolScanType: 1 mrCommentEnable: true newDefectJudgeFromDate: "" transferAuthorList: [] @@ -400,58 +364,54 @@ stages: customPath: [] openScanPrj: false GOLANG_RULE: - - "codecc_default_go" + - codecc_default_go GOLANG_TOOL: - toolList: - - "CLOC" - - "SENSITIVE" - - "DUPC" - - "CCN" + - CLOC + - SENSITIVE + - DUPC + - CCN - toolList: - - "GOML" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - - name: "CCK-腾讯代码分析(最新)" - id: "9" - if: null - if-modify: null - uses: "CodeccCheckAtomDebug@4.*" + - GOML + runAdditionalOptions: {} + - name: CCK-腾讯代码分析(最新) + id: 9 + uses: CodeccCheckAtomDebug@4.* with: languages: - - "GOLANG" - checkerSetType: "openScan" + - GOLANG + checkerSetType: openScan tools: - - "GOML" + - GOML asyncTask: false asyncTaskId: "" goPath: "" - pyVersion: "py3" - scriptType: "SHELL" - script: "# Coverity/Klocwork将通过调用编译脚本来编译您的代码,以追踪深层次的缺陷\n# 请使用依赖的构建工具如maven/cmake等写一个编译脚本build.sh\n# 确保build.sh能够编译代码\n# cd path/to/build.sh\n# sh build.sh" + pyVersion: py3 + scriptType: SHELL + script: |- + # Coverity/Klocwork将通过调用编译脚本来编译您的代码,以追踪深层次的缺陷 + # 请使用依赖的构建工具如maven/cmake等写一个编译脚本build.sh + # 确保build.sh能够编译代码 + # cd path/to/build.sh + # sh build.sh languageRuleSetMap: GOLANG_RULE: - - "standard_go" + - standard_go C_CPP_RULE: [] - rtxReceiverType: "0" + rtxReceiverType: 0 rtxReceiverList: [] botWebhookUrl: "" - botRemindRange: "1" - botRemindSeverity: "7" + botRemindRange: 1 + botRemindSeverity: 7 botRemaindTools: [] - emailReceiverType: "0" + emailReceiverType: 0 emailReceiverList: [] emailCCReceiverList: [] - instantReportStatus: "2" + instantReportStatus: 2 reportDate: [] reportTime: "" reportTools: [] - toolScanType: "1" + toolScanType: 1 mrCommentEnable: true newDefectJudgeFromDate: "" transferAuthorList: [] @@ -459,120 +419,40 @@ stages: customPath: [] openScanPrj: false GOLANG_RULE: - - "codecc_default_go" + - codecc_default_go GOLANG_TOOL: - toolList: - - "CLOC" - - "SENSITIVE" - - "DUPC" - - "CCN" + - CLOC + - SENSITIVE + - DUPC + - CCN - toolList: - - "GOML" - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: null - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"template_step_id_1 username world!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"cyc_step_id_1 username CYC_STEP1!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"cyc_step_id_3 username STEP6!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"cyc_step_id_2 username CYC_STEP4!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"cyc_step_id_6 username STEP6!\"\n" - runAdditionalOptions: - shell: null - checkout: null - - name: null - id: null - if: null - if-modify: null - uses: null - with: null - timeout-minutes: null - continue-on-error: null - retry-times: null - env: null - run: "echo \"cyc_step_id_5 username CYC_STEP5!\"\n" - runAdditionalOptions: - shell: null - checkout: null - if-modify: null + - GOML + runAdditionalOptions: {} + - run: | + echo "template_step_id_1 username world!" + runAdditionalOptions: {} + - run: | + echo "cyc_step_id_1 username CYC_STEP1!" + runAdditionalOptions: {} + - run: | + echo "cyc_step_id_3 username STEP6!" + runAdditionalOptions: {} + - run: | + echo "cyc_step_id_2 username CYC_STEP4!" + runAdditionalOptions: {} + - run: | + echo "cyc_step_id_6 username STEP6!" + runAdditionalOptions: {} + - run: | + echo "cyc_step_id_5 username CYC_STEP5!" + runAdditionalOptions: {} timeout-minutes: 480 env: {} continue-on-error: false - strategy: null depend-on: [] - if-modify: null - check-in: null - check-out: null resource: repositories: - - repository: "pcg/stream-ci-template" - name: "stream-ci-template" - ref: null - credentials: null + - repository: pcg/stream-ci-template + name: stream-ci-template finally: [] diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/samples/all/all.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/samples/all/all.yml index f097c5e4a45..976d57e304c 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/samples/all/all.yml +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/samples/all/all.yml @@ -1,7 +1,5 @@ version: v2.0 -on: delete - stages: - name: stage-1 check-in: diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/templates/repoC/templates/pipeline.yml b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/templates/repoC/templates/pipeline.yml index 5bf1600e73b..1e1d8c6d84d 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/templates/repoC/templates/pipeline.yml +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/test/resources/templates/repoC/templates/pipeline.yml @@ -74,7 +74,7 @@ stages: timeout-minutes: 480 continue-on-error: false retry-times: 0 - env: +# env: # - template: steps.yml # parameters: # username: STEP diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/trigger/CodeGitWebHookTriggerElement.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/trigger/CodeGitWebHookTriggerElement.kt index fd31ed72a56..df36dc88ecc 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/trigger/CodeGitWebHookTriggerElement.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/trigger/CodeGitWebHookTriggerElement.kt @@ -43,25 +43,25 @@ data class CodeGitWebHookTriggerElement( @ApiModelProperty("状态", required = false) override var status: String? = null, @ApiModelProperty("仓库ID", required = true) - val repositoryHashId: String?, + val repositoryHashId: String? = null, @ApiModelProperty("分支名称", required = false) - val branchName: String?, + val branchName: String? = null, @ApiModelProperty("用于排除的分支名", required = false) - val excludeBranchName: String?, + val excludeBranchName: String? = null, @ApiModelProperty("路径过滤类型", required = true) val pathFilterType: PathFilterType? = PathFilterType.NamePrefixFilter, @ApiModelProperty("用于包含的路径", required = false) - val includePaths: String?, + val includePaths: String? = null, @ApiModelProperty("用于排除的路径", required = false) - val excludePaths: String?, + val excludePaths: String? = null, @ApiModelProperty("用户白名单", required = false) val includeUsers: List? = null, @ApiModelProperty("用于排除的user id", required = false) - val excludeUsers: List?, + val excludeUsers: List? = null, @ApiModelProperty("事件类型", required = false) val eventType: CodeEventType?, @ApiModelProperty("是否为block", required = false) - val block: Boolean?, + val block: Boolean? = null, @ApiModelProperty("新版的git原子的类型") val repositoryType: RepositoryType? = null, @ApiModelProperty("新版的git代码库名") diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/trigger/CodeGithubWebHookTriggerElement.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/trigger/CodeGithubWebHookTriggerElement.kt index 3eb1827f1a0..dbb36e8d234 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/trigger/CodeGithubWebHookTriggerElement.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/trigger/CodeGithubWebHookTriggerElement.kt @@ -30,6 +30,7 @@ package com.tencent.devops.common.pipeline.pojo.element.trigger import com.tencent.devops.common.api.enums.RepositoryType import com.tencent.devops.common.pipeline.enums.StartType import com.tencent.devops.common.pipeline.pojo.element.trigger.enums.CodeEventType +import com.tencent.devops.common.pipeline.pojo.element.trigger.enums.PathFilterType import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -42,13 +43,51 @@ data class CodeGithubWebHookTriggerElement( @ApiModelProperty("状态", required = false) override var status: String? = null, @ApiModelProperty("仓库ID", required = true) - val repositoryHashId: String?, + val repositoryHashId: String? = null, @ApiModelProperty("分支名称", required = false) - val branchName: String?, + val branchName: String? = null, @ApiModelProperty("用于排除的分支名称", required = false) - val excludeBranchName: String?, + val excludeBranchName: String? = null, + @ApiModelProperty("路径过滤类型", required = true) + val pathFilterType: PathFilterType? = PathFilterType.NamePrefixFilter, + @ApiModelProperty("用于包含的路径", required = false) + val includePaths: String? = null, + @ApiModelProperty("用于排除的路径", required = false) + val excludePaths: String? = null, + @ApiModelProperty("用户白名单", required = false) + val includeUsers: List? = null, @ApiModelProperty("用于排除的user id", required = false) - val excludeUsers: String?, + val excludeUsers: String? = null, + @ApiModelProperty("tag名称", required = false) + val tagName: String? = null, + @ApiModelProperty("用于排除的tag名称", required = false) + val excludeTagName: String? = null, + @ApiModelProperty("tag从哪条分支创建", required = false) + val fromBranches: String? = null, + @ApiModelProperty("用于排除的源分支名称", required = false) + val excludeSourceBranchName: String? = null, + @ApiModelProperty("用于包含的源分支名称", required = false) + val includeSourceBranchName: String? = null, + @ApiModelProperty("webhook队列", required = false) + val webhookQueue: Boolean? = false, + @ApiModelProperty("code review 状态", required = false) + val includeCrState: List? = null, + @ApiModelProperty("code review 类型", required = false) + val includeCrTypes: List? = null, + @ApiModelProperty("code note comment", required = false) + val includeNoteComment: String? = null, + @ApiModelProperty("code note 类型", required = false) + val includeNoteTypes: List? = null, + @ApiModelProperty("是否启用回写") + val enableCheck: Boolean? = true, + @ApiModelProperty("issue事件action") + val includeIssueAction: List? = null, + @ApiModelProperty("mr事件action") + val includeMrAction: List? = null, + @ApiModelProperty("push事件action") + val includePushAction: List? = null, + @ApiModelProperty("是否启用第三方过滤") + val enableThirdFilter: Boolean? = false, @ApiModelProperty("事件类型", required = false) val eventType: CodeEventType?, @ApiModelProperty("新版的github原子的类型") diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/trigger/CodeTGitWebHookTriggerElement.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/trigger/CodeTGitWebHookTriggerElement.kt index 4cb174d9369..0a83b093fa1 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/trigger/CodeTGitWebHookTriggerElement.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/trigger/CodeTGitWebHookTriggerElement.kt @@ -68,23 +68,25 @@ data class CodeTGitWebHookTriggerData( @ApiModel("TGit事件触发数据") data class CodeTGitWebHookTriggerInput( @ApiModelProperty("仓库ID", required = true) - val repositoryHashId: String?, + val repositoryHashId: String? = null, @ApiModelProperty("分支名称", required = false) - val branchName: String?, + val branchName: String? = null, @ApiModelProperty("用于排除的分支名", required = false) - val excludeBranchName: String?, + val excludeBranchName: String? = null, @ApiModelProperty("路径过滤类型", required = true) val pathFilterType: PathFilterType? = PathFilterType.NamePrefixFilter, @ApiModelProperty("用于包含的路径", required = false) - val includePaths: String?, + val includePaths: String? = null, @ApiModelProperty("用于排除的路径", required = false) - val excludePaths: String?, + val excludePaths: String? = null, + @ApiModelProperty("用户白名单", required = false) + val includeUsers: List? = null, @ApiModelProperty("用于排除的user id", required = false) - val excludeUsers: List?, + val excludeUsers: List? = null, @ApiModelProperty("事件类型", required = false) val eventType: CodeEventType?, @ApiModelProperty("是否为block", required = false) - val block: Boolean?, + val block: Boolean? = null, @ApiModelProperty("新版的git原子的类型") val repositoryType: RepositoryType? = null, @ApiModelProperty("新版的git代码库名") @@ -93,10 +95,30 @@ data class CodeTGitWebHookTriggerInput( val tagName: String? = null, @ApiModelProperty("用于排除的tag名称", required = false) val excludeTagName: String? = null, + @ApiModelProperty("tag从哪条分支创建", required = false) + val fromBranches: String? = null, @ApiModelProperty("用于排除的源分支名称", required = false) val excludeSourceBranchName: String? = null, @ApiModelProperty("用于包含的源分支名称", required = false) val includeSourceBranchName: String? = null, + @ApiModelProperty("webhook队列", required = false) + val webhookQueue: Boolean? = false, @ApiModelProperty("code review 状态", required = false) - val includeCrState: List? = null + val includeCrState: List? = null, + @ApiModelProperty("code review 类型", required = false) + val includeCrTypes: List? = null, + @ApiModelProperty("code note comment", required = false) + val includeNoteComment: String? = null, + @ApiModelProperty("code note 类型", required = false) + val includeNoteTypes: List? = null, + @ApiModelProperty("是否启用回写") + val enableCheck: Boolean? = true, + @ApiModelProperty("issue事件action") + val includeIssueAction: List? = null, + @ApiModelProperty("mr事件action") + val includeMrAction: List? = null, + @ApiModelProperty("push事件action") + val includePushAction: List? = null, + @ApiModelProperty("是否启用第三方过滤") + val enableThirdFilter: Boolean? = false ) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt new file mode 100644 index 00000000000..5546bedfc0a --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt @@ -0,0 +1,123 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.api.user + +import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID +import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE +import com.tencent.devops.common.api.pojo.Result +import com.tencent.devops.common.pipeline.pojo.element.Element +import com.tencent.devops.process.pojo.transfer.PreviewResponse +import com.tencent.devops.process.pojo.transfer.TransferActionType +import com.tencent.devops.process.pojo.transfer.TransferBody +import com.tencent.devops.process.pojo.transfer.TransferResponse +import io.swagger.annotations.Api +import io.swagger.annotations.ApiOperation +import io.swagger.annotations.ApiParam +import javax.ws.rs.Consumes +import javax.ws.rs.GET +import javax.ws.rs.HeaderParam +import javax.ws.rs.POST +import javax.ws.rs.Path +import javax.ws.rs.PathParam +import javax.ws.rs.Produces +import javax.ws.rs.QueryParam +import javax.ws.rs.core.MediaType + +@Api(tags = ["USER_PIPELINE_TRANSFER"], description = "用户-流水线互转资源") +@Path("/user/transfer") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +@Suppress("ALL") +interface UserPipelineTransferResource { + + @ApiOperation("互转入口") + @POST + @Path("/{projectId}") + fun transfer( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线id", required = true) + @QueryParam("pipelineId") + pipelineId: String, + @ApiParam("操作类型", required = true) + @QueryParam("actionType") + actionType: TransferActionType, + data: TransferBody + ): Result + + @ApiOperation("task转yaml格式") + @POST + @Path("/{projectId}/task2yaml") + fun modelTaskTransfer( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线id", required = true) + @QueryParam("pipelineId") + pipelineId: String, + data: Element + ): Result + + @ApiOperation("task转json格式") + @POST + @Path("/{projectId}/task2yaml") + fun yamlTaskTransfer( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线id", required = true) + @QueryParam("pipelineId") + pipelineId: String, + yaml: String + ): Result + + @ApiOperation("触发前配置") + @GET + @Path("/{projectId}/preview_code") + fun preview( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线id", required = true) + @QueryParam("pipelineId") + pipelineId: String + ): Result +} diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/PreviewResponse.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/PreviewResponse.kt new file mode 100644 index 00000000000..1cb0f0668e8 --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/PreviewResponse.kt @@ -0,0 +1,45 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.pojo.transfer + +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty + +@ApiModel("构建模型-ID") +data class PreviewResponse( + @ApiModelProperty("yaml内容") + val yaml: String, + @ApiModelProperty("流水线编排") + val pipeline: List?, + @ApiModelProperty("触发器配置") + val trigger: List?, + @ApiModelProperty("通知配置") + val notice: List?, + @ApiModelProperty("基础设置") + val setting: List? +) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferActionType.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferActionType.kt new file mode 100644 index 00000000000..6e8d18c2191 --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferActionType.kt @@ -0,0 +1,41 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.pojo.transfer + +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty + +@ApiModel("流水线互转操作类型") +enum class TransferActionType { + @ApiModelProperty("完整转换:model -> yaml") + FULL_MODEL2YAML, + @ApiModelProperty("完整转换:yaml -> model") + FULL_YAML2MODEL, + @ApiModelProperty("yaml 中插入的插件") + YAML_INSERT_TASK; +} diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferBody.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferBody.kt new file mode 100644 index 00000000000..ac18e66e710 --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferBody.kt @@ -0,0 +1,40 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.pojo.transfer + +import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty + +@ApiModel("构建模型-ID") +data class TransferBody( + @ApiModelProperty("modelAndSetting") + val modelAndSetting: PipelineModelAndSetting, + @ApiModelProperty("当前yaml内容") + val oldYaml: String +) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferMark.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferMark.kt new file mode 100644 index 00000000000..4c5c1d906c6 --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferMark.kt @@ -0,0 +1,46 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.pojo.transfer + +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty + +@ApiModel("互转yaml定位") +data class TransferMark( + @ApiModelProperty("标记头") + val startMark: Mark, + @ApiModelProperty("标记尾") + val endMark: Mark +) { + data class Mark( + @ApiModelProperty("行数 0开始") + val line: Int, + @ApiModelProperty("列数 0开始") + val column: Int + ) +} diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferResponse.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferResponse.kt new file mode 100644 index 00000000000..3c7b9da2711 --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferResponse.kt @@ -0,0 +1,42 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.pojo.transfer + +import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty + +@ApiModel("流水线互转-Response") +data class TransferResponse( + @ApiModelProperty("modelAndSetting") + val modelAndSetting: PipelineModelAndSetting? = null, + @ApiModelProperty("当前yaml内容") + val newYaml: String? = null, + @ApiModelProperty("定位") + val mark: TransferMark? = null +) diff --git a/src/backend/ci/core/process/biz-process/build.gradle.kts b/src/backend/ci/core/process/biz-process/build.gradle.kts index b6689638b3a..a2490a363c2 100644 --- a/src/backend/ci/core/process/biz-process/build.gradle.kts +++ b/src/backend/ci/core/process/biz-process/build.gradle.kts @@ -47,6 +47,7 @@ dependencies { api(project(":core:log:api-log")) api(project(":core:common:common-webhook:biz-common-webhook")) api(project(":core:auth:api-auth")) + api(project(":core:common:common-pipeline-yaml")) api("org.springframework.boot:spring-boot-starter-websocket") api("javax.websocket:javax.websocket-api") diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt new file mode 100644 index 00000000000..aad6180ce4b --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt @@ -0,0 +1,76 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.api + +import com.tencent.devops.common.api.pojo.Result +import com.tencent.devops.common.pipeline.pojo.element.Element +import com.tencent.devops.common.web.RestResource +import com.tencent.devops.process.api.user.UserPipelineTransferResource +import com.tencent.devops.process.pojo.transfer.PreviewResponse +import com.tencent.devops.process.pojo.transfer.TransferActionType +import com.tencent.devops.process.pojo.transfer.TransferBody +import com.tencent.devops.process.pojo.transfer.TransferResponse +import com.tencent.devops.process.service.transfer.PipelineTransferService +import org.springframework.beans.factory.annotation.Autowired + +@RestResource +class UserPipelineTransferResourceImpl @Autowired constructor( + private val transferService: PipelineTransferService +) : UserPipelineTransferResource { + override fun transfer( + userId: String, + projectId: String, + pipelineId: String, + actionType: TransferActionType, + data: TransferBody + ): Result { + return Result(transferService.transfer(userId, projectId, pipelineId, actionType, data)) + } + + override fun modelTaskTransfer( + userId: String, + projectId: String, + pipelineId: String, + data: Element + ): Result { + return Result(transferService.modelTaskTransfer(userId, projectId, pipelineId, data)) + } + + override fun yamlTaskTransfer( + userId: String, + projectId: String, + pipelineId: String, + yaml: String + ): Result { + return Result(transferService.yamlTaskTransfer(userId, projectId, pipelineId, yaml)) + } + + override fun preview(userId: String, projectId: String, pipelineId: String): Result { + return Result(transferService.preview(userId, projectId, pipelineId)) + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferService.kt new file mode 100644 index 00000000000..919bc19a400 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferService.kt @@ -0,0 +1,204 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.service.transfer + +import com.fasterxml.jackson.core.type.TypeReference +import com.fasterxml.jackson.databind.ObjectMapper +import com.tencent.devops.common.api.exception.ErrorCodeException +import com.tencent.devops.common.api.util.Watcher +import com.tencent.devops.common.client.Client +import com.tencent.devops.common.pipeline.pojo.element.Element +import com.tencent.devops.process.dao.PipelineViewUserLastViewDao +import com.tencent.devops.process.dao.PipelineViewUserSettingsDao +import com.tencent.devops.process.dao.label.PipelineGroupDao +import com.tencent.devops.process.dao.label.PipelineLabelDao +import com.tencent.devops.process.dao.label.PipelineLabelPipelineDao +import com.tencent.devops.process.dao.label.PipelineViewDao +import com.tencent.devops.process.dao.label.PipelineViewTopDao +import com.tencent.devops.process.engine.dao.PipelineInfoDao +import com.tencent.devops.process.engine.service.PipelineRepositoryService +import com.tencent.devops.process.permission.PipelineGroupPermissionService +import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting +import com.tencent.devops.process.pojo.transfer.PreviewResponse +import com.tencent.devops.process.pojo.transfer.TransferActionType +import com.tencent.devops.process.pojo.transfer.TransferBody +import com.tencent.devops.process.pojo.transfer.TransferMark +import com.tencent.devops.process.pojo.transfer.TransferResponse +import com.tencent.devops.process.service.label.PipelineGroupService +import com.tencent.devops.process.yaml.modelTransfer.ElementTransfer +import com.tencent.devops.process.yaml.modelTransfer.ModelTransfer +import com.tencent.devops.process.yaml.modelTransfer.TransferMapper +import com.tencent.devops.process.yaml.modelTransfer.pojo.ModelTransferInput +import com.tencent.devops.process.yaml.modelTransfer.pojo.YamlTransferInput +import com.tencent.devops.process.yaml.pojo.TemplatePath +import com.tencent.devops.process.yaml.pojo.YamlVersion +import com.tencent.devops.process.yaml.v2.models.PreTemplateScriptBuildYaml +import com.tencent.devops.process.yaml.v2.models.step.PreStep +import com.tencent.devops.process.yaml.v2.parsers.template.YamlTemplate +import com.tencent.devops.process.yaml.v2.parsers.template.YamlTemplateConf +import com.tencent.devops.process.yaml.v2.parsers.template.models.GetTemplateParam +import com.tencent.devops.process.yaml.v2.utils.ScriptYmlUtils +import org.jooq.DSLContext +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Service + +@Suppress("ALL") +@Service +class PipelineTransferService @Autowired constructor( + private val dslContext: DSLContext, + private val objectMapper: ObjectMapper, + private val pipelineViewDao: PipelineViewDao, + private val pipelineInfoDao: PipelineInfoDao, + private val pipelineLabelDao: PipelineLabelDao, + private val pipelineGroupDao: PipelineGroupDao, + private val pipelineLabelPipelineDao: PipelineLabelPipelineDao, + private val pipelineViewTopDao: PipelineViewTopDao, + private val pipelineViewUserSettingDao: PipelineViewUserSettingsDao, + private val pipelineViewLastViewDao: PipelineViewUserLastViewDao, + private val pipelineGroupService: PipelineGroupService, + private val client: Client, + private val pipelineGroupPermissionService: PipelineGroupPermissionService, + private val modelTransfer: ModelTransfer, + private val elementTransfer: ElementTransfer, + private val pipelineRepositoryService: PipelineRepositoryService +) { + + companion object { + private val logger = LoggerFactory.getLogger(PipelineTransferService::class.java) + private const val TEMPLATE_ROOT_FILE = "TEMPLATE_ROOT_FILE" + private val pipeline_key = listOf("stages", "jobs", "steps", "finally") + private val trigger_key = listOf("on") + private val notice_key = listOf("notices") + private val setting_key = listOf("concurrency", "name", "version", "label") + } + + fun getTemplate(param: GetTemplateParam): String { + return "" + } + + fun transfer( + userId: String, + projectId: String, + pipelineId: String, + actionType: TransferActionType, + data: TransferBody + ): TransferResponse { + + val watcher = Watcher(id = "yaml2Model") + // todo 权限校验 + when (actionType) { + TransferActionType.FULL_MODEL2YAML -> { + val yml = modelTransfer.model2yaml( + ModelTransferInput( + data.modelAndSetting.model, + data.modelAndSetting.setting, + YamlVersion.Version.V3_0 + ) + ) + return TransferResponse(newYaml = TransferMapper.toYaml(yml)) + } + TransferActionType.FULL_YAML2MODEL -> { + watcher.start("FULL_YAML2MODEL start") + val pipelineInfo = pipelineRepositoryService.getPipelineInfo(projectId, pipelineId) + val pYml = TransferMapper.getObjectMapper() + .readValue(data.oldYaml, object : TypeReference() {}) + watcher.start("parse template") + pYml.replaceTemplate { templateFilter -> + YamlTemplate( + yamlObject = templateFilter, + filePath = TemplatePath(TEMPLATE_ROOT_FILE), + extraParameters = this, + getTemplateMethod = ::getTemplate, + nowRepo = null, + repo = null, + resourcePoolMapExt = null, + conf = YamlTemplateConf( + useOldParametersExpression = false // todo + ) + ).replace() + } + watcher.start("transfer start") + val input = YamlTransferInput( + pipelineInfo?.creator ?: userId, projectId, pYml + ) + val model = modelTransfer.yaml2Model(input) + val setting = modelTransfer.yaml2Setting(input) + return TransferResponse(modelAndSetting = PipelineModelAndSetting(model, setting)) + } + } + return TransferResponse() + } + + fun modelTaskTransfer( + userId: String, + projectId: String, + pipelineId: String, + data: Element + ): String { + // todo 权限校验 + val yml = elementTransfer.element2YamlStep(data) ?: throw ErrorCodeException(errorCode = "") + return TransferMapper.toYaml(yml) + } + + fun yamlTaskTransfer( + userId: String, + projectId: String, + pipelineId: String, + yaml: String + ): Element { + // todo 权限校验 + val tYml = TransferMapper.getObjectMapper() + .readValue(yaml, object : TypeReference() {}) + return elementTransfer.yaml2element(ScriptYmlUtils.preStepToStep(tYml), null) + } + + fun preview(userId: String, projectId: String, pipelineId: String): PreviewResponse { + // todo 权限校验 + val yml = getPipelineYaml(userId, projectId, pipelineId) + val pipelineIndex = mutableListOf() + val triggerIndex = mutableListOf() + val noticeIndex = mutableListOf() + val settingIndex = mutableListOf() + TransferMapper.getYamlLevelOneIndex(yml).forEach { (key, value) -> + if (key in pipeline_key) pipelineIndex.add(value) + if (key in trigger_key) triggerIndex.add(value) + if (key in notice_key) noticeIndex.add(value) + if (key in setting_key) settingIndex.add(value) + } + return PreviewResponse(yml, pipelineIndex, triggerIndex, noticeIndex, settingIndex) + } + + private fun getPipelineYaml(userId: String, projectId: String, pipelineId: String): String { + // 临时方案 todo + val classLoader = Thread.currentThread().contextClassLoader + val resourceAsStream = classLoader.getResourceAsStream("temp.yml") + + return resourceAsStream?.bufferedReader().use { it?.readText() } ?: "" + } +} diff --git a/src/backend/ci/core/store/api-store-image/src/main/kotlin/com/tencent/devops/store/api/image/service/ServiceStoreImageResource.kt b/src/backend/ci/core/store/api-store-image/src/main/kotlin/com/tencent/devops/store/api/image/service/ServiceStoreImageResource.kt index 738a04525ac..5cfff4d6614 100644 --- a/src/backend/ci/core/store/api-store-image/src/main/kotlin/com/tencent/devops/store/api/image/service/ServiceStoreImageResource.kt +++ b/src/backend/ci/core/store/api-store-image/src/main/kotlin/com/tencent/devops/store/api/image/service/ServiceStoreImageResource.kt @@ -85,6 +85,18 @@ interface ServiceStoreImageResource { buildId: String? ): Result + @ApiOperation("根据code查询镜像详情简化版(只查镜像信息,不做额外校验)") + @GET + @Path("/image/imageCodes/{imageCode}/imageVersions/{imageVersion}") + fun getImageInfoByCodeAndVersion( + @ApiParam("镜像标识", required = true) + @PathParam("imageCode") + imageCode: String, + @ApiParam("镜像版本", required = false) + @PathParam("imageVersion") + imageVersion: String? + ): Result + @ApiOperation("获取所有的自研公共镜像") @GET @Path("/image/self_develop/public_images") diff --git a/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/api/atom/ServiceMarketAtomResource.kt b/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/api/atom/ServiceMarketAtomResource.kt index 67156d84a82..b81d70432d7 100644 --- a/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/api/atom/ServiceMarketAtomResource.kt +++ b/src/backend/ci/core/store/api-store/src/main/kotlin/com/tencent/devops/store/api/atom/ServiceMarketAtomResource.kt @@ -36,6 +36,7 @@ import com.tencent.devops.store.pojo.atom.AtomPipeline import com.tencent.devops.store.pojo.atom.AtomPostReqItem import com.tencent.devops.store.pojo.atom.AtomPostResp import com.tencent.devops.store.pojo.atom.AtomVersion +import com.tencent.devops.store.pojo.atom.ElementThirdPartySearchParam import com.tencent.devops.store.pojo.atom.GetRelyAtom import com.tencent.devops.store.pojo.atom.InstallAtomReq import com.tencent.devops.store.pojo.atom.enums.AtomStatusEnum @@ -163,4 +164,11 @@ interface ServiceMarketAtomResource { @ApiParam("getRelyAtom", required = false) getRelyAtom: GetRelyAtom ): Result>?> + + @ApiOperation("查看插件参数的依赖关系") + @POST + @Path("/atom/default_value") + fun getAtomsDefaultValue( + atom: ElementThirdPartySearchParam + ): Result> } diff --git a/src/backend/ci/core/store/biz-store-image/src/main/kotlin/com/tencent/devops/store/resources/image/service/ServiceStoreImageResourceImpl.kt b/src/backend/ci/core/store/biz-store-image/src/main/kotlin/com/tencent/devops/store/resources/image/service/ServiceStoreImageResourceImpl.kt index 03cf99953b3..2bd06373897 100644 --- a/src/backend/ci/core/store/biz-store-image/src/main/kotlin/com/tencent/devops/store/resources/image/service/ServiceStoreImageResourceImpl.kt +++ b/src/backend/ci/core/store/biz-store-image/src/main/kotlin/com/tencent/devops/store/resources/image/service/ServiceStoreImageResourceImpl.kt @@ -94,4 +94,13 @@ class ServiceStoreImageResourceImpl @Autowired constructor( ) ) } + + override fun getImageInfoByCodeAndVersion(imageCode: String, imageVersion: String?): Result { + return Result( + imageService.getImageInfoByCodeAndVersion( + imageCode = imageCode, + imageVersion = imageVersion + ) + ) + } } diff --git a/src/backend/ci/core/store/biz-store-image/src/main/kotlin/com/tencent/devops/store/service/image/ImageService.kt b/src/backend/ci/core/store/biz-store-image/src/main/kotlin/com/tencent/devops/store/service/image/ImageService.kt index 4180b48111d..297d3c9143c 100644 --- a/src/backend/ci/core/store/biz-store-image/src/main/kotlin/com/tencent/devops/store/service/image/ImageService.kt +++ b/src/backend/ci/core/store/biz-store-image/src/main/kotlin/com/tencent/devops/store/service/image/ImageService.kt @@ -724,6 +724,30 @@ abstract class ImageService @Autowired constructor() { } } + fun getImageInfoByCodeAndVersion( + imageCode: String, + imageVersion: String? + ): ImageRepoInfo? { + // 区分是否为调试项目 + val imageStatusList = mutableListOf( + ImageStatusEnum.RELEASED.status.toByte(), + ImageStatusEnum.UNDERCARRIAGING.status.toByte(), + ImageStatusEnum.UNDERCARRIAGED.status.toByte() + ) + val imageRecords = + imageDao.getImagesByBaseVersion( + dslContext = dslContext, + imageCode = imageCode, + imageStatusSet = imageStatusList.toSet(), + baseVersion = imageVersion + ) + imageRecords?.sortWith(Comparator { o1, o2 -> + ImageUtil.compareVersion(o2.get(KEY_IMAGE_VERSION) as String?, o1.get(KEY_IMAGE_VERSION) as String?) + }) + val latestImage = imageRecords?.get(0) + return latestImage?.let { getImageRepoInfoByRecord(it) } + } + fun getSelfDevelopPublicImages( interfaceName: String? = "Anon interface" ): List { diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/resources/atom/ServiceMarketAtomResourceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/resources/atom/ServiceMarketAtomResourceImpl.kt index d706fe50420..fe4259e4417 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/resources/atom/ServiceMarketAtomResourceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/resources/atom/ServiceMarketAtomResourceImpl.kt @@ -38,6 +38,7 @@ import com.tencent.devops.store.pojo.atom.AtomPipeline import com.tencent.devops.store.pojo.atom.AtomPostReqItem import com.tencent.devops.store.pojo.atom.AtomPostResp import com.tencent.devops.store.pojo.atom.AtomVersion +import com.tencent.devops.store.pojo.atom.ElementThirdPartySearchParam import com.tencent.devops.store.pojo.atom.GetRelyAtom import com.tencent.devops.store.pojo.atom.InstallAtomReq import com.tencent.devops.store.pojo.atom.enums.AtomStatusEnum @@ -110,4 +111,8 @@ class ServiceMarketAtomResourceImpl @Autowired constructor( override fun getAtomRely(getRelyAtom: GetRelyAtom): Result>?> { return Result(marketAtomService.getAtomsRely(getRelyAtom = getRelyAtom)) } + + override fun getAtomsDefaultValue(atom: ElementThirdPartySearchParam): Result> { + return Result(marketAtomService.getAtomsDefaultValue(atom = atom)) + } } diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/MarketAtomService.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/MarketAtomService.kt index 2150c4c9498..eb940088798 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/MarketAtomService.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/MarketAtomService.kt @@ -36,6 +36,7 @@ import com.tencent.devops.store.pojo.atom.AtomPostReqItem import com.tencent.devops.store.pojo.atom.AtomPostResp import com.tencent.devops.store.pojo.atom.AtomVersion import com.tencent.devops.store.pojo.atom.AtomVersionListItem +import com.tencent.devops.store.pojo.atom.ElementThirdPartySearchParam import com.tencent.devops.store.pojo.atom.GetRelyAtom import com.tencent.devops.store.pojo.atom.InstallAtomReq import com.tencent.devops.store.pojo.atom.MarketAtomResp @@ -178,6 +179,11 @@ interface MarketAtomService { */ fun getAtomsRely(getRelyAtom: GetRelyAtom): Map> + /** + * 获得插件默认值 + */ + fun getAtomsDefaultValue(atom: ElementThirdPartySearchParam): Map + /** * 查找带post属性的插件 */ diff --git a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomServiceImpl.kt b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomServiceImpl.kt index 6beb667dca5..06f2b023c8b 100644 --- a/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomServiceImpl.kt +++ b/src/backend/ci/core/store/biz-store/src/main/kotlin/com/tencent/devops/store/service/atom/impl/MarketAtomServiceImpl.kt @@ -91,6 +91,7 @@ import com.tencent.devops.store.pojo.atom.AtomPostReqItem import com.tencent.devops.store.pojo.atom.AtomPostResp import com.tencent.devops.store.pojo.atom.AtomVersion import com.tencent.devops.store.pojo.atom.AtomVersionListItem +import com.tencent.devops.store.pojo.atom.ElementThirdPartySearchParam import com.tencent.devops.store.pojo.atom.GetRelyAtom import com.tencent.devops.store.pojo.atom.InstallAtomReq import com.tencent.devops.store.pojo.atom.MarketAtomResp @@ -132,16 +133,16 @@ import com.tencent.devops.store.service.common.StoreTotalStatisticService import com.tencent.devops.store.service.common.StoreUserService import com.tencent.devops.store.service.websocket.StoreWebsocketService import com.tencent.devops.store.utils.StoreUtils -import java.time.LocalDateTime -import java.util.Calendar -import java.util.concurrent.Callable -import java.util.concurrent.Executors -import java.util.concurrent.Future import org.jooq.DSLContext import org.jooq.impl.DSL import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Value +import java.time.LocalDateTime +import java.util.Calendar +import java.util.concurrent.Callable +import java.util.concurrent.Executors +import java.util.concurrent.Future @Suppress("ALL") abstract class MarketAtomServiceImpl @Autowired constructor() : MarketAtomService { @@ -328,11 +329,13 @@ abstract class MarketAtomServiceImpl @Autowired constructor() : MarketAtomServic val atomIndexInfos = atomIndexInfosMap[atomCode] val members = memberData?.get(atomCode) val defaultFlag = it[tAtom.DEFAULT_FLAG] as Boolean - val flag = storeCommonService.generateInstallFlag(defaultFlag = defaultFlag, + val flag = storeCommonService.generateInstallFlag( + defaultFlag = defaultFlag, members = members, userId = userId, visibleList = visibleList, - userDeptList = userDeptList) + userDeptList = userDeptList + ) val classifyId = it[tAtom.CLASSIFY_ID] as String var logoUrl = it[tAtom.LOGO_URL] logoUrl = if (logoUrl?.contains("?") == true) { @@ -1198,6 +1201,29 @@ abstract class MarketAtomServiceImpl @Autowired constructor() : MarketAtomServic return result } + override fun getAtomsDefaultValue(atom: ElementThirdPartySearchParam): Map { + val atomInfo = atomDao.getPipelineAtom(dslContext, atom.atomCode, atom.version) ?: return emptyMap() + val res = mutableMapOf() + val props: Map = jacksonObjectMapper().readValue(atomInfo.props) + if (null != props["input"]) { + val input = props["input"] as Map + input.forEach { inputIt -> + val paramKey = inputIt.key + val paramValueMap = inputIt.value as Map + val default = when (val d = paramValueMap["default"]) { + null -> null + is List<*> -> d.joinToString(separator = ",") + is String -> d + else -> d.toString() + } + if (default != null) { + res[paramKey] = default + } + } + } + return res + } + @Suppress("UNCHECKED_CAST") private fun generateYaml(atom: TAtomRecord, defaultShowFlag: Boolean?): String { val sb = StringBuilder() @@ -1336,7 +1362,7 @@ abstract class MarketAtomServiceImpl @Autowired constructor() : MarketAtomServic } val type = paramValueMap["type"] val required = null != paramValueMap["required"] && - "true".equals(paramValueMap["required"].toString(), true) + "true".equals(paramValueMap["required"].toString(), true) val defaultValue = paramValueMap["default"] val multipleMap = paramValueMap["optionsConf"] val multiple = if (null != multipleMap && null != (multipleMap as Map)["multiple"]) { @@ -1390,7 +1416,7 @@ abstract class MarketAtomServiceImpl @Autowired constructor() : MarketAtomServic "atom-checkbox" -> sb.append("boolean") "key-value-normal" -> sb.append( "\n - key: string" + - "\n value: string" + "\n value: string" ) else -> sb.append("string") } diff --git a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/ManualTriggerService.kt b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/ManualTriggerService.kt index 3f6a086b25d..e8127eeb21b 100644 --- a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/ManualTriggerService.kt +++ b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/ManualTriggerService.kt @@ -53,6 +53,7 @@ import com.tencent.devops.process.api.service.ServicePipelineSettingResource import com.tencent.devops.process.pojo.pipeline.DynamicParameterInfo import com.tencent.devops.process.pojo.pipeline.DynamicParameterInfoParam import com.tencent.devops.process.pojo.pipeline.StartUpInfo +import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.models.PreTemplateScriptBuildYaml import com.tencent.devops.process.yaml.v2.models.Variable import com.tencent.devops.process.yaml.v2.models.VariablePropType @@ -280,7 +281,7 @@ class ManualTriggerService @Autowired constructor( return YamlTemplate( yamlObject = yamlObject, - filePath = StreamYamlTrigger.STREAM_TEMPLATE_ROOT_FILE, + filePath = TemplatePath(StreamYamlTrigger.STREAM_TEMPLATE_ROOT_FILE), extraParameters = action, getTemplateMethod = yamlTemplateService::getTemplate, nowRepo = null, diff --git a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlTrigger.kt b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlTrigger.kt index c76bb8b271b..b745a82c200 100644 --- a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlTrigger.kt +++ b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlTrigger.kt @@ -36,7 +36,10 @@ import com.tencent.devops.common.pipeline.enums.BuildStatus import com.tencent.devops.common.pipeline.enums.ChannelCode import com.tencent.devops.common.service.prometheus.BkTimed import com.tencent.devops.process.api.service.ServicePipelineSettingResource +import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.exception.YamlFormatException +import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYaml +import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYamlI import com.tencent.devops.process.yaml.v2.models.Resources import com.tencent.devops.process.yaml.v2.models.ResourcesPools import com.tencent.devops.process.yaml.v2.models.format @@ -433,7 +436,7 @@ class StreamYamlTrigger @Autowired constructor( try { val preYamlObject = YamlTemplate( yamlObject = preTemplateYamlObject, - filePath = filePath, + filePath = TemplatePath(filePath), extraParameters = action, getTemplateMethod = yamlTemplateService::getTemplate, nowRepo = null, @@ -442,7 +445,7 @@ class StreamYamlTrigger @Autowired constructor( conf = YamlTemplateConf( useOldParametersExpression = action.data.context.pipelineAsCodeSettings?.enable != true ) - ).replace() + ).replace() as PreScriptBuildYaml val newPreYamlObject = preYamlObject.copy( resources = Resources( diff --git a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/pojo/ManualPreScriptBuildYaml.kt b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/pojo/ManualPreScriptBuildYaml.kt index 01271d253e0..7ec61158284 100644 --- a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/pojo/ManualPreScriptBuildYaml.kt +++ b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/pojo/ManualPreScriptBuildYaml.kt @@ -29,6 +29,7 @@ package com.tencent.devops.stream.trigger.pojo import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude +import com.tencent.devops.process.yaml.pojo.YamlVersion import com.tencent.devops.process.yaml.v2.models.Concurrency import com.tencent.devops.process.yaml.v2.models.Extends import com.tencent.devops.process.yaml.v2.models.GitNotices @@ -51,7 +52,7 @@ class ManualPreScriptBuildYaml( override var version: String?, override var name: String?, override var label: List? = null, - override var triggerOn: PreTriggerOn?, + var triggerOn: PreTriggerOn?, var inputs: Map?, override var variables: Map? = null, override var stages: List? = null, @@ -79,4 +80,6 @@ class ManualPreScriptBuildYaml( finally = pre.finally, concurrency = pre.concurrency ) + + override fun yamlVersion() = YamlVersion.Version.V2_0 } From 84a3347b63e0e1b475a522ac3b8d76f78c6c2805 Mon Sep 17 00:00:00 2001 From: yongyiduan Date: Thu, 10 Aug 2023 10:40:23 +0800 Subject: [PATCH 050/852] =?UTF-8?q?=E3=80=90=E8=93=9D=E7=9B=BE-=E8=AF=84?= =?UTF-8?q?=E5=AE=A1=E4=BC=9A=E5=B7=B2=E8=AF=84=E5=AE=A1=E3=80=91=E3=80=90?= =?UTF-8?q?PAC=E3=80=91feat=EF=BC=9A=E6=96=B0=E5=BB=BA/=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=94=AF=E6=8C=81=E4=BB=A5=20Code?= =?UTF-8?q?=20=E6=96=B9=E5=BC=8F=E7=BC=96=E6=8E=92=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=20#8125?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tencent/devops/process/yaml/modelTransfer/StageTransfer.kt | 2 +- .../devops/process/yaml/modelTransfer/TriggerTransfer.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt index b1e6b8a3069..8e9ef890257 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt @@ -85,7 +85,7 @@ class StageTransfer @Autowired(required = false) constructor( val triggerContainer = TriggerContainer( id = "0", - name = I18nUtil.getCodeLanMessage(CommonMessageCode.BK_BUILD_MSG_TRIGGERS), + name = I18nUtil.getCodeLanMessage(CommonMessageCode.BK_BUILD_TRIGGER), elements = triggerElementList, status = null, startEpoch = null, diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt index 4fe796f47b3..85a6f2a207c 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt @@ -68,7 +68,7 @@ class TriggerTransfer @Autowired(required = false) constructor( if (triggerOn.manual != "disabled") { elementQueue.add( ManualTriggerElement( - I18nUtil.getCodeLanMessage(CommonMessageCode.BK_BUILD_MSG_MANUAL), + I18nUtil.getCodeLanMessage(CommonMessageCode.BK_MANUAL_TRIGGER), "T-1-1-1" ) ) From d3773b246006109f23290fb2ce77312e302061cd Mon Sep 17 00:00:00 2001 From: yongyiduan Date: Thu, 10 Aug 2023 10:51:47 +0800 Subject: [PATCH 051/852] =?UTF-8?q?=E3=80=90=E8=93=9D=E7=9B=BE-=E8=AF=84?= =?UTF-8?q?=E5=AE=A1=E4=BC=9A=E5=B7=B2=E8=AF=84=E5=AE=A1=E3=80=91=E3=80=90?= =?UTF-8?q?PAC=E3=80=91feat=EF=BC=9A=E6=96=B0=E5=BB=BA/=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=94=AF=E6=8C=81=E4=BB=A5=20Code?= =?UTF-8?q?=20=E6=96=B9=E5=BC=8F=E7=BC=96=E6=8E=92=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=20#8125?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/api/UserPipelineTransferResourceImpl.kt | 4 ++-- ...elineTransferService.kt => PipelineTransferYamlService.kt} | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/{PipelineTransferService.kt => PipelineTransferYamlService.kt} (99%) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt index aad6180ce4b..b93930da34c 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt @@ -35,12 +35,12 @@ import com.tencent.devops.process.pojo.transfer.PreviewResponse import com.tencent.devops.process.pojo.transfer.TransferActionType import com.tencent.devops.process.pojo.transfer.TransferBody import com.tencent.devops.process.pojo.transfer.TransferResponse -import com.tencent.devops.process.service.transfer.PipelineTransferService +import com.tencent.devops.process.service.transfer.PipelineTransferYamlService import org.springframework.beans.factory.annotation.Autowired @RestResource class UserPipelineTransferResourceImpl @Autowired constructor( - private val transferService: PipelineTransferService + private val transferService: PipelineTransferYamlService ) : UserPipelineTransferResource { override fun transfer( userId: String, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt similarity index 99% rename from src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferService.kt rename to src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt index 919bc19a400..69d90fbbf42 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt @@ -70,7 +70,7 @@ import org.springframework.stereotype.Service @Suppress("ALL") @Service -class PipelineTransferService @Autowired constructor( +class PipelineTransferYamlService @Autowired constructor( private val dslContext: DSLContext, private val objectMapper: ObjectMapper, private val pipelineViewDao: PipelineViewDao, @@ -90,7 +90,7 @@ class PipelineTransferService @Autowired constructor( ) { companion object { - private val logger = LoggerFactory.getLogger(PipelineTransferService::class.java) + private val logger = LoggerFactory.getLogger(PipelineTransferYamlService::class.java) private const val TEMPLATE_ROOT_FILE = "TEMPLATE_ROOT_FILE" private val pipeline_key = listOf("stages", "jobs", "steps", "finally") private val trigger_key = listOf("on") From 5a74846a8c9b1bc005c5a77d6543fefb68498186 Mon Sep 17 00:00:00 2001 From: yongyiduan Date: Thu, 10 Aug 2023 11:05:57 +0800 Subject: [PATCH 052/852] =?UTF-8?q?=E3=80=90=E8=93=9D=E7=9B=BE-=E8=AF=84?= =?UTF-8?q?=E5=AE=A1=E4=BC=9A=E5=B7=B2=E8=AF=84=E5=AE=A1=E3=80=91=E3=80=90?= =?UTF-8?q?PAC=E3=80=91feat=EF=BC=9A=E6=96=B0=E5=BB=BA/=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=94=AF=E6=8C=81=E4=BB=A5=20Code?= =?UTF-8?q?=20=E6=96=B9=E5=BC=8F=E7=BC=96=E6=8E=92=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=20#8125?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/api/user/UserPipelineTransferResource.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt index 5546bedfc0a..376fdda7192 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt @@ -92,7 +92,7 @@ interface UserPipelineTransferResource { @ApiOperation("task转json格式") @POST - @Path("/{projectId}/task2yaml") + @Path("/{projectId}/task2model") fun yamlTaskTransfer( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) From 3d4ed13b851c4e8e16c5369e5e1777ebbe848760 Mon Sep 17 00:00:00 2001 From: yongyiduan Date: Thu, 10 Aug 2023 12:41:36 +0800 Subject: [PATCH 053/852] =?UTF-8?q?=E3=80=90=E8=93=9D=E7=9B=BE-=E8=AF=84?= =?UTF-8?q?=E5=AE=A1=E4=BC=9A=E5=B7=B2=E8=AF=84=E5=AE=A1=E3=80=91=E3=80=90?= =?UTF-8?q?PAC=E3=80=91feat=EF=BC=9A=E6=96=B0=E5=BB=BA/=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=94=AF=E6=8C=81=E4=BB=A5=20Code?= =?UTF-8?q?=20=E6=96=B9=E5=BC=8F=E7=BC=96=E6=8E=92=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=20#8125?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../modelTransfer/inner/TransferModelCreator.kt | 1 - .../inner/TransferModelCreatorImpl.kt | 7 +++---- .../devops/process/yaml/pojo/YamlVersion.kt | 7 ++++++- .../yaml/v2/models/PreTemplateScriptBuildYaml.kt | 15 ++++++++++++++- .../transfer/PipelineTransferYamlService.kt | 3 ++- 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreator.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreator.kt index f520b28c058..afe5f18d644 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreator.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreator.kt @@ -29,7 +29,6 @@ package com.tencent.devops.process.yaml.modelTransfer.inner import com.tencent.devops.common.pipeline.pojo.element.ElementAdditionalOptions import com.tencent.devops.common.pipeline.pojo.element.market.MarketBuildAtomElement -import com.tencent.devops.process.yaml.v2.models.job.Job import com.tencent.devops.process.yaml.v2.models.step.Step /** diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreatorImpl.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreatorImpl.kt index 12e4e0f5f7e..e3caf5247ff 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreatorImpl.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreatorImpl.kt @@ -41,13 +41,13 @@ import javax.ws.rs.core.Response @Component class TransferModelCreatorImpl @Autowired constructor( ) : TransferModelCreator { - @Value("\${stream.marketRun.enable:#{false}}") + @Value("\${marketRun.enable:#{false}}") private val marketRunTaskData: Boolean = false - @Value("\${stream.marketRun.atomCode:#{null}}") + @Value("\${marketRun.atomCode:#{null}}") private val runPlugInAtomCodeData: String? = null - @Value("\${stream.marketRun.atomVersion:#{null}}") + @Value("\${marketRun.atomVersion:#{null}}") private val runPlugInVersionData: String? = null @Value("\${container.defaultImage:#{null}}") @@ -91,7 +91,6 @@ class TransferModelCreatorImpl @Autowired constructor( inputMap["repositoryUrl"] = step.checkout!! - // 用户未指定时缺省为 AUTH_USER_TOKEN 同时指定 开启人 if (inputMap["authType"] == null) { inputMap["authType"] = STREAM_CHECK_AUTH_TYPE diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/YamlVersion.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/YamlVersion.kt index fe093956046..bfcd7a91f63 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/YamlVersion.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/YamlVersion.kt @@ -3,7 +3,12 @@ package com.tencent.devops.process.yaml.pojo interface YamlVersion { enum class Version { V2_0, - V3_0 + V3_0; + + companion object { + const val V2 = "v2.0" + const val V3 = "v3.0" + } } fun yamlVersion(): Version diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt index a2b3982069f..5a73c782957 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt @@ -31,6 +31,8 @@ import com.fasterxml.jackson.annotation.JsonIgnore import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonSubTypes +import com.fasterxml.jackson.annotation.JsonTypeInfo import com.tencent.devops.common.api.enums.ScmType import com.tencent.devops.process.yaml.pojo.YamlVersion import com.tencent.devops.process.yaml.v2.models.job.Job @@ -38,7 +40,18 @@ import com.tencent.devops.process.yaml.v2.models.on.PreTriggerOn import com.tencent.devops.process.yaml.v2.models.on.TriggerOn import com.tencent.devops.process.yaml.v2.models.stage.Stage import com.tencent.devops.process.yaml.v2.utils.ScriptYmlUtils - +import com.tencent.devops.process.yaml.v3.models.PreTemplateScriptBuildYamlV3 + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "version", + defaultImpl = PreTemplateScriptBuildYaml::class +) +@JsonSubTypes( + JsonSubTypes.Type(value = PreTemplateScriptBuildYamlV3::class, name = YamlVersion.Version.V3), + JsonSubTypes.Type(value = PreTemplateScriptBuildYaml::class, name = YamlVersion.Version.V2) +) interface IPreTemplateScriptBuildYaml : YamlVersion { val version: String? val name: String? diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt index 69d90fbbf42..521298e7dd9 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt @@ -57,6 +57,7 @@ import com.tencent.devops.process.yaml.modelTransfer.pojo.ModelTransferInput import com.tencent.devops.process.yaml.modelTransfer.pojo.YamlTransferInput import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.pojo.YamlVersion +import com.tencent.devops.process.yaml.v2.models.IPreTemplateScriptBuildYaml import com.tencent.devops.process.yaml.v2.models.PreTemplateScriptBuildYaml import com.tencent.devops.process.yaml.v2.models.step.PreStep import com.tencent.devops.process.yaml.v2.parsers.template.YamlTemplate @@ -127,7 +128,7 @@ class PipelineTransferYamlService @Autowired constructor( watcher.start("FULL_YAML2MODEL start") val pipelineInfo = pipelineRepositoryService.getPipelineInfo(projectId, pipelineId) val pYml = TransferMapper.getObjectMapper() - .readValue(data.oldYaml, object : TypeReference() {}) + .readValue(data.oldYaml, object : TypeReference() {}) watcher.start("parse template") pYml.replaceTemplate { templateFilter -> YamlTemplate( From 3ea6fe31aeb0534f89118e5fc6975af17a1aae98 Mon Sep 17 00:00:00 2001 From: yongyiduan Date: Thu, 10 Aug 2023 14:20:13 +0800 Subject: [PATCH 054/852] =?UTF-8?q?=E3=80=90=E8=93=9D=E7=9B=BE-=E8=AF=84?= =?UTF-8?q?=E5=AE=A1=E4=BC=9A=E5=B7=B2=E8=AF=84=E5=AE=A1=E3=80=91=E3=80=90?= =?UTF-8?q?PAC=E3=80=91feat=EF=BC=9A=E6=96=B0=E5=BB=BA/=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=94=AF=E6=8C=81=E4=BB=A5=20Code?= =?UTF-8?q?=20=E6=96=B9=E5=BC=8F=E7=BC=96=E6=8E=92=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=20#8125?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/yaml/modelTransfer/ModelTransfer.kt | 11 +++++++---- .../yaml/modelTransfer/pojo/YamlTransferInput.kt | 2 ++ .../devops/process/pojo/transfer/PreviewResponse.kt | 2 +- .../service/transfer/PipelineTransferYamlService.kt | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt index a4463a64794..d5eb5902003 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt @@ -38,6 +38,7 @@ import com.tencent.devops.process.pojo.classify.PipelineGroupCreate import com.tencent.devops.process.pojo.classify.PipelineLabelCreate import com.tencent.devops.process.pojo.setting.PipelineRunLockType import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_QUEUE_SIZE_DEFAULT import com.tencent.devops.process.yaml.modelTransfer.pojo.ModelTransferInput import com.tencent.devops.process.yaml.modelTransfer.pojo.YamlTransferInput import com.tencent.devops.process.yaml.pojo.YamlVersion @@ -73,6 +74,10 @@ class ModelTransfer @Autowired constructor( fun yaml2Setting(yamlInput: YamlTransferInput): PipelineSetting { val yaml = yamlInput.yaml return PipelineSetting( + projectId = yamlInput.pipelineInfo?.projectId ?: "", + pipelineId = yamlInput.pipelineInfo?.pipelineId ?: "", + pipelineName = yaml.name ?: yamlInput.pipelineInfo?.pipelineName ?: "", + desc = yamlInput.pipelineInfo?.pipelineDesc ?: "", concurrencyGroup = yaml.concurrency?.group, // Cancel-In-Progress 配置group后默认为true concurrencyCancelInProgress = yaml.concurrency?.cancelInProgress @@ -83,9 +88,7 @@ class ModelTransfer @Autowired constructor( else -> PipelineRunLockType.MULTIPLE }, waitQueueTimeMinute = yaml.concurrency?.queueTimeoutMinutes ?: TimeUnit.HOURS.toMinutes(8).toInt(), - // #6090 stream重试时均需要清理变量表 - cleanVariablesWhenRetry = true, - maxQueueSize = yaml.concurrency?.queueLength ?: 1, + maxQueueSize = yaml.concurrency?.queueLength ?: PIPELINE_SETTING_MAX_QUEUE_SIZE_DEFAULT, labels = yaml2Labels(yamlInput), pipelineAsCodeSettings = yamlInput.asCodeSettings ) @@ -131,7 +134,7 @@ class ModelTransfer @Autowired constructor( stages = stageList, labels = emptyList(), instanceFromTemplate = false, - pipelineCreator = yamlInput.userId + pipelineCreator = yamlInput.pipelineInfo?.creator ?: yamlInput.userId ) } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/YamlTransferInput.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/YamlTransferInput.kt index 9bb2a0fe3d1..a6d9f85e7dd 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/YamlTransferInput.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/YamlTransferInput.kt @@ -2,12 +2,14 @@ package com.tencent.devops.process.yaml.modelTransfer.pojo import com.tencent.devops.common.api.enums.ScmType import com.tencent.devops.common.api.pojo.PipelineAsCodeSettings +import com.tencent.devops.process.engine.pojo.PipelineInfo import com.tencent.devops.process.pojo.BuildTemplateAcrossInfo import com.tencent.devops.process.yaml.v2.models.IPreTemplateScriptBuildYaml data class YamlTransferInput( val userId: String, val projectCode: String, + val pipelineInfo: PipelineInfo?, val yaml: IPreTemplateScriptBuildYaml, val defaultScmType: ScmType = ScmType.CODE_GIT, val asCodeSettings: PipelineAsCodeSettings? = null, diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/PreviewResponse.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/PreviewResponse.kt index 1cb0f0668e8..94947764492 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/PreviewResponse.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/PreviewResponse.kt @@ -30,7 +30,7 @@ package com.tencent.devops.process.pojo.transfer import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty -@ApiModel("构建模型-ID") +@ApiModel("流水线 yaml 带定位信息") data class PreviewResponse( @ApiModelProperty("yaml内容") val yaml: String, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt index 521298e7dd9..5d462d29b4f 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt @@ -146,7 +146,7 @@ class PipelineTransferYamlService @Autowired constructor( } watcher.start("transfer start") val input = YamlTransferInput( - pipelineInfo?.creator ?: userId, projectId, pYml + userId, pipelineInfo, pYml ) val model = modelTransfer.yaml2Model(input) val setting = modelTransfer.yaml2Setting(input) From 3f963caae65e0a97eaccce6fd4deacc97b7be072 Mon Sep 17 00:00:00 2001 From: yongyiduan Date: Thu, 10 Aug 2023 14:40:46 +0800 Subject: [PATCH 055/852] =?UTF-8?q?=E3=80=90=E8=93=9D=E7=9B=BE-=E8=AF=84?= =?UTF-8?q?=E5=AE=A1=E4=BC=9A=E5=B7=B2=E8=AF=84=E5=AE=A1=E3=80=91=E3=80=90?= =?UTF-8?q?PAC=E3=80=91feat=EF=BC=9A=E6=96=B0=E5=BB=BA/=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=94=AF=E6=8C=81=E4=BB=A5=20Code?= =?UTF-8?q?=20=E6=96=B9=E5=BC=8F=E7=BC=96=E6=8E=92=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=20#8125?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/service/transfer/PipelineTransferYamlService.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt index 5d462d29b4f..471342a35f2 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt @@ -58,7 +58,6 @@ import com.tencent.devops.process.yaml.modelTransfer.pojo.YamlTransferInput import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.pojo.YamlVersion import com.tencent.devops.process.yaml.v2.models.IPreTemplateScriptBuildYaml -import com.tencent.devops.process.yaml.v2.models.PreTemplateScriptBuildYaml import com.tencent.devops.process.yaml.v2.models.step.PreStep import com.tencent.devops.process.yaml.v2.parsers.template.YamlTemplate import com.tencent.devops.process.yaml.v2.parsers.template.YamlTemplateConf @@ -146,7 +145,7 @@ class PipelineTransferYamlService @Autowired constructor( } watcher.start("transfer start") val input = YamlTransferInput( - userId, pipelineInfo, pYml + userId, projectId, pipelineInfo, pYml ) val model = modelTransfer.yaml2Model(input) val setting = modelTransfer.yaml2Setting(input) From e51a8f0fdbf4fde4ea3aada734598856c61fcd4f Mon Sep 17 00:00:00 2001 From: yongyiduan Date: Mon, 14 Aug 2023 11:03:33 +0800 Subject: [PATCH 056/852] =?UTF-8?q?=E3=80=90=E8=93=9D=E7=9B=BE-=E8=AF=84?= =?UTF-8?q?=E5=AE=A1=E4=BC=9A=E5=B7=B2=E8=AF=84=E5=AE=A1=E3=80=91=E3=80=90?= =?UTF-8?q?PAC=E3=80=91feat=EF=BC=9A=E6=96=B0=E5=BB=BA/=E7=BC=96=E8=BE=91?= =?UTF-8?q?=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=94=AF=E6=8C=81=E4=BB=A5=20Code?= =?UTF-8?q?=20=E6=96=B9=E5=BC=8F=E7=BC=96=E6=8E=92=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=20#8125?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yaml/modelTransfer/TransferMapper.kt | 8 +++- .../devops/common/pipeline/IModelTemplate.kt | 42 +++++++++++++++++++ .../tencent/devops/common/pipeline/Model.kt | 6 ++- .../common/pipeline/container/Container.kt | 4 +- .../pipeline/container/NormalContainer.kt | 4 +- .../devops/common/pipeline/container/Stage.kt | 7 +++- .../pipeline/container/TriggerContainer.kt | 4 +- .../pipeline/container/VMBuildContainer.kt | 4 +- .../common/pipeline/pojo/element/Element.kt | 7 +++- .../transfer/PipelineTransferYamlService.kt | 17 +++++--- 10 files changed, 86 insertions(+), 17 deletions(-) create mode 100644 src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/IModelTemplate.kt diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferMapper.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferMapper.kt index fe5ef96307a..2e0efd0ffce 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferMapper.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferMapper.kt @@ -19,6 +19,7 @@ import com.tencent.devops.process.pojo.transfer.TransferMark import com.tencent.devops.process.yaml.v2.models.YAME_META_DATA_JSON_FILTER import org.json.JSONArray import org.json.JSONObject +import org.slf4j.LoggerFactory import org.yaml.snakeyaml.DumperOptions import org.yaml.snakeyaml.LoaderOptions import org.yaml.snakeyaml.Yaml @@ -44,6 +45,7 @@ import java.util.function.Supplier import java.util.regex.Pattern object TransferMapper { + private val logger = LoggerFactory.getLogger(TransferMapper::class.java) /** * 重写StringQuotingChecker 以支持on关键字特性 @@ -258,7 +260,8 @@ object TransferMapper { /* startMark = */ n.startMark, /* endMark = */ n.endMark, /* style = */ DumperOptions.ScalarStyle.PLAIN - ), n + ), + n ) ) } @@ -476,7 +479,8 @@ object TransferMapper { // throw Exception("not same node") // } if (!exactlyTheSameNode(getYamlFactory().compose(new.reader()), getYamlFactory().compose(out.reader()))) { - throw Exception("not same node") + logger.warn("merge yaml fail|new=\n$new\n|||out=\n$out\n") + return new } return out } diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/IModelTemplate.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/IModelTemplate.kt new file mode 100644 index 00000000000..a63445e945f --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/IModelTemplate.kt @@ -0,0 +1,42 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.common.pipeline + +/** + * model中报错模板信息的扩展参数 + */ +interface IModelTemplate { + var template: String? + var ref: String? + + /** + * 判读是否来自于模板 + * @return true 是来自于模板|false 不是来自于模板 + */ + fun fromTemplate() = !template.isNullOrBlank() +} diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/Model.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/Model.kt index 7817d4d4e9f..4a6743eb141 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/Model.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/Model.kt @@ -64,8 +64,10 @@ data class Model( @ApiModelProperty("静态流水线组", required = false) var staticViews: List = emptyList(), @ApiModelProperty("各项耗时", required = true) - var timeCost: BuildRecordTimeCost? = null -) { + var timeCost: BuildRecordTimeCost? = null, + override var template: String? = null, + override var ref: String? = null +) : IModelTemplate { @ApiModelProperty("提交时流水线最新版本号", required = false) var latestVersion: Int = 0 diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/Container.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/Container.kt index d1bab16477e..abfca6881e1 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/Container.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/Container.kt @@ -30,6 +30,7 @@ package com.tencent.devops.common.pipeline.container import com.fasterxml.jackson.annotation.JsonSubTypes import com.fasterxml.jackson.annotation.JsonTypeInfo import com.tencent.devops.common.api.util.JsonUtil +import com.tencent.devops.common.pipeline.IModelTemplate import com.tencent.devops.common.pipeline.pojo.element.Element import com.tencent.devops.common.pipeline.pojo.time.BuildRecordTimeCost import io.swagger.annotations.ApiModel @@ -41,7 +42,7 @@ import io.swagger.annotations.ApiModel JsonSubTypes.Type(value = NormalContainer::class, name = NormalContainer.classType), JsonSubTypes.Type(value = VMBuildContainer::class, name = VMBuildContainer.classType) ) -interface Container { +interface Container : IModelTemplate { var id: String? // seq id var name: String var elements: List @@ -83,6 +84,7 @@ interface Container { it.transformCompatibility() } } + /** * 只存储Container相关的配置,elements不会存储。 */ diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/NormalContainer.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/NormalContainer.kt index 7355a0e5359..79f52529ad2 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/NormalContainer.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/NormalContainer.kt @@ -100,7 +100,9 @@ data class NormalContainer( @ApiModelProperty("当前矩阵子容器的上下文组合(分裂后的子容器特有字段)", required = false) var matrixContext: Map? = null, @ApiModelProperty("分裂后的容器集合(分裂后的父容器特有字段)", required = false) - var groupContainers: MutableList? = null + var groupContainers: MutableList? = null, + override var template: String? = null, + override var ref: String? = null ) : Container { companion object { const val classType = "normal" diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/Stage.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/Stage.kt index 355767feb3c..373837d6261 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/Stage.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/Stage.kt @@ -27,6 +27,7 @@ package com.tencent.devops.common.pipeline.container +import com.tencent.devops.common.pipeline.IModelTemplate import com.tencent.devops.common.pipeline.option.StageControlOption import com.tencent.devops.common.pipeline.pojo.StagePauseCheck import com.tencent.devops.common.pipeline.pojo.time.BuildRecordTimeCost @@ -68,8 +69,10 @@ data class Stage( @ApiModelProperty("步骤运行次数", required = false, accessMode = ApiModelProperty.AccessMode.READ_ONLY) var executeCount: Int? = null, @ApiModelProperty("各项耗时", required = true) - var timeCost: BuildRecordTimeCost? = null -) { + var timeCost: BuildRecordTimeCost? = null, + override var template: String? = null, + override var ref: String? = null +) : IModelTemplate { /** * 刷新stage的所有配置,如果是初始化则重置所有历史数据 */ diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/TriggerContainer.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/TriggerContainer.kt index 2babc801a03..91f81281d29 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/TriggerContainer.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/TriggerContainer.kt @@ -80,7 +80,9 @@ data class TriggerContainer( @ApiModelProperty("是否为构建矩阵", required = false, accessMode = ApiModelProperty.AccessMode.READ_ONLY) override var matrixGroupFlag: Boolean? = false, @ApiModelProperty("各项耗时", required = true) - override var timeCost: BuildRecordTimeCost? = null + override var timeCost: BuildRecordTimeCost? = null, + override var template: String? = null, + override var ref: String? = null ) : Container { companion object { const val classType = "trigger" diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/VMBuildContainer.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/VMBuildContainer.kt index b83862706ae..202180cd91c 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/VMBuildContainer.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/container/VMBuildContainer.kt @@ -120,7 +120,9 @@ data class VMBuildContainer( @ApiModelProperty("当前矩阵子容器的上下文组合(分裂后的子容器特有字段)", required = false) var matrixContext: Map? = null, @ApiModelProperty("分裂后的容器集合(分裂后的父容器特有字段)", required = false) - var groupContainers: MutableList? = null + var groupContainers: MutableList? = null, + override var template: String? = null, + override var ref: String? = null ) : Container { companion object { const val classType = "vmBuild" diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/Element.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/Element.kt index 0f38d87f1af..b5e0838c952 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/Element.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/element/Element.kt @@ -30,6 +30,7 @@ package com.tencent.devops.common.pipeline.pojo.element import com.fasterxml.jackson.annotation.JsonSubTypes import com.fasterxml.jackson.annotation.JsonTypeInfo import com.tencent.devops.common.api.util.JsonUtil +import com.tencent.devops.common.pipeline.IModelTemplate import com.tencent.devops.common.pipeline.enums.BuildStatus import com.tencent.devops.common.pipeline.enums.StartType import com.tencent.devops.common.pipeline.pojo.element.agent.CodeGitElement @@ -139,8 +140,10 @@ abstract class Element( @ApiModelProperty("所属插件分类代码(仅在运行构建时有用的中间参数,不要在编排保存阶段设置值)", required = false) open var classifyCode: String? = null, @ApiModelProperty("所属插件分类名称(仅在运行构建时有用的中间参数,不要在编排保存阶段设置值)", required = false) - open var classifyName: String? = null -) { + open var classifyName: String? = null, + override var template: String? = null, + override var ref: String? = null +) : IModelTemplate { open fun getAtomCode() = getClassType() diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt index 471342a35f2..23b250e1dfe 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt @@ -110,10 +110,11 @@ class PipelineTransferYamlService @Autowired constructor( data: TransferBody ): TransferResponse { - val watcher = Watcher(id = "yaml2Model") + val watcher = Watcher(id = "yaml and model transfer watcher") // todo 权限校验 when (actionType) { TransferActionType.FULL_MODEL2YAML -> { + watcher.start("step_1|FULL_MODEL2YAML start") val yml = modelTransfer.model2yaml( ModelTransferInput( data.modelAndSetting.model, @@ -121,14 +122,18 @@ class PipelineTransferYamlService @Autowired constructor( YamlVersion.Version.V3_0 ) ) - return TransferResponse(newYaml = TransferMapper.toYaml(yml)) + watcher.start("step_2|mergeYaml") + val newYaml = TransferMapper.mergeYaml(data.oldYaml, TransferMapper.toYaml(yml)) + watcher.stop() + logger.info(watcher.toString()) + return TransferResponse(newYaml = newYaml) } TransferActionType.FULL_YAML2MODEL -> { - watcher.start("FULL_YAML2MODEL start") + watcher.start("step_1|FULL_YAML2MODEL start") val pipelineInfo = pipelineRepositoryService.getPipelineInfo(projectId, pipelineId) val pYml = TransferMapper.getObjectMapper() .readValue(data.oldYaml, object : TypeReference() {}) - watcher.start("parse template") + watcher.start("step_2|parse template") pYml.replaceTemplate { templateFilter -> YamlTemplate( yamlObject = templateFilter, @@ -143,12 +148,14 @@ class PipelineTransferYamlService @Autowired constructor( ) ).replace() } - watcher.start("transfer start") + watcher.start("step_3|transfer start") val input = YamlTransferInput( userId, projectId, pipelineInfo, pYml ) val model = modelTransfer.yaml2Model(input) val setting = modelTransfer.yaml2Setting(input) + watcher.stop() + logger.info(watcher.toString()) return TransferResponse(modelAndSetting = PipelineModelAndSetting(model, setting)) } } From 0156f06d10c7a73b90c20da14312cd911afdf597 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 14 Aug 2023 11:10:18 +0800 Subject: [PATCH 057/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tencent/devops/common/pipeline/PipelineModelAndYaml.kt | 2 +- .../devops/process/api/user/UserPipelineVersionResource.kt | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt index d7a8b993f35..503c20ad47e 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt @@ -32,6 +32,6 @@ import io.swagger.annotations.ApiModelProperty data class PipelineModelAndYaml( @ApiModelProperty("流水线模型", required = true) val model: Model, - @ApiModelProperty("流水线YAML编排", required = false) + @ApiModelProperty("流水线YAML编排(不为空时以YAML为准)", required = false) val yaml: String? ) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 257b63faa4c..32ae1374471 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -58,6 +58,10 @@ import javax.ws.rs.core.MediaType @Suppress("LongParameterList") interface UserPipelineVersionResource { + // TODO 从模板新建直接传ID + + // TODO 版本历史接口增加获取YAML的方式(对比) + @ApiOperation("新建流水线编排") @POST @Path("/projects/{projectId}/createPipeline") From 00a94b532789b64642aca0e79d248d6bb909661e Mon Sep 17 00:00:00 2001 From: yongyiduan Date: Mon, 14 Aug 2023 11:23:09 +0800 Subject: [PATCH 058/852] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=BB=BA/?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=BB=A5=20Code=20=E6=96=B9=E5=BC=8F=E7=BC=96=E6=8E=92?= =?UTF-8?q?=E6=B5=81=E6=B0=B4=E7=BA=BF=20#8125?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/user/UserPipelineTransferResource.kt | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt index 376fdda7192..cc810562f02 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt @@ -57,7 +57,7 @@ interface UserPipelineTransferResource { @ApiOperation("互转入口") @POST - @Path("/{projectId}") + @Path("/{projectId}/{pipelineId}") fun transfer( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -66,7 +66,7 @@ interface UserPipelineTransferResource { @PathParam("projectId") projectId: String, @ApiParam("流水线id", required = true) - @QueryParam("pipelineId") + @PathParam("pipelineId") pipelineId: String, @ApiParam("操作类型", required = true) @QueryParam("actionType") @@ -76,7 +76,7 @@ interface UserPipelineTransferResource { @ApiOperation("task转yaml格式") @POST - @Path("/{projectId}/task2yaml") + @Path("/{projectId}/{pipelineId}/task2yaml") fun modelTaskTransfer( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -85,14 +85,14 @@ interface UserPipelineTransferResource { @PathParam("projectId") projectId: String, @ApiParam("流水线id", required = true) - @QueryParam("pipelineId") + @PathParam("pipelineId") pipelineId: String, data: Element ): Result @ApiOperation("task转json格式") @POST - @Path("/{projectId}/task2model") + @Path("/{projectId}/{pipelineId}/task2model") fun yamlTaskTransfer( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -101,14 +101,14 @@ interface UserPipelineTransferResource { @PathParam("projectId") projectId: String, @ApiParam("流水线id", required = true) - @QueryParam("pipelineId") + @PathParam("pipelineId") pipelineId: String, yaml: String ): Result @ApiOperation("触发前配置") @GET - @Path("/{projectId}/preview_code") + @Path("/{projectId}/{pipelineId}/preview_code") fun preview( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -117,7 +117,7 @@ interface UserPipelineTransferResource { @PathParam("projectId") projectId: String, @ApiParam("流水线id", required = true) - @QueryParam("pipelineId") + @PathParam("pipelineId") pipelineId: String ): Result } From 84fda236309d13978034541ffc87b867a704835a Mon Sep 17 00:00:00 2001 From: yongyiduan Date: Mon, 14 Aug 2023 20:27:05 +0800 Subject: [PATCH 059/852] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=BB=BA/?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=BB=A5=20Code=20=E6=96=B9=E5=BC=8F=E7=BC=96=E6=8E=92?= =?UTF-8?q?=E6=B5=81=E6=B0=B4=E7=BA=BF=20#8125?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yaml/modelTransfer/ModelTransfer.kt | 3 +-- .../transfer/PipelineTransferYamlService.kt | 26 ------------------- 2 files changed, 1 insertion(+), 28 deletions(-) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt index d5eb5902003..7f29b60690b 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt @@ -74,7 +74,7 @@ class ModelTransfer @Autowired constructor( fun yaml2Setting(yamlInput: YamlTransferInput): PipelineSetting { val yaml = yamlInput.yaml return PipelineSetting( - projectId = yamlInput.pipelineInfo?.projectId ?: "", + projectId = yamlInput.pipelineInfo?.projectId ?: "", pipelineId = yamlInput.pipelineInfo?.pipelineId ?: "", pipelineName = yaml.name ?: yamlInput.pipelineInfo?.pipelineName ?: "", desc = yamlInput.pipelineInfo?.pipelineDesc ?: "", @@ -97,7 +97,6 @@ class ModelTransfer @Autowired constructor( fun yaml2Model( yamlInput: YamlTransferInput ): Model { - val stageList = mutableListOf() // 蓝盾引擎会将stageId从1开始顺序强制重写,因此在生成model时保持一致 diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt index 23b250e1dfe..e15547803e1 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt @@ -28,28 +28,16 @@ package com.tencent.devops.process.service.transfer import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.databind.ObjectMapper import com.tencent.devops.common.api.exception.ErrorCodeException import com.tencent.devops.common.api.util.Watcher -import com.tencent.devops.common.client.Client import com.tencent.devops.common.pipeline.pojo.element.Element -import com.tencent.devops.process.dao.PipelineViewUserLastViewDao -import com.tencent.devops.process.dao.PipelineViewUserSettingsDao -import com.tencent.devops.process.dao.label.PipelineGroupDao -import com.tencent.devops.process.dao.label.PipelineLabelDao -import com.tencent.devops.process.dao.label.PipelineLabelPipelineDao -import com.tencent.devops.process.dao.label.PipelineViewDao -import com.tencent.devops.process.dao.label.PipelineViewTopDao -import com.tencent.devops.process.engine.dao.PipelineInfoDao import com.tencent.devops.process.engine.service.PipelineRepositoryService -import com.tencent.devops.process.permission.PipelineGroupPermissionService import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting import com.tencent.devops.process.pojo.transfer.PreviewResponse import com.tencent.devops.process.pojo.transfer.TransferActionType import com.tencent.devops.process.pojo.transfer.TransferBody import com.tencent.devops.process.pojo.transfer.TransferMark import com.tencent.devops.process.pojo.transfer.TransferResponse -import com.tencent.devops.process.service.label.PipelineGroupService import com.tencent.devops.process.yaml.modelTransfer.ElementTransfer import com.tencent.devops.process.yaml.modelTransfer.ModelTransfer import com.tencent.devops.process.yaml.modelTransfer.TransferMapper @@ -63,7 +51,6 @@ import com.tencent.devops.process.yaml.v2.parsers.template.YamlTemplate import com.tencent.devops.process.yaml.v2.parsers.template.YamlTemplateConf import com.tencent.devops.process.yaml.v2.parsers.template.models.GetTemplateParam import com.tencent.devops.process.yaml.v2.utils.ScriptYmlUtils -import org.jooq.DSLContext import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service @@ -71,19 +58,6 @@ import org.springframework.stereotype.Service @Suppress("ALL") @Service class PipelineTransferYamlService @Autowired constructor( - private val dslContext: DSLContext, - private val objectMapper: ObjectMapper, - private val pipelineViewDao: PipelineViewDao, - private val pipelineInfoDao: PipelineInfoDao, - private val pipelineLabelDao: PipelineLabelDao, - private val pipelineGroupDao: PipelineGroupDao, - private val pipelineLabelPipelineDao: PipelineLabelPipelineDao, - private val pipelineViewTopDao: PipelineViewTopDao, - private val pipelineViewUserSettingDao: PipelineViewUserSettingsDao, - private val pipelineViewLastViewDao: PipelineViewUserLastViewDao, - private val pipelineGroupService: PipelineGroupService, - private val client: Client, - private val pipelineGroupPermissionService: PipelineGroupPermissionService, private val modelTransfer: ModelTransfer, private val elementTransfer: ElementTransfer, private val pipelineRepositoryService: PipelineRepositoryService From 68e37d798314673382dc320ca280f23f857c6d87 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 14 Aug 2023 20:31:12 +0800 Subject: [PATCH 060/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0yaml=E5=86=85=E5=AE=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/user/UserPipelineTransferResource.kt | 21 ++----------- .../api/user/UserPipelineVersionResource.kt | 31 +++++++++++++++---- .../pojo/pipeline/PipelineResourceVersion.kt | 4 ++- .../process/engine/dao/PipelineResDao.kt | 1 + .../engine/dao/PipelineResVersionDao.kt | 13 +++++--- .../service/PipelineRepositoryService.kt | 11 ++++++- .../api/UserPipelineTransferResourceImpl.kt | 4 +-- .../api/UserPipelineVersionResourceImpl.kt | 17 +++++++++- .../transfer/PipelineTransferYamlService.kt | 29 +++++++++++------ 9 files changed, 88 insertions(+), 43 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt index cc810562f02..4a42c651545 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt @@ -57,7 +57,7 @@ interface UserPipelineTransferResource { @ApiOperation("互转入口") @POST - @Path("/{projectId}/{pipelineId}") + @Path("/projects/{projectId}/pipelines/{pipelineId}") fun transfer( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -76,7 +76,7 @@ interface UserPipelineTransferResource { @ApiOperation("task转yaml格式") @POST - @Path("/{projectId}/{pipelineId}/task2yaml") + @Path("/projects/{projectId}/pipelines/{pipelineId}/task2yaml") fun modelTaskTransfer( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -92,7 +92,7 @@ interface UserPipelineTransferResource { @ApiOperation("task转json格式") @POST - @Path("/{projectId}/{pipelineId}/task2model") + @Path("/projects/{projectId}/pipelines/{pipelineId}/task2model") fun yamlTaskTransfer( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -105,19 +105,4 @@ interface UserPipelineTransferResource { pipelineId: String, yaml: String ): Result - - @ApiOperation("触发前配置") - @GET - @Path("/{projectId}/{pipelineId}/preview_code") - fun preview( - @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) - @HeaderParam(AUTH_HEADER_USER_ID) - userId: String, - @ApiParam("项目ID", required = true) - @PathParam("projectId") - projectId: String, - @ApiParam("流水线id", required = true) - @PathParam("pipelineId") - pipelineId: String - ): Result } diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 32ae1374471..ab76bba1e5e 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -37,6 +37,7 @@ import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.process.pojo.transfer.PreviewResponse import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation import io.swagger.annotations.ApiParam @@ -62,9 +63,27 @@ interface UserPipelineVersionResource { // TODO 版本历史接口增加获取YAML的方式(对比) + @ApiOperation("触发前配置") + @GET + @Path("/projects/{projectId}/pipelines/{pipelineId}/preview_code") + fun preview( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线id", required = true) + @PathParam("pipelineId") + pipelineId: String, + @ApiParam("流水线版本号", required = false) + @QueryParam("version") + version: Int? + ): Result + @ApiOperation("新建流水线编排") @POST - @Path("/projects/{projectId}/createPipeline") + @Path("/projects/{projectId}/create_pipeline") fun createPipeline( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -81,7 +100,7 @@ interface UserPipelineVersionResource { @ApiOperation("保存流水线编排草稿") @POST - @Path("/projects/{projectId}/pipelines/{pipelineId}/saveDraft") + @Path("/projects/{projectId}/pipelines/{pipelineId}/save_draft") fun savePipeline( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -102,7 +121,7 @@ interface UserPipelineVersionResource { @ApiOperation("保存流水线设置") @POST - @Path("/projects/{projectId}/pipelines/{pipelineId}/saveSetting") + @Path("/projects/{projectId}/pipelines/{pipelineId}/save_setting") fun saveSetting( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -119,7 +138,7 @@ interface UserPipelineVersionResource { @ApiOperation("获取流水线编排创建人列表(分页)") @GET - @Path("/projects/{projectId}/pipelines/{pipelineId}/creatorList") + @Path("/projects/{projectId}/pipelines/{pipelineId}/creator_list") fun creatorList( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -167,7 +186,7 @@ interface UserPipelineVersionResource { @ApiOperation("获取流水线操作日志列表(分页)") @GET - @Path("/projects/{projectId}/pipelines/{pipelineId}/operationLog") + @Path("/projects/{projectId}/pipelines/{pipelineId}/operation_log") fun getPipelineOperationLogs( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -188,7 +207,7 @@ interface UserPipelineVersionResource { @ApiOperation("获取流水线操作人列表(分页)") @GET - @Path("/projects/{projectId}/pipelines/{pipelineId}/operatorList") + @Path("/projects/{projectId}/pipelines/{pipelineId}/operator_list") fun operatorList( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt index 02847850c21..4444fc38bd2 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt @@ -42,8 +42,10 @@ data class PipelineResourceVersion( val pipelineId: String, @ApiModelProperty("记录版本号", required = true) val version: Int, - @ApiModelProperty("编排内容", required = true) + @ApiModelProperty("JSON编排内容(POJO)", required = true) val model: Model, + @ApiModelProperty("YAML编排内容", required = false) + val yaml: String?, @ApiModelProperty("创建者", required = true) val creator: String, @ApiModelProperty("版本名称", required = true) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt index c00b0ce709e..14ec8cfcb14 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt @@ -116,6 +116,7 @@ class PipelineResDao { null } } ?: return null, + yaml = record.yaml, creator = record.creator, versionName = record.versionName, createTime = record.createTime, diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt index 9a94cefe39c..fbccb666c02 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt @@ -51,6 +51,7 @@ class PipelineResVersionDao { version: Int, versionName: String, model: Model, + yaml: String?, pipelineVersion: Int?, triggerVersion: Int?, settingVersion: Int?, @@ -64,7 +65,8 @@ class PipelineResVersionDao { creator = creator, version = version, versionName = versionName, - modelString = JsonUtil.toJson(model, formatted = false), + modelStr = JsonUtil.toJson(model, formatted = false), + yamlStr = yaml, pipelineVersion = pipelineVersion, triggerVersion = triggerVersion, settingVersion = settingVersion, @@ -80,7 +82,8 @@ class PipelineResVersionDao { creator: String, version: Int, versionName: String = "init", - modelString: String, + modelStr: String, + yamlStr: String?, pipelineVersion: Int?, triggerVersion: Int?, settingVersion: Int?, @@ -93,7 +96,8 @@ class PipelineResVersionDao { .set(PIPELINE_ID, pipelineId) .set(VERSION, version) .set(VERSION_NAME, versionName) - .set(MODEL, modelString) + .set(MODEL, modelStr) + .set(YAML, yamlStr) .set(CREATOR, creator) .set(CREATE_TIME, LocalDateTime.now()) .set(PIPELINE_VERSION, pipelineVersion) @@ -102,7 +106,7 @@ class PipelineResVersionDao { .set(STATUS, status?.name) .set(DESCRIPTION, description) .onDuplicateKeyUpdate() - .set(MODEL, modelString) + .set(MODEL, modelStr) .set(CREATOR, creator) .set(VERSION_NAME, versionName) .set(PIPELINE_VERSION, pipelineVersion) @@ -166,6 +170,7 @@ class PipelineResVersionDao { null } } ?: return null, + yaml = record.yaml, creator = record.creator, versionName = record.versionName, createTime = record.createTime, diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index c597e6e0243..b969f40afe4 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -176,6 +176,8 @@ class PipelineRepositoryService constructor( create = create, channelCode = channelCode ) + // TODO 增加互转处理 + val yamlStr = null val buildNo = (model.stages[0].containers[0] as TriggerContainer).buildNo val triggerContainer = model.stages[0].containers[0] as TriggerContainer @@ -199,6 +201,7 @@ class PipelineRepositoryService constructor( pipelineId = pipelineId, userId = userId, model = model, + yamlStr = yamlStr, canManualStartup = canManualStartup, canElementSkip = canElementSkip, buildNo = buildNo, @@ -228,6 +231,7 @@ class PipelineRepositoryService constructor( projectId = projectId, pipelineId = pipelineId, model = model, + yamlStr = yamlStr, userId = userId, channelCode = channelCode, canManualStartup = canManualStartup, @@ -526,6 +530,7 @@ class PipelineRepositoryService constructor( projectId: String, pipelineId: String, model: Model, + yamlStr: String?, userId: String, channelCode: ChannelCode, canManualStartup: Boolean, @@ -649,6 +654,7 @@ class PipelineRepositoryService constructor( creator = userId, version = 1, model = model, + yaml = yamlStr, versionName = versionName ?: "init", pipelineVersion = modelVersion, triggerVersion = triggerVersion, @@ -689,6 +695,7 @@ class PipelineRepositoryService constructor( pipelineId: String, userId: String, model: Model, + yamlStr: String?, canManualStartup: Boolean, canElementSkip: Boolean, buildNo: BuildNo?, @@ -788,6 +795,7 @@ class PipelineRepositoryService constructor( creator = userId, version = version, model = model, + yaml = yamlStr, versionName = versionName ?: "init", pipelineVersion = pipelineVersion, triggerVersion = triggerVersion, @@ -818,7 +826,8 @@ class PipelineRepositoryService constructor( pipelineId = pipelineId, creator = userId, version = version - 1, - modelString = lastVersionModelStr, + modelStr = lastVersionModelStr, + yamlStr = yamlStr, pipelineVersion = null, triggerVersion = null, settingVersion = null, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt index b93930da34c..30657a8b666 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt @@ -70,7 +70,5 @@ class UserPipelineTransferResourceImpl @Autowired constructor( return Result(transferService.yamlTaskTransfer(userId, projectId, pipelineId, yaml)) } - override fun preview(userId: String, projectId: String, pipelineId: String): Result { - return Result(transferService.preview(userId, projectId, pipelineId)) - } + } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index 07daf022182..edd6bd8abcf 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -48,21 +48,36 @@ import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.audit.Audit import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.process.pojo.transfer.PreviewResponse import com.tencent.devops.process.service.PipelineInfoFacadeService import com.tencent.devops.process.service.PipelineOperationLogService import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService +import com.tencent.devops.process.service.transfer.PipelineTransferYamlService import org.springframework.beans.factory.annotation.Autowired @RestResource +@Suppress("ALL") class UserPipelineVersionResourceImpl @Autowired constructor( private val pipelineSettingFacadeService: PipelineSettingFacadeService, private val pipelinePermissionService: PipelinePermissionService, private val pipelineInfoFacadeService: PipelineInfoFacadeService, private val auditService: AuditService, private val pipelineVersionFacadeService: PipelineVersionFacadeService, - private val pipelineOperationLogService: PipelineOperationLogService + private val pipelineOperationLogService: PipelineOperationLogService, + private val transferService: PipelineTransferYamlService ) : UserPipelineVersionResource { + override fun preview( + userId: String, + projectId: String, + pipelineId: String, + version: Int? + ): Result { + return Result( + transferService.buildPreview(userId, projectId, pipelineId, version) + ) + } + override fun createPipeline( userId: String, projectId: String, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt index 23b250e1dfe..b25a21ae7cc 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt @@ -43,6 +43,7 @@ import com.tencent.devops.process.dao.label.PipelineViewTopDao import com.tencent.devops.process.engine.dao.PipelineInfoDao import com.tencent.devops.process.engine.service.PipelineRepositoryService import com.tencent.devops.process.permission.PipelineGroupPermissionService +import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting import com.tencent.devops.process.pojo.transfer.PreviewResponse import com.tencent.devops.process.pojo.transfer.TransferActionType @@ -185,9 +186,14 @@ class PipelineTransferYamlService @Autowired constructor( return elementTransfer.yaml2element(ScriptYmlUtils.preStepToStep(tYml), null) } - fun preview(userId: String, projectId: String, pipelineId: String): PreviewResponse { - // todo 权限校验 - val yml = getPipelineYaml(userId, projectId, pipelineId) + fun buildPreview( + userId: String, + projectId: String, + pipelineId: String, + version: Int? + ): PreviewResponse { + // todo 权限校验,增加不存在yaml时自动将model转过来 + val yml = getPipelineResource(projectId, pipelineId, version)?.yaml ?: "" val pipelineIndex = mutableListOf() val triggerIndex = mutableListOf() val noticeIndex = mutableListOf() @@ -201,11 +207,16 @@ class PipelineTransferYamlService @Autowired constructor( return PreviewResponse(yml, pipelineIndex, triggerIndex, noticeIndex, settingIndex) } - private fun getPipelineYaml(userId: String, projectId: String, pipelineId: String): String { - // 临时方案 todo - val classLoader = Thread.currentThread().contextClassLoader - val resourceAsStream = classLoader.getResourceAsStream("temp.yml") - - return resourceAsStream?.bufferedReader().use { it?.readText() } ?: "" + private fun getPipelineResource( + projectId: String, + pipelineId: String, + version: Int? + ): PipelineResourceVersion? { + // 如果指定版本号则获取对应版本内容,如果未指定则获取最新内容 + return pipelineRepositoryService.getPipelineResourceVersion( + projectId = projectId, + pipelineId = pipelineId, + version = version, + ) } } From d0384bb235611f9f262f2e544214e420f7221b8d Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 14 Aug 2023 20:57:43 +0800 Subject: [PATCH 061/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0=E8=8E=B7=E5=8F=96=E5=90=AByaml?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/common/pipeline/IModelTemplate.kt | 1 + .../pojo/TemplateInstanceCreateRequest.kt | 37 +++++++++++++ .../api/user/UserPipelineVersionResource.kt | 53 +++++++++++++++---- 3 files changed, 81 insertions(+), 10 deletions(-) create mode 100644 src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/TemplateInstanceCreateRequest.kt diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/IModelTemplate.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/IModelTemplate.kt index a63445e945f..ad69d04673d 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/IModelTemplate.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/IModelTemplate.kt @@ -31,6 +31,7 @@ package com.tencent.devops.common.pipeline * model中报错模板信息的扩展参数 */ interface IModelTemplate { + var template: String? var ref: String? diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/TemplateInstanceCreateRequest.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/TemplateInstanceCreateRequest.kt new file mode 100644 index 00000000000..7c7a1004d65 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/TemplateInstanceCreateRequest.kt @@ -0,0 +1,37 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.common.pipeline.pojo + +import io.swagger.annotations.ApiModelProperty + +data class TemplateInstanceCreateRequest( + @ApiModelProperty("模板ID", required = true) + var template: String, + @ApiModelProperty("版本REF(不传默认最新)", required = false) + var ref: String? +) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index ab76bba1e5e..257de924e96 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -33,6 +33,7 @@ import com.tencent.devops.common.api.pojo.Page import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.PipelineModelAndYaml +import com.tencent.devops.common.pipeline.pojo.TemplateInstanceCreateRequest import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineOperationDetail @@ -59,27 +60,41 @@ import javax.ws.rs.core.MediaType @Suppress("LongParameterList") interface UserPipelineVersionResource { - // TODO 从模板新建直接传ID + @ApiOperation("通过指定模板创建流水线") + @POST + @Path("/projects/{projectId}/create_pipeline") + fun createPipelineFromPipeline( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("是否使用模板配置", required = false) + @QueryParam("useTemplateSettings") + useTemplateSettings: Boolean? = false, + @ApiParam(value = "流水线模型实例请求", required = true) + pipeline: TemplateInstanceCreateRequest + ): Result - // TODO 版本历史接口增加获取YAML的方式(对比) - @ApiOperation("触发前配置") + @ApiOperation("获取流水线指定版本的两种编排") @GET - @Path("/projects/{projectId}/pipelines/{pipelineId}/preview_code") - fun preview( + @Path("/projects/{projectId}/pipelines/{pipelineId}/versions/{version}") + fun getVersion( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) userId: String, @ApiParam("项目ID", required = true) @PathParam("projectId") projectId: String, - @ApiParam("流水线id", required = true) + @ApiParam("流水线ID", required = true) @PathParam("pipelineId") pipelineId: String, - @ApiParam("流水线版本号", required = false) - @QueryParam("version") - version: Int? - ): Result + @ApiParam("流水线编排版本", required = true) + @PathParam("version") + version: Int + ): Result @ApiOperation("新建流水线编排") @POST @@ -98,6 +113,24 @@ interface UserPipelineVersionResource { pipeline: PipelineModelAndYaml ): Result + @ApiOperation("触发前配置") + @GET + @Path("/projects/{projectId}/pipelines/{pipelineId}/preview_code") + fun preview( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线id", required = true) + @PathParam("pipelineId") + pipelineId: String, + @ApiParam("流水线版本号", required = false) + @QueryParam("version") + version: Int? + ): Result + @ApiOperation("保存流水线编排草稿") @POST @Path("/projects/{projectId}/pipelines/{pipelineId}/save_draft") From 318b26b57adbcc33f48e78289adfa4a880284448 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 14 Aug 2023 21:19:17 +0800 Subject: [PATCH 062/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0=E8=8E=B7=E5=8F=96=E5=90=AByaml?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/api/UserPipelineVersionResourceImpl.kt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index edd6bd8abcf..b007c8c45d4 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -37,6 +37,7 @@ import com.tencent.devops.common.auth.api.AuthResourceType import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.PipelineModelAndYaml import com.tencent.devops.common.pipeline.enums.ChannelCode +import com.tencent.devops.common.pipeline.pojo.TemplateInstanceCreateRequest import com.tencent.devops.common.web.RestResource import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.api.user.UserPipelineVersionResource @@ -78,6 +79,14 @@ class UserPipelineVersionResourceImpl @Autowired constructor( ) } + override fun createPipelineFromPipeline(userId: String, projectId: String, useTemplateSettings: Boolean?, pipeline: TemplateInstanceCreateRequest): Result { + TODO("Not yet implemented") + } + + override fun getVersion(userId: String, projectId: String, pipelineId: String, version: Int): Result { + TODO("Not yet implemented") + } + override fun createPipeline( userId: String, projectId: String, From 48ef302efa1a1c1be515eb8dba600e155a420a13 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 15 Aug 2023 10:48:39 +0800 Subject: [PATCH 063/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0=E8=8E=B7=E5=8F=96=E5=90=AByaml?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/api/user/UserPipelineVersionResource.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 257de924e96..416748018f4 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -62,7 +62,7 @@ interface UserPipelineVersionResource { @ApiOperation("通过指定模板创建流水线") @POST - @Path("/projects/{projectId}/create_pipeline") + @Path("/projects/{projectId}/create_pipeline_with_template") fun createPipelineFromPipeline( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) From 24dc75311fdc571b6f3b06356f83032c4c15d7bf Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 15 Aug 2023 14:48:38 +0800 Subject: [PATCH 064/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0=E8=8E=B7=E5=8F=96=E5=90=AByaml?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/user/UserPipelineTransferResource.kt | 2 +- .../api/user/UserPipelineVersionResource.kt | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt index 4a42c651545..5d1b7947673 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt @@ -55,7 +55,7 @@ import javax.ws.rs.core.MediaType @Suppress("ALL") interface UserPipelineTransferResource { - @ApiOperation("互转入口") + @ApiOperation("model与yaml互转入口") @POST @Path("/projects/{projectId}/pipelines/{pipelineId}") fun transfer( diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 416748018f4..60333fd12f9 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -62,7 +62,7 @@ interface UserPipelineVersionResource { @ApiOperation("通过指定模板创建流水线") @POST - @Path("/projects/{projectId}/create_pipeline_with_template") + @Path("/projects/{projectId}/createPipelineWithTemplate") fun createPipelineFromPipeline( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -98,7 +98,7 @@ interface UserPipelineVersionResource { @ApiOperation("新建流水线编排") @POST - @Path("/projects/{projectId}/create_pipeline") + @Path("/projects/{projectId}/createPipeline") fun createPipeline( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -115,7 +115,7 @@ interface UserPipelineVersionResource { @ApiOperation("触发前配置") @GET - @Path("/projects/{projectId}/pipelines/{pipelineId}/preview_code") + @Path("/projects/{projectId}/pipelines/{pipelineId}/previewCode") fun preview( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -133,7 +133,7 @@ interface UserPipelineVersionResource { @ApiOperation("保存流水线编排草稿") @POST - @Path("/projects/{projectId}/pipelines/{pipelineId}/save_draft") + @Path("/projects/{projectId}/pipelines/{pipelineId}/saveDraft") fun savePipeline( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -154,7 +154,7 @@ interface UserPipelineVersionResource { @ApiOperation("保存流水线设置") @POST - @Path("/projects/{projectId}/pipelines/{pipelineId}/save_setting") + @Path("/projects/{projectId}/pipelines/{pipelineId}/saveSetting") fun saveSetting( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -171,7 +171,7 @@ interface UserPipelineVersionResource { @ApiOperation("获取流水线编排创建人列表(分页)") @GET - @Path("/projects/{projectId}/pipelines/{pipelineId}/creator_list") + @Path("/projects/{projectId}/pipelines/{pipelineId}/creatorList") fun creatorList( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -219,7 +219,7 @@ interface UserPipelineVersionResource { @ApiOperation("获取流水线操作日志列表(分页)") @GET - @Path("/projects/{projectId}/pipelines/{pipelineId}/operation_log") + @Path("/projects/{projectId}/pipelines/{pipelineId}/operationLog") fun getPipelineOperationLogs( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -240,7 +240,7 @@ interface UserPipelineVersionResource { @ApiOperation("获取流水线操作人列表(分页)") @GET - @Path("/projects/{projectId}/pipelines/{pipelineId}/operator_list") + @Path("/projects/{projectId}/pipelines/{pipelineId}/operatorList") fun operatorList( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) From 4609a7ed166a0caca717397e90a0eb60368b4d8a Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 15 Aug 2023 17:53:50 +0800 Subject: [PATCH 065/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0=E8=8E=B7=E5=8F=96=E5=90=AByaml?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/yaml/modelCreate/ModelCreate.kt | 6 +- .../yaml/modelTransfer/ElementTransfer.kt | 2 +- .../yaml/modelTransfer/ModelTransfer.kt | 6 +- .../yaml/modelTransfer/StageTransfer.kt | 2 +- .../inner/TransferModelCreatorImpl.kt | 3 +- .../modelTransfer/pojo/ModelTransferInput.kt | 2 +- .../devops/process/yaml/v2/models/Variable.kt | 23 +--- .../yaml/v2/parsers/template/YamlTemplate.kt | 2 +- .../common/common-pipeline/build.gradle.kts | 1 + .../common/pipeline/PipelineModelAndYaml.kt | 3 +- .../pipeline/pojo}/PipelineModelAndSetting.kt | 3 +- .../pojo/TemplateInstanceCreateRequest.kt | 10 +- .../pojo/setting/PipelineRunLockType.kt | 2 +- .../pipeline}/pojo/setting/PipelineSetting.kt | 65 ++-------- .../pojo/setting}/PipelineSubscriptionType.kt | 2 +- .../pipeline}/pojo/setting/Subscription.kt | 4 +- .../pojo/setting/SubscriptionGroup.kt | 2 +- .../common/pipeline/utils/Constants.kt} | 39 +++--- .../api/apigw/v3/ApigwPipelineResourceV3.kt | 4 +- .../api/apigw/v4/ApigwPipelineResourceV4.kt | 4 +- .../apigw/v3/ApigwPipelineResourceV3Impl.kt | 4 +- .../apigw/v4/ApigwPipelineResourceV4Impl.kt | 4 +- .../api/op/OpPipelineSettingResource.kt | 2 +- .../api/service/ServicePipelineResource.kt | 4 +- .../service/ServicePipelineSettingResource.kt | 2 +- .../service/ServicePipelineVersionResource.kt | 2 +- .../api/template/UserPTemplateResource.kt | 2 +- .../process/api/user/UserPipelineResource.kt | 4 +- .../api/user/UserPipelineSettingResource.kt | 2 +- .../api/user/UserPipelineTransferResource.kt | 2 - .../api/user/UserPipelineVersionResource.kt | 34 ++--- .../process/constant/ProcessMessageCode.kt | 1 + .../process/pojo/app/StartBuildContext.kt | 4 +- .../setting/PipelineResourceAndSetting.kt | 1 + .../pojo/setting/PipelineSettingVersion.kt | 1 + .../pojo/setting/SubscriptionResponse.kt | 2 +- .../process/pojo/transfer/TransferBody.kt | 4 +- .../process/pojo/transfer/TransferResponse.kt | 2 +- .../devops/process/dao/PipelineSettingDao.kt | 8 +- .../process/dao/PipelineSettingVersionDao.kt | 6 +- .../engine/interceptor/InterceptData.kt | 2 +- .../engine/interceptor/QueueInterceptor.kt | 2 +- .../engine/interceptor/RunLockInterceptor.kt | 2 +- .../service/PipelineRepositoryService.kt | 48 ++++++- .../engine/service/PipelineSettingService.kt | 2 +- .../service/pipeline/PipelineStatusService.kt | 2 +- .../engine/control/BuildStartControl.kt | 4 +- .../api/ServicePipelineResourceImpl.kt | 6 +- .../api/ServicePipelineVersionResourceImpl.kt | 2 +- .../process/api/UserPipelineResourceImpl.kt | 5 +- .../api/UserPipelineSettingResourceImpl.kt | 2 +- .../api/UserPipelineTransferResourceImpl.kt | 3 - .../api/UserPipelineVersionResourceImpl.kt | 119 ++++++++++++------ .../api/op/OpPipelineSettingResourceImpl.kt | 2 +- .../ServicePipelineSettingResourceImpl.kt | 2 +- .../api/template/UserPTemplateResourceImpl.kt | 4 +- .../notify/command/BuildNotifyContext.kt | 2 +- .../service/PipelineInfoFacadeService.kt | 4 +- .../service/PipelineListFacadeService.kt | 2 +- .../service/PipelineSettingVersionService.kt | 6 +- .../pipeline/PipelineSettingFacadeService.kt | 8 +- .../service/template/TemplateFacadeService.kt | 2 +- .../transfer/PipelineTransferYamlService.kt | 4 +- .../stream/service/StreamPipelineService.kt | 2 +- .../stream/trigger/StreamYamlBaseBuild.kt | 2 +- .../stream/trigger/StreamYamlTrigger.kt | 1 - .../devops/stream/util/StreamPipelineUtils.kt | 4 +- 67 files changed, 274 insertions(+), 246 deletions(-) rename src/backend/ci/core/{process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting => common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo}/PipelineModelAndSetting.kt (93%) rename src/backend/ci/core/{process/api-process/src/main/kotlin/com/tencent/devops/process => common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline}/pojo/setting/PipelineRunLockType.kt (98%) rename src/backend/ci/core/{process/api-process/src/main/kotlin/com/tencent/devops/process => common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline}/pojo/setting/PipelineSetting.kt (60%) rename src/backend/ci/core/{process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline => common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting}/PipelineSubscriptionType.kt (96%) rename src/backend/ci/core/{process/api-process/src/main/kotlin/com/tencent/devops/process => common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline}/pojo/setting/Subscription.kt (95%) rename src/backend/ci/core/{process/api-process/src/main/kotlin/com/tencent/devops/process => common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline}/pojo/setting/SubscriptionGroup.kt (96%) rename src/backend/ci/core/{process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineSubscription.kt => common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/utils/Constants.kt} (69%) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelCreate.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelCreate.kt index bc6471362ad..c5a48c43dec 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelCreate.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelCreate.kt @@ -43,9 +43,9 @@ import com.tencent.devops.process.engine.common.VMUtils import com.tencent.devops.process.pojo.classify.PipelineGroup import com.tencent.devops.process.pojo.classify.PipelineGroupCreate import com.tencent.devops.process.pojo.classify.PipelineLabelCreate -import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting -import com.tencent.devops.process.pojo.setting.PipelineRunLockType -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.yaml.modelCreate.inner.ModelCreateEvent import com.tencent.devops.process.yaml.pojo.QualityElementInfo import com.tencent.devops.process.yaml.v2.models.ScriptBuildYaml diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt index 5cdff16ebbd..dbd31d4d144 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt @@ -129,7 +129,7 @@ class ElementTransfer @Autowired(required = false) constructor( fun yaml2element( step: Step, - agentSelector: String?, + agentSelector: String? ): Element { val timeout = setupTimeout(step) val additionalOptions = ElementAdditionalOptions( diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt index 7f29b60690b..7c8a4616304 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt @@ -36,8 +36,8 @@ import com.tencent.devops.process.api.user.UserPipelineGroupResource import com.tencent.devops.process.pojo.classify.PipelineGroup import com.tencent.devops.process.pojo.classify.PipelineGroupCreate import com.tencent.devops.process.pojo.classify.PipelineLabelCreate -import com.tencent.devops.process.pojo.setting.PipelineRunLockType -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_QUEUE_SIZE_DEFAULT import com.tencent.devops.process.yaml.modelTransfer.pojo.ModelTransferInput import com.tencent.devops.process.yaml.modelTransfer.pojo.YamlTransferInput @@ -149,7 +149,7 @@ class ModelTransfer @Autowired constructor( val variables = getVariableFromModel(modelInput.model) val finally = modelStage.model2YamlStage(modelInput.model.stages.last()).jobs val concurrency = getConcurrency(modelInput.setting) - val notices = ""// TODO: 2023/7/17 + val notices = "" // TODO: 2023/7/17 return when (modelInput.version) { YamlVersion.Version.V2_0 -> PreScriptBuildYaml( diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt index 8e9ef890257..e95dfed7f4a 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt @@ -101,7 +101,7 @@ class StageTransfer @Autowired(required = false) constructor( fun yaml2FinallyStage( stageIndex: Int, finallyJobs: List, - yamlInput: YamlTransferInput, + yamlInput: YamlTransferInput ): Stage { return yaml2Stage( stage = StreamV2Stage( diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreatorImpl.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreatorImpl.kt index e3caf5247ff..e9173bb4209 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreatorImpl.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreatorImpl.kt @@ -39,8 +39,7 @@ import javax.ws.rs.core.Response @Primary @Component -class TransferModelCreatorImpl @Autowired constructor( -) : TransferModelCreator { +class TransferModelCreatorImpl @Autowired constructor() : TransferModelCreator { @Value("\${marketRun.enable:#{false}}") private val marketRunTaskData: Boolean = false diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/ModelTransferInput.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/ModelTransferInput.kt index 840c12df566..ebd4c89e0a8 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/ModelTransferInput.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/ModelTransferInput.kt @@ -2,7 +2,7 @@ package com.tencent.devops.process.yaml.modelTransfer.pojo import com.tencent.devops.common.api.enums.ScmType import com.tencent.devops.common.pipeline.Model -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.yaml.pojo.YamlVersion data class ModelTransferInput( diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Variable.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Variable.kt index 6bb16677283..ae027e85917 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Variable.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Variable.kt @@ -30,24 +30,11 @@ package com.tencent.devops.process.yaml.v2.models import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.core.JsonGenerator -import com.fasterxml.jackson.core.JsonParser -import com.fasterxml.jackson.core.type.TypeReference -import com.fasterxml.jackson.databind.DeserializationContext -import com.fasterxml.jackson.databind.JsonNode -import com.fasterxml.jackson.databind.SerializerProvider -import com.fasterxml.jackson.databind.annotation.JsonDeserialize -import com.fasterxml.jackson.databind.deser.std.StdDeserializer -import com.fasterxml.jackson.databind.node.ArrayNode -import com.fasterxml.jackson.databind.node.ObjectNode -import com.fasterxml.jackson.databind.node.TextNode -import com.fasterxml.jackson.databind.ser.std.StdSerializer -import com.tencent.devops.common.api.util.JsonUtil -//@JsonDeserialize(using = IVariableDeserializer::class) +// @JsonDeserialize(using = IVariableDeserializer::class) interface IVariable // -//class IVariableDeserializer : StdDeserializer(IVariable::class.java) { +// class IVariableDeserializer : StdDeserializer(IVariable::class.java) { // override fun deserialize(p: JsonParser, ctxt: DeserializationContext): IVariable { // val node: JsonNode = p.codec.readTree(p) // return when (node) { @@ -63,9 +50,9 @@ interface IVariable // else -> throw Exception("") // } // } -//} +// } // -//class IVariableSerializer : StdSerializer(IVariable::class.java) { +// class IVariableSerializer : StdSerializer(IVariable::class.java) { // override fun serialize(value: IVariable, gen: JsonGenerator, provider: SerializerProvider) { // when (value) { // is ShortVariable -> gen.writeString(value.value) @@ -73,7 +60,7 @@ interface IVariable // is TemplateVariable -> gen.writeObject(value.toList()) // } // } -//} +// } /** * Variable model diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlTemplate.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlTemplate.kt index 120241ad291..fb4196e696d 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlTemplate.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlTemplate.kt @@ -633,7 +633,7 @@ class YamlTemplate( templateType = templateType, templateLib = templateLib, nowRepo = nowRepo, - toRepo = repo, + toRepo = repo ), templateType = templateType ) diff --git a/src/backend/ci/core/common/common-pipeline/build.gradle.kts b/src/backend/ci/core/common/common-pipeline/build.gradle.kts index 519a6f15264..9844e4706b0 100644 --- a/src/backend/ci/core/common/common-pipeline/build.gradle.kts +++ b/src/backend/ci/core/common/common-pipeline/build.gradle.kts @@ -28,6 +28,7 @@ dependencies { api(project(":core:common:common-api")) api(project(":core:common:common-event")) api(project(":core:common:common-expression")) + api(project(":core:common:common-web")) api("org.apache.ant:ant") api("org.apache.commons:commons-text") api("org.slf4j:slf4j-api") diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt index 503c20ad47e..cf0c3e5b1f7 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt @@ -27,11 +27,12 @@ package com.tencent.devops.common.pipeline +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting import io.swagger.annotations.ApiModelProperty data class PipelineModelAndYaml( @ApiModelProperty("流水线模型", required = true) - val model: Model, + val modelAndSetting: PipelineModelAndSetting, @ApiModelProperty("流水线YAML编排(不为空时以YAML为准)", required = false) val yaml: String? ) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineModelAndSetting.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/PipelineModelAndSetting.kt similarity index 93% rename from src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineModelAndSetting.kt rename to src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/PipelineModelAndSetting.kt index c83ce6677bf..91701ab8e8a 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineModelAndSetting.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/PipelineModelAndSetting.kt @@ -25,9 +25,10 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.tencent.devops.process.pojo.setting +package com.tencent.devops.common.pipeline.pojo import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import io.swagger.annotations.ApiModelProperty import javax.validation.Valid diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/TemplateInstanceCreateRequest.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/TemplateInstanceCreateRequest.kt index 7c7a1004d65..367d73b30c6 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/TemplateInstanceCreateRequest.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/TemplateInstanceCreateRequest.kt @@ -31,7 +31,13 @@ import io.swagger.annotations.ApiModelProperty data class TemplateInstanceCreateRequest( @ApiModelProperty("模板ID", required = true) - var template: String, + var templateId: String, @ApiModelProperty("版本REF(不传默认最新)", required = false) - var ref: String? + var ref: String?, + @ApiModelProperty("是否使用模板配置", required = false) + var useTemplateSettings: Boolean?, + @ApiModelProperty("是否使用标签配置", required = false) + var useLabelSettings: Boolean?, + @ApiModelProperty("是否使用并发配置", required = false) + var useConcurrencyGroup: Boolean?, ) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineRunLockType.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/PipelineRunLockType.kt similarity index 98% rename from src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineRunLockType.kt rename to src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/PipelineRunLockType.kt index 5fa9efb5fde..ccc2c14fafa 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineRunLockType.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/PipelineRunLockType.kt @@ -25,7 +25,7 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.tencent.devops.process.pojo.setting +package com.tencent.devops.common.pipeline.pojo.setting import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSetting.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/PipelineSetting.kt similarity index 60% rename from src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSetting.kt rename to src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/PipelineSetting.kt index c327a6ad1a6..30d9cd42ccf 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSetting.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/PipelineSetting.kt @@ -25,26 +25,16 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.tencent.devops.process.pojo.setting +package com.tencent.devops.common.pipeline.pojo.setting -import com.tencent.devops.common.api.exception.InvalidParamException import com.tencent.devops.common.api.pojo.PipelineAsCodeSettings +import com.tencent.devops.common.pipeline.utils.PIPELINE_RES_NUM_MIN +import com.tencent.devops.common.pipeline.utils.PIPELINE_SETTING_CONCURRENCY_GROUP_DEFAULT +import com.tencent.devops.common.pipeline.utils.PIPELINE_SETTING_MAX_CON_QUEUE_SIZE_MAX +import com.tencent.devops.common.pipeline.utils.PIPELINE_SETTING_MAX_QUEUE_SIZE_DEFAULT +import com.tencent.devops.common.pipeline.utils.PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_DEFAULT import com.tencent.devops.common.web.annotation.BkField import com.tencent.devops.common.web.constant.BkStyleEnum -import com.tencent.devops.common.web.utils.I18nUtil -import com.tencent.devops.process.constant.ProcessMessageCode.MAXIMUM_NUMBER_CONCURRENCY_ILLEGAL -import com.tencent.devops.process.constant.ProcessMessageCode.MAXIMUM_NUMBER_QUEUES_ILLEGAL -import com.tencent.devops.process.constant.ProcessMessageCode.MAXIMUM_QUEUE_LENGTH_ILLEGAL -import com.tencent.devops.process.constant.ProcessMessageCode.PIPELINE_ORCHESTRATIONS_NUMBER_ILLEGAL -import com.tencent.devops.process.utils.PIPELINE_RES_NUM_MIN -import com.tencent.devops.process.utils.PIPELINE_SETTING_CONCURRENCY_GROUP_DEFAULT -import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_CON_QUEUE_SIZE_MAX -import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_QUEUE_SIZE_DEFAULT -import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_QUEUE_SIZE_MAX -import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_QUEUE_SIZE_MIN -import com.tencent.devops.process.utils.PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_DEFAULT -import com.tencent.devops.process.utils.PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_MAX -import com.tencent.devops.process.utils.PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_MIN import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -93,45 +83,4 @@ data class PipelineSetting( val cleanVariablesWhenRetry: Boolean? = false, @ApiModelProperty("YAML流水线特殊配置", required = false) val pipelineAsCodeSettings: PipelineAsCodeSettings? = null -) { - - @Suppress("ALL") - fun checkParam() { - if (maxPipelineResNum < 1) { - throw InvalidParamException( - message = I18nUtil.getCodeLanMessage(PIPELINE_ORCHESTRATIONS_NUMBER_ILLEGAL), - params = arrayOf("maxPipelineResNum") - ) - } - if (runLockType == PipelineRunLockType.SINGLE || - runLockType == PipelineRunLockType.SINGLE_LOCK || runLockType == PipelineRunLockType.GROUP_LOCK - ) { - if (waitQueueTimeMinute < PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_MIN || - waitQueueTimeMinute > PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_MAX - ) { - throw InvalidParamException( - I18nUtil.getCodeLanMessage(MAXIMUM_QUEUE_LENGTH_ILLEGAL), - params = arrayOf("waitQueueTimeMinute") - ) - } - if (maxQueueSize < PIPELINE_SETTING_MAX_QUEUE_SIZE_MIN || - maxQueueSize > PIPELINE_SETTING_MAX_QUEUE_SIZE_MAX - ) { - throw InvalidParamException( - I18nUtil.getCodeLanMessage(MAXIMUM_NUMBER_QUEUES_ILLEGAL), - params = arrayOf("maxQueueSize") - ) - } - } - if (maxConRunningQueueSize != null && ( - maxConRunningQueueSize <= PIPELINE_SETTING_MAX_QUEUE_SIZE_MIN || - maxConRunningQueueSize > PIPELINE_SETTING_MAX_CON_QUEUE_SIZE_MAX - ) - ) { - throw InvalidParamException( - I18nUtil.getCodeLanMessage(MAXIMUM_NUMBER_CONCURRENCY_ILLEGAL), - params = arrayOf("maxConRunningQueueSize") - ) - } - } -} +) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineSubscriptionType.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/PipelineSubscriptionType.kt similarity index 96% rename from src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineSubscriptionType.kt rename to src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/PipelineSubscriptionType.kt index d26c1c68c12..4f3e08b4625 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineSubscriptionType.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/PipelineSubscriptionType.kt @@ -25,7 +25,7 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.tencent.devops.process.pojo.pipeline +package com.tencent.devops.common.pipeline.pojo.setting import io.swagger.annotations.ApiModel diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/Subscription.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/Subscription.kt similarity index 95% rename from src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/Subscription.kt rename to src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/Subscription.kt index bdf0a796e3d..f1658c9c44f 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/Subscription.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/Subscription.kt @@ -25,9 +25,8 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.tencent.devops.process.pojo.setting +package com.tencent.devops.common.pipeline.pojo.setting -import com.tencent.devops.process.pojo.pipeline.PipelineSubscriptionType import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -49,5 +48,4 @@ data class Subscription( val detailFlag: Boolean = false, @ApiModelProperty("自定义通知内容", required = false) val content: String = "" - ) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/SubscriptionGroup.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/SubscriptionGroup.kt similarity index 96% rename from src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/SubscriptionGroup.kt rename to src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/SubscriptionGroup.kt index a6402b519fa..e24002cf9c8 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/SubscriptionGroup.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/SubscriptionGroup.kt @@ -25,7 +25,7 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.tencent.devops.process.pojo.setting +package com.tencent.devops.common.pipeline.pojo.setting data class SubscriptionGroup( val id: String, diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineSubscription.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/utils/Constants.kt similarity index 69% rename from src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineSubscription.kt rename to src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/utils/Constants.kt index 4dcc7dd2dfe..f07249df6ac 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineSubscription.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/utils/Constants.kt @@ -25,20 +25,29 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.tencent.devops.process.pojo.pipeline +package com.tencent.devops.common.pipeline.utils -import com.tencent.devops.process.pojo.SubscriptionType -import io.swagger.annotations.ApiModel -import io.swagger.annotations.ApiModelProperty +/** + * 流水线设置-最大排队数量-默认值 + */ +const val PIPELINE_SETTING_MAX_QUEUE_SIZE_DEFAULT = 10 + +/** + * 流水线设置-最大并发数量-最大值 + */ +const val PIPELINE_SETTING_MAX_CON_QUEUE_SIZE_MAX = 200 + +/** + * 流水线设置-最大排队时间-默认值 单位:分钟 + */ +const val PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_DEFAULT = 1 + +/** + * 流水线设置-CONCURRENCY GROUP 并发组-默认值 + */ +const val PIPELINE_SETTING_CONCURRENCY_GROUP_DEFAULT = "\${{ci.pipeline_id}}" -@ApiModel("流水线-消息订阅") -data class PipelineSubscription( - @ApiModelProperty("流水线ID", required = true) - val pipelineId: String, - @ApiModelProperty("订阅用户RTX", required = true) - val username: String, - @ApiModelProperty("订阅消息的发送类型(email, rtx)", required = true) - val subscriptionTypes: List, - @ApiModelProperty("订阅类型", required = false) - val type: SubscriptionType? -) +/** + * 保存流水线编排的最大个数 + */ +const val PIPELINE_RES_NUM_MIN = 50 diff --git a/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v3/ApigwPipelineResourceV3.kt b/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v3/ApigwPipelineResourceV3.kt index 7c6fea4788e..fd083b33b2f 100644 --- a/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v3/ApigwPipelineResourceV3.kt +++ b/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v3/ApigwPipelineResourceV3.kt @@ -40,8 +40,8 @@ import com.tencent.devops.process.pojo.PipelineCopy import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineName import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult -import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation import io.swagger.annotations.ApiParam diff --git a/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/ApigwPipelineResourceV4.kt b/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/ApigwPipelineResourceV4.kt index 5521c556ea2..990584cf690 100644 --- a/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/ApigwPipelineResourceV4.kt +++ b/src/backend/ci/core/openapi/api-openapi/src/main/kotlin/com/tencent/devops/openapi/api/apigw/v4/ApigwPipelineResourceV4.kt @@ -41,8 +41,8 @@ import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineIdAndName import com.tencent.devops.process.pojo.PipelineName import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult -import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation import io.swagger.annotations.ApiParam diff --git a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v3/ApigwPipelineResourceV3Impl.kt b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v3/ApigwPipelineResourceV3Impl.kt index 4a535304283..949fbb5b622 100644 --- a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v3/ApigwPipelineResourceV3Impl.kt +++ b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v3/ApigwPipelineResourceV3Impl.kt @@ -39,8 +39,8 @@ import com.tencent.devops.process.pojo.PipelineCopy import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineName import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult -import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired diff --git a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/ApigwPipelineResourceV4Impl.kt b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/ApigwPipelineResourceV4Impl.kt index 0cbf0eb0f9a..9ec026aed83 100644 --- a/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/ApigwPipelineResourceV4Impl.kt +++ b/src/backend/ci/core/openapi/biz-openapi/src/main/kotlin/com/tencent/devops/openapi/resources/apigw/v4/ApigwPipelineResourceV4Impl.kt @@ -40,8 +40,8 @@ import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineIdAndName import com.tencent.devops.process.pojo.PipelineName import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult -import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/op/OpPipelineSettingResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/op/OpPipelineSettingResource.kt index 7af0b2b71cb..31f9788b94b 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/op/OpPipelineSettingResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/op/OpPipelineSettingResource.kt @@ -31,7 +31,7 @@ import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.api.pojo.PipelineAsCodeSettings -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_CON_QUEUE_SIZE_DEFAULT import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt index 08f353f9202..d83b39edb69 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt @@ -46,8 +46,8 @@ import com.tencent.devops.process.pojo.PipelineIdInfo import com.tencent.devops.process.pojo.PipelineName import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult import com.tencent.devops.process.pojo.pipeline.SimplePipeline -import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation import io.swagger.annotations.ApiParam diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineSettingResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineSettingResource.kt index a4c7adf6f2f..6aa6e2c6fe3 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineSettingResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineSettingResource.kt @@ -31,7 +31,7 @@ import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.enums.ChannelCode -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.pojo.setting.UpdatePipelineModelRequest import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt index bf8b618cb30..59bf3b34a74 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt @@ -35,7 +35,7 @@ import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.enums.ChannelCode import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.pojo.PipelineOperationDetail -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation import io.swagger.annotations.ApiParam diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPTemplateResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPTemplateResource.kt index 89a4cd24e03..77c61305e84 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPTemplateResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPTemplateResource.kt @@ -33,7 +33,7 @@ import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.web.annotation.BkField import com.tencent.devops.common.web.constant.BkStyleEnum -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.pojo.template.CopyTemplateReq import com.tencent.devops.process.pojo.template.OptionalTemplateList import com.tencent.devops.process.pojo.template.SaveAsTemplateReq diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt index 3e5b019d2b0..4b45c5edbab 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt @@ -50,9 +50,9 @@ import com.tencent.devops.process.pojo.classify.PipelineViewAndPipelines import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import com.tencent.devops.process.pojo.pipeline.BatchDeletePipeline import com.tencent.devops.process.pojo.pipeline.PipelineCount -import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting import com.tencent.devops.process.pojo.setting.PipelineResourceAndSetting -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation import io.swagger.annotations.ApiParam diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineSettingResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineSettingResource.kt index 29ec393010d..0386a2cc978 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineSettingResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineSettingResource.kt @@ -31,7 +31,7 @@ import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.process.pojo.setting.PipelineCommonSetting -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation import io.swagger.annotations.ApiParam diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt index 5d1b7947673..24d30e49350 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineTransferResource.kt @@ -31,7 +31,6 @@ import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.pojo.element.Element -import com.tencent.devops.process.pojo.transfer.PreviewResponse import com.tencent.devops.process.pojo.transfer.TransferActionType import com.tencent.devops.process.pojo.transfer.TransferBody import com.tencent.devops.process.pojo.transfer.TransferResponse @@ -39,7 +38,6 @@ import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation import io.swagger.annotations.ApiParam import javax.ws.rs.Consumes -import javax.ws.rs.GET import javax.ws.rs.HeaderParam import javax.ws.rs.POST import javax.ws.rs.Path diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 60333fd12f9..1e3844943c9 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -31,13 +31,12 @@ import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE import com.tencent.devops.common.api.pojo.Page import com.tencent.devops.common.api.pojo.Result -import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.PipelineModelAndYaml import com.tencent.devops.common.pipeline.pojo.TemplateInstanceCreateRequest import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineOperationDetail -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.pojo.transfer.PreviewResponse import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation @@ -63,21 +62,17 @@ interface UserPipelineVersionResource { @ApiOperation("通过指定模板创建流水线") @POST @Path("/projects/{projectId}/createPipelineWithTemplate") - fun createPipelineFromPipeline( + fun createPipelineFromTemplate( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) userId: String, @ApiParam("项目ID", required = true) @PathParam("projectId") projectId: String, - @ApiParam("是否使用模板配置", required = false) - @QueryParam("useTemplateSettings") - useTemplateSettings: Boolean? = false, @ApiParam(value = "流水线模型实例请求", required = true) pipeline: TemplateInstanceCreateRequest ): Result - @ApiOperation("获取流水线指定版本的两种编排") @GET @Path("/projects/{projectId}/pipelines/{pipelineId}/versions/{version}") @@ -96,23 +91,6 @@ interface UserPipelineVersionResource { version: Int ): Result - @ApiOperation("新建流水线编排") - @POST - @Path("/projects/{projectId}/createPipeline") - fun createPipeline( - @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) - @HeaderParam(AUTH_HEADER_USER_ID) - userId: String, - @ApiParam("项目ID", required = true) - @PathParam("projectId") - projectId: String, - @ApiParam("是否使用模板配置", required = false) - @QueryParam("useTemplateSettings") - useTemplateSettings: Boolean? = false, - @ApiParam(value = "流水线PAC模型", required = true) - pipeline: PipelineModelAndYaml - ): Result - @ApiOperation("触发前配置") @GET @Path("/projects/{projectId}/pipelines/{pipelineId}/previewCode") @@ -146,7 +124,7 @@ interface UserPipelineVersionResource { pipelineId: String, @ApiParam(value = "流水线模型与设置", required = true) @Valid - model: Model, + modelAndYaml: PipelineModelAndYaml, @ApiParam("变更说明", required = false) @QueryParam("description") description: String? = null @@ -252,4 +230,10 @@ interface UserPipelineVersionResource { @PathParam("pipelineId") pipelineId: String ): Result> + + // TODO 回滚接口:回归指定版本作为草稿,覆盖已有草稿 + + // TODO 模板查询:在新建预览页带简要信息:3个bool + + // } diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/constant/ProcessMessageCode.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/constant/ProcessMessageCode.kt index f4a404cb323..e627c915c6b 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/constant/ProcessMessageCode.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/constant/ProcessMessageCode.kt @@ -281,6 +281,7 @@ object ProcessMessageCode { const val GET_PIPELINE_ATOM_INFO_NO_PERMISSION = "2101180" // 无权访问插件{0}的流水线信息,请联系组件管理员 const val GROUP_IS_EXIST = "2101181" // 分组({0})已存在/group ({0}) is already exist const val GROUP_LABEL_IS_EXIST = "2101182" // 分组标签({0})已存在/group label ({0}) is already exist + const val ERROR_NO_PIPELINE_VERSION_EXISTS_BY_ID = "2101183" // 流水线[{0}]不存在 const val BK_SUCCESSFULLY_DISTRIBUTED = "bkSuccessfullyDistributed" // 跨项目构件分发成功,共分发了{0}个文件 const val BK_SUCCESSFULLY_FAILED = "bkSuccessfullyFailed" // 跨项目构件分发失败, diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/app/StartBuildContext.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/app/StartBuildContext.kt index 4479c8908cd..cf397d2857e 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/app/StartBuildContext.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/app/StartBuildContext.kt @@ -61,8 +61,8 @@ import com.tencent.devops.common.webhook.pojo.code.PIPELINE_WEBHOOK_EVENT_TYPE import com.tencent.devops.common.webhook.pojo.code.PIPELINE_WEBHOOK_REVISION import com.tencent.devops.common.webhook.pojo.code.PIPELINE_WEBHOOK_TYPE import com.tencent.devops.process.pojo.code.WebhookInfo -import com.tencent.devops.process.pojo.setting.PipelineRunLockType -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.utils.BUILD_NO import com.tencent.devops.process.utils.DependOnUtils import com.tencent.devops.process.utils.PIPELINE_BUILD_MSG diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineResourceAndSetting.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineResourceAndSetting.kt index 6767b0abdce..4517beb61b2 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineResourceAndSetting.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineResourceAndSetting.kt @@ -27,6 +27,7 @@ package com.tencent.devops.process.pojo.setting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.pojo.PipelineDetail import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion import io.swagger.annotations.ApiModelProperty diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSettingVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSettingVersion.kt index 223a5b03656..4582b2e92ea 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSettingVersion.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineSettingVersion.kt @@ -27,6 +27,7 @@ package com.tencent.devops.process.pojo.setting +import com.tencent.devops.common.pipeline.pojo.setting.Subscription import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/SubscriptionResponse.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/SubscriptionResponse.kt index eb78e97a7d3..86a21aba5d4 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/SubscriptionResponse.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/SubscriptionResponse.kt @@ -27,7 +27,7 @@ package com.tencent.devops.process.pojo.setting -import com.tencent.devops.process.pojo.pipeline.PipelineSubscriptionType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSubscriptionType import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferBody.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferBody.kt index ac18e66e710..f55c12e0594 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferBody.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferBody.kt @@ -27,7 +27,7 @@ package com.tencent.devops.process.pojo.transfer -import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -36,5 +36,5 @@ data class TransferBody( @ApiModelProperty("modelAndSetting") val modelAndSetting: PipelineModelAndSetting, @ApiModelProperty("当前yaml内容") - val oldYaml: String + val oldYaml: String = "" ) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferResponse.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferResponse.kt index 3c7b9da2711..7964b7ad7f8 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferResponse.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferResponse.kt @@ -27,7 +27,7 @@ package com.tencent.devops.process.pojo.transfer -import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt index 5bfa9801592..b4f19725327 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingDao.kt @@ -34,10 +34,10 @@ import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.notify.enums.NotifyType import com.tencent.devops.model.process.tables.TPipelineSetting import com.tencent.devops.model.process.tables.records.TPipelineSettingRecord -import com.tencent.devops.process.pojo.pipeline.PipelineSubscriptionType -import com.tencent.devops.process.pojo.setting.PipelineRunLockType -import com.tencent.devops.process.pojo.setting.PipelineSetting -import com.tencent.devops.process.pojo.setting.Subscription +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSubscriptionType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.Subscription import com.tencent.devops.process.util.NotifyTemplateUtils import com.tencent.devops.process.utils.PIPELINE_RES_NUM_MIN import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_QUEUE_SIZE_DEFAULT diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingVersionDao.kt index a7cc0c66e39..5e2d27dcaed 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineSettingVersionDao.kt @@ -32,10 +32,10 @@ import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.notify.enums.NotifyType import com.tencent.devops.model.process.tables.TPipelineSettingVersion import com.tencent.devops.model.process.tables.records.TPipelineSettingVersionRecord -import com.tencent.devops.process.pojo.pipeline.PipelineSubscriptionType -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSubscriptionType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.pojo.setting.PipelineSettingVersion -import com.tencent.devops.process.pojo.setting.Subscription +import com.tencent.devops.common.pipeline.pojo.setting.Subscription import com.tencent.devops.process.util.NotifyTemplateUtils import com.tencent.devops.process.utils.PIPELINE_START_USER_NAME import org.jooq.DSLContext diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/interceptor/InterceptData.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/interceptor/InterceptData.kt index e631d321089..778a0ad748f 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/interceptor/InterceptData.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/interceptor/InterceptData.kt @@ -30,7 +30,7 @@ package com.tencent.devops.process.engine.interceptor import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.enums.StartType import com.tencent.devops.process.engine.pojo.PipelineInfo -import com.tencent.devops.process.pojo.setting.PipelineRunLockType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType import io.swagger.annotations.ApiModelProperty /** diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/interceptor/QueueInterceptor.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/interceptor/QueueInterceptor.kt index a0bd90f0e0b..a907cec721c 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/interceptor/QueueInterceptor.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/interceptor/QueueInterceptor.kt @@ -46,7 +46,7 @@ import com.tencent.devops.process.engine.service.PipelineRedisService import com.tencent.devops.process.engine.service.PipelineRuntimeExtService import com.tencent.devops.process.engine.service.PipelineRuntimeService import com.tencent.devops.process.engine.service.PipelineTaskService -import com.tencent.devops.process.pojo.setting.PipelineRunLockType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType import com.tencent.devops.process.util.TaskUtils import java.util.concurrent.TimeUnit import org.slf4j.LoggerFactory diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/interceptor/RunLockInterceptor.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/interceptor/RunLockInterceptor.kt index e4609eceda9..89dd98aad68 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/interceptor/RunLockInterceptor.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/interceptor/RunLockInterceptor.kt @@ -32,7 +32,7 @@ import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.constant.ProcessMessageCode.ERROR_PIPELINE_LOCK import com.tencent.devops.process.engine.pojo.Response import com.tencent.devops.process.engine.service.PipelineRuntimeService -import com.tencent.devops.process.pojo.setting.PipelineRunLockType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index b969f40afe4..bd64aa6090c 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -86,9 +86,15 @@ import com.tencent.devops.process.pojo.pipeline.DeletePipelineResult import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion import com.tencent.devops.process.pojo.setting.PipelineModelVersion -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.service.PipelineOperationLogService import com.tencent.devops.process.utils.PIPELINE_MATRIX_CON_RUNNING_SIZE_MAX +import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_CON_QUEUE_SIZE_MAX +import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_QUEUE_SIZE_MAX +import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_QUEUE_SIZE_MIN +import com.tencent.devops.process.utils.PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_MAX +import com.tencent.devops.process.utils.PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_MIN import com.tencent.devops.project.api.service.ServiceAllocIdResource import com.tencent.devops.project.api.service.ServiceProjectResource import org.joda.time.LocalDateTime @@ -148,6 +154,46 @@ class PipelineRepositoryService constructor( "init" } else "P$pipelineVersion.T$triggerVersion.$settingVersion" } + + @Suppress("ALL") + fun PipelineSetting.checkParam() { + if (maxPipelineResNum < 1) { + throw InvalidParamException( + message = I18nUtil.getCodeLanMessage(ProcessMessageCode.PIPELINE_ORCHESTRATIONS_NUMBER_ILLEGAL), + params = arrayOf("maxPipelineResNum") + ) + } + if (runLockType == PipelineRunLockType.SINGLE || + runLockType == PipelineRunLockType.SINGLE_LOCK || runLockType == PipelineRunLockType.GROUP_LOCK + ) { + if (waitQueueTimeMinute < PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_MIN || + waitQueueTimeMinute > PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_MAX + ) { + throw InvalidParamException( + I18nUtil.getCodeLanMessage(ProcessMessageCode.MAXIMUM_QUEUE_LENGTH_ILLEGAL), + params = arrayOf("waitQueueTimeMinute") + ) + } + if (maxQueueSize < PIPELINE_SETTING_MAX_QUEUE_SIZE_MIN || + maxQueueSize > PIPELINE_SETTING_MAX_QUEUE_SIZE_MAX + ) { + throw InvalidParamException( + I18nUtil.getCodeLanMessage(ProcessMessageCode.MAXIMUM_NUMBER_QUEUES_ILLEGAL), + params = arrayOf("maxQueueSize") + ) + } + } + if (maxConRunningQueueSize != null && ( + this.maxConRunningQueueSize!! <= PIPELINE_SETTING_MAX_QUEUE_SIZE_MIN || + this.maxConRunningQueueSize!! > PIPELINE_SETTING_MAX_CON_QUEUE_SIZE_MAX + ) + ) { + throw InvalidParamException( + I18nUtil.getCodeLanMessage(ProcessMessageCode.MAXIMUM_NUMBER_CONCURRENCY_ILLEGAL), + params = arrayOf("maxConRunningQueueSize") + ) + } + } } fun deployPipeline( diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineSettingService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineSettingService.kt index 0d3e99f42ac..d118fdd275c 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineSettingService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineSettingService.kt @@ -31,7 +31,7 @@ import com.tencent.devops.common.api.util.DateTimeUtil import com.tencent.devops.common.redis.RedisOperation import com.tencent.devops.process.dao.PipelineSettingDao import com.tencent.devops.process.engine.dao.PipelineBuildDao -import com.tencent.devops.process.pojo.setting.PipelineRunLockType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType import org.jooq.DSLContext import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineStatusService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineStatusService.kt index c89720a432b..f9a1f657b3f 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineStatusService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineStatusService.kt @@ -37,7 +37,7 @@ import com.tencent.devops.process.engine.dao.PipelineBuildTaskDao import com.tencent.devops.process.engine.dao.PipelineInfoDao import com.tencent.devops.process.engine.service.PipelineRuntimeService import com.tencent.devops.process.pojo.PipelineStatus -import com.tencent.devops.process.pojo.setting.PipelineRunLockType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType import org.jooq.DSLContext import org.springframework.stereotype.Service diff --git a/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/BuildStartControl.kt b/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/BuildStartControl.kt index 297488e244f..bba8429599e 100644 --- a/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/BuildStartControl.kt +++ b/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/BuildStartControl.kt @@ -83,8 +83,8 @@ import com.tencent.devops.process.engine.service.record.PipelineBuildRecordServi import com.tencent.devops.process.engine.service.record.StageBuildRecordService import com.tencent.devops.process.engine.service.record.TaskBuildRecordService import com.tencent.devops.process.engine.utils.ContainerUtils -import com.tencent.devops.process.pojo.setting.PipelineRunLockType -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.service.BuildVariableService import com.tencent.devops.process.service.scm.ScmProxyService import com.tencent.devops.process.utils.BUILD_NO diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt index c27c1559486..2f37fa79be9 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt @@ -39,12 +39,14 @@ import com.tencent.devops.common.event.pojo.measure.PipelineLabelRelateInfo import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.ModelUpdate import com.tencent.devops.common.pipeline.enums.ChannelCode +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting import com.tencent.devops.common.web.RestResource import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.api.service.ServicePipelineResource import com.tencent.devops.process.audit.service.AuditService import com.tencent.devops.process.engine.pojo.PipelineInfo import com.tencent.devops.process.engine.service.PipelineRepositoryService +import com.tencent.devops.process.engine.service.PipelineRepositoryService.Companion.checkParam import com.tencent.devops.process.engine.service.rule.PipelineRuleService import com.tencent.devops.process.permission.PipelinePermissionService import com.tencent.devops.process.pojo.Permission @@ -59,8 +61,7 @@ import com.tencent.devops.process.pojo.audit.Audit import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult import com.tencent.devops.process.pojo.pipeline.SimplePipeline import com.tencent.devops.process.pojo.pipeline.enums.PipelineRuleBusCodeEnum -import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.service.PipelineInfoFacadeService import com.tencent.devops.process.service.PipelineListFacadeService import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService @@ -77,6 +78,7 @@ class ServicePipelineResourceImpl @Autowired constructor( private val pipelineSettingFacadeService: PipelineSettingFacadeService, private val pipelinePermissionService: PipelinePermissionService ) : ServicePipelineResource { + override fun status( userId: String, projectId: String, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt index 389ba4db8b0..e1ebf152c56 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt @@ -45,7 +45,7 @@ import com.tencent.devops.process.engine.service.PipelineVersionFacadeService import com.tencent.devops.process.permission.PipelinePermissionService import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.audit.Audit -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.service.PipelineInfoFacadeService import com.tencent.devops.process.service.PipelineOperationLogService import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index f01061c32af..86b04a8b4cf 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -71,9 +71,10 @@ import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import com.tencent.devops.process.pojo.pipeline.BatchDeletePipeline import com.tencent.devops.process.pojo.pipeline.PipelineCount import com.tencent.devops.process.pojo.pipeline.enums.PipelineRuleBusCodeEnum -import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting import com.tencent.devops.process.pojo.setting.PipelineResourceAndSetting -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting +import com.tencent.devops.process.engine.service.PipelineRepositoryService.Companion.checkParam import com.tencent.devops.process.service.PipelineInfoFacadeService import com.tencent.devops.process.service.PipelineListFacadeService import com.tencent.devops.process.service.PipelineRecentUseService diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineSettingResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineSettingResourceImpl.kt index 79ea08794b2..7e6a3fd8b0e 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineSettingResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineSettingResourceImpl.kt @@ -31,7 +31,7 @@ import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.web.RestResource import com.tencent.devops.process.api.user.UserPipelineSettingResource import com.tencent.devops.process.pojo.setting.PipelineCommonSetting -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.service.PipelineInfoFacadeService import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService import org.springframework.beans.factory.annotation.Autowired diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt index 30657a8b666..154abdc1ff1 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt @@ -31,7 +31,6 @@ import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.pojo.element.Element import com.tencent.devops.common.web.RestResource import com.tencent.devops.process.api.user.UserPipelineTransferResource -import com.tencent.devops.process.pojo.transfer.PreviewResponse import com.tencent.devops.process.pojo.transfer.TransferActionType import com.tencent.devops.process.pojo.transfer.TransferBody import com.tencent.devops.process.pojo.transfer.TransferResponse @@ -69,6 +68,4 @@ class UserPipelineTransferResourceImpl @Autowired constructor( ): Result { return Result(transferService.yamlTaskTransfer(userId, projectId, pipelineId, yaml)) } - - } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index b007c8c45d4..521950f0ebc 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -28,15 +28,16 @@ package com.tencent.devops.process.api import com.tencent.devops.common.api.constant.CommonMessageCode +import com.tencent.devops.common.api.exception.ErrorCodeException import com.tencent.devops.common.api.exception.ParamBlankException import com.tencent.devops.common.api.pojo.Page import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.auth.api.AuthResourceType -import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.PipelineModelAndYaml import com.tencent.devops.common.pipeline.enums.ChannelCode +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting import com.tencent.devops.common.pipeline.pojo.TemplateInstanceCreateRequest import com.tencent.devops.common.web.RestResource import com.tencent.devops.common.web.utils.I18nUtil @@ -48,8 +49,12 @@ import com.tencent.devops.process.permission.PipelinePermissionService import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.audit.Audit -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting +import com.tencent.devops.process.constant.ProcessMessageCode +import com.tencent.devops.process.engine.service.PipelineRepositoryService import com.tencent.devops.process.pojo.transfer.PreviewResponse +import com.tencent.devops.process.pojo.transfer.TransferActionType +import com.tencent.devops.process.pojo.transfer.TransferBody import com.tencent.devops.process.service.PipelineInfoFacadeService import com.tencent.devops.process.service.PipelineOperationLogService import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService @@ -65,7 +70,8 @@ class UserPipelineVersionResourceImpl @Autowired constructor( private val auditService: AuditService, private val pipelineVersionFacadeService: PipelineVersionFacadeService, private val pipelineOperationLogService: PipelineOperationLogService, - private val transferService: PipelineTransferYamlService + private val transferService: PipelineTransferYamlService, + private val pipelineRepositoryService: PipelineRepositoryService ) : UserPipelineVersionResource { override fun preview( @@ -74,55 +80,98 @@ class UserPipelineVersionResourceImpl @Autowired constructor( pipelineId: String, version: Int? ): Result { + val permission = AuthPermission.VIEW + pipelinePermissionService.validPipelinePermission( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + permission = permission, + message = MessageUtil.getMessageByLocale( + CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, + I18nUtil.getLanguage(userId), + arrayOf( + userId, + projectId, + permission.getI18n(I18nUtil.getLanguage(userId)), + pipelineId + ) + ) + ) return Result( transferService.buildPreview(userId, projectId, pipelineId, version) ) } - override fun createPipelineFromPipeline(userId: String, projectId: String, useTemplateSettings: Boolean?, pipeline: TemplateInstanceCreateRequest): Result { - TODO("Not yet implemented") - } - - override fun getVersion(userId: String, projectId: String, pipelineId: String, version: Int): Result { - TODO("Not yet implemented") + override fun createPipelineFromTemplate( + userId: String, + projectId: String, + pipeline: TemplateInstanceCreateRequest + ): Result { + TODO() } - override fun createPipeline( + override fun getVersion( userId: String, projectId: String, - useTemplateSettings: Boolean?, - pipeline: PipelineModelAndYaml - ): Result { - checkParam(userId, projectId) - // TODO #8161 如果传了YAML则以YAML为准 - val pipelineId = PipelineId( - id = pipelineInfoFacadeService.createPipeline( - userId = userId, - projectId = projectId, - model = pipeline.model, - channelCode = ChannelCode.BS, - useTemplateSettings = useTemplateSettings + pipelineId: String, + version: Int + ): Result { + val permission = AuthPermission.VIEW + pipelinePermissionService.validPipelinePermission( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + permission = permission, + message = MessageUtil.getMessageByLocale( + CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, + I18nUtil.getLanguage(userId), + arrayOf( + userId, + projectId, + permission.getI18n(I18nUtil.getLanguage(userId)), + pipelineId + ) ) ) - auditService.createAudit( - Audit( - resourceType = AuthResourceType.PIPELINE_DEFAULT.value, - resourceId = pipelineId.id, - resourceName = pipeline.model.name, - userId = userId, - action = "create", - actionContent = "Create", - projectId = projectId + val resource = pipelineRepositoryService.getPipelineResourceVersion( + projectId = projectId, + pipelineId = pipelineId, + version = version, + includeDraft = true + ) ?: throw ErrorCodeException( + errorCode = ProcessMessageCode.ERROR_NO_PIPELINE_VERSION_EXISTS_BY_ID, + params = arrayOf(version.toString()) + ) + val setting = pipelineSettingFacadeService.userGetSetting( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + version = resource.settingVersion ?: version + ) + val modelAndSetting = PipelineModelAndSetting( + setting = setting, + model = resource.model + ) + val yaml = resource.yaml ?: transferService.transfer( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + actionType = TransferActionType.FULL_MODEL2YAML, + data = TransferBody(modelAndSetting) + ).newYaml + return Result( + PipelineModelAndYaml( + modelAndSetting = modelAndSetting, + yaml = yaml ) ) - return Result(pipelineId) } override fun savePipeline( userId: String, projectId: String, pipelineId: String, - model: Model, + modelAndYaml: PipelineModelAndYaml, description: String? ): Result { checkParam(userId, projectId) @@ -130,7 +179,7 @@ class UserPipelineVersionResourceImpl @Autowired constructor( userId = userId, projectId = projectId, pipelineId = pipelineId, - model = model, + model = modelAndYaml.modelAndSetting.model, channelCode = ChannelCode.BS, checkPermission = true, checkTemplate = true, @@ -141,7 +190,7 @@ class UserPipelineVersionResourceImpl @Autowired constructor( Audit( resourceType = AuthResourceType.PIPELINE_DEFAULT.value, resourceId = pipelineId, - resourceName = model.name, + resourceName = modelAndYaml.modelAndSetting.model.name, userId = userId, action = "edit", actionContent = "Save Ver.${pipelineResult.version}", diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/op/OpPipelineSettingResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/op/OpPipelineSettingResourceImpl.kt index 6fb0f83108f..e623025d393 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/op/OpPipelineSettingResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/op/OpPipelineSettingResourceImpl.kt @@ -38,7 +38,7 @@ import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.constant.ProcessMessageCode.MAXIMUM_NUMBER_CONCURRENCY_ILLEGAL import com.tencent.devops.process.constant.ProcessMessageCode.PROJECT_NOT_EXIST import com.tencent.devops.process.dao.PipelineSettingDao -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_CON_QUEUE_SIZE_MAX import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_QUEUE_SIZE_MIN diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineSettingResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineSettingResourceImpl.kt index 9d246d7f8f1..6d14358bafa 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineSettingResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineSettingResourceImpl.kt @@ -30,7 +30,7 @@ package com.tencent.devops.process.api.service import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.enums.ChannelCode import com.tencent.devops.common.web.RestResource -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.pojo.setting.UpdatePipelineModelRequest import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService import org.springframework.beans.factory.annotation.Autowired diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPTemplateResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPTemplateResourceImpl.kt index 7e0e8687005..c17ee3d7888 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPTemplateResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPTemplateResourceImpl.kt @@ -33,8 +33,8 @@ import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.web.RestResource import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.constant.ProcessMessageCode -import com.tencent.devops.process.pojo.setting.PipelineRunLockType -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.pojo.template.CopyTemplateReq import com.tencent.devops.process.pojo.template.OptionalTemplateList import com.tencent.devops.process.pojo.template.SaveAsTemplateReq diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/notify/command/BuildNotifyContext.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/notify/command/BuildNotifyContext.kt index dcd66fcfa05..d39bd563cb8 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/notify/command/BuildNotifyContext.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/notify/command/BuildNotifyContext.kt @@ -3,7 +3,7 @@ package com.tencent.devops.process.notify.command import com.tencent.devops.common.api.util.Watcher import com.tencent.devops.common.pipeline.enums.BuildStatus import com.tencent.devops.process.command.CmdContext -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting data class BuildNotifyContext( override var cmdFlowSeq: Int = 0, // 命令序号 diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index fbf6dfc6a8c..f4d8aecc53c 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -72,8 +72,8 @@ import com.tencent.devops.process.pojo.classify.PipelineViewBulkAdd import com.tencent.devops.process.pojo.pipeline.DeletePipelineResult import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion -import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.pojo.template.TemplateType import com.tencent.devops.process.service.label.PipelineGroupService import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineListFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineListFacadeService.kt index d03c2169ea8..364468054c4 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineListFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineListFacadeService.kt @@ -91,7 +91,7 @@ import com.tencent.devops.process.pojo.classify.enums.Logic import com.tencent.devops.process.pojo.code.WebhookInfo import com.tencent.devops.process.pojo.pipeline.PipelineCount import com.tencent.devops.process.pojo.pipeline.SimplePipeline -import com.tencent.devops.process.pojo.setting.PipelineRunLockType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType import com.tencent.devops.process.pojo.template.TemplatePipelineInfo import com.tencent.devops.process.service.label.PipelineGroupService import com.tencent.devops.process.service.pipeline.PipelineStatusService diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineSettingVersionService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineSettingVersionService.kt index 661dea4c2cb..a324754ad8c 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineSettingVersionService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineSettingVersionService.kt @@ -40,12 +40,10 @@ class PipelineSettingVersionService @Autowired constructor( private val pipelineSettingVersionDao: PipelineSettingVersionDao ) { - fun getSubscriptionsVer( - userId: String, + fun getPipelineSettingVersion( projectId: String, pipelineId: String, - version: Int, - channelCode: ChannelCode = ChannelCode.BS + version: Int ): PipelineSettingVersion { return pipelineSettingVersionDao.getSettingVersion( dslContext = dslContext, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt index c6b56b5e6f4..f1d438bcadd 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt @@ -52,10 +52,10 @@ import com.tencent.devops.process.pojo.config.StageCommonSettingConfig import com.tencent.devops.process.pojo.config.TaskCommonSettingConfig import com.tencent.devops.process.pojo.setting.JobCommonSetting import com.tencent.devops.process.pojo.setting.PipelineCommonSetting -import com.tencent.devops.process.pojo.setting.PipelineRunLockType -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.pojo.setting.StageCommonSetting -import com.tencent.devops.process.pojo.setting.Subscription +import com.tencent.devops.common.pipeline.pojo.setting.Subscription import com.tencent.devops.process.pojo.setting.TaskCommonSetting import com.tencent.devops.process.pojo.setting.TaskComponentCommonSetting import com.tencent.devops.process.pojo.setting.UpdatePipelineModelRequest @@ -252,7 +252,7 @@ class PipelineSettingFacadeService @Autowired constructor( } if (version > 0) { // #671 目前只接受通知设置的版本管理, 其他属于公共设置不接受版本管理 - val ve = pipelineSettingVersionService.getSubscriptionsVer(userId, projectId, pipelineId, version) + val ve = pipelineSettingVersionService.getPipelineSettingVersion(projectId, pipelineId, version) settingInfo.successSubscription = ve.successSubscription settingInfo.failSubscription = ve.failSubscription settingInfo.successSubscriptionList = ve.successSubscriptionList diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt index e8b6d99fcf3..35a1038e2c7 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt @@ -85,7 +85,7 @@ import com.tencent.devops.process.permission.PipelinePermissionService import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineTemplateInfo import com.tencent.devops.process.pojo.enums.TemplateSortTypeEnum -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.pojo.template.AddMarketTemplateRequest import com.tencent.devops.process.pojo.template.CopyTemplateReq import com.tencent.devops.process.pojo.template.OptionalTemplate diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt index 2ce6aac6b63..ead7a8c4795 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt @@ -30,10 +30,10 @@ package com.tencent.devops.process.service.transfer import com.fasterxml.jackson.core.type.TypeReference import com.tencent.devops.common.api.exception.ErrorCodeException import com.tencent.devops.common.api.util.Watcher +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting import com.tencent.devops.common.pipeline.pojo.element.Element import com.tencent.devops.process.engine.service.PipelineRepositoryService import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion -import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting import com.tencent.devops.process.pojo.transfer.PreviewResponse import com.tencent.devops.process.pojo.transfer.TransferActionType import com.tencent.devops.process.pojo.transfer.TransferBody @@ -190,7 +190,7 @@ class PipelineTransferYamlService @Autowired constructor( return pipelineRepositoryService.getPipelineResourceVersion( projectId = projectId, pipelineId = pipelineId, - version = version, + version = version ) } } diff --git a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/service/StreamPipelineService.kt b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/service/StreamPipelineService.kt index 268772165e2..57508bbf2ab 100644 --- a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/service/StreamPipelineService.kt +++ b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/service/StreamPipelineService.kt @@ -37,7 +37,7 @@ import com.tencent.devops.common.redis.RedisLock import com.tencent.devops.common.redis.RedisOperation import com.tencent.devops.model.stream.tables.records.TGitPipelineResourceRecord import com.tencent.devops.process.api.service.ServicePipelineResource -import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting import com.tencent.devops.process.yaml.v2.utils.ScriptYmlUtils import com.tencent.devops.stream.config.StreamGitConfig import com.tencent.devops.stream.dao.GitPipelineResourceDao diff --git a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlBaseBuild.kt b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlBaseBuild.kt index e9abcde563c..d57f0c3c2f1 100644 --- a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlBaseBuild.kt +++ b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlBaseBuild.kt @@ -46,7 +46,7 @@ import com.tencent.devops.process.pojo.BuildId import com.tencent.devops.process.pojo.BuildTemplateAcrossInfo import com.tencent.devops.process.pojo.TemplateAcrossInfoType import com.tencent.devops.process.pojo.code.PipelineBuildCommit -import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting import com.tencent.devops.process.pojo.webhook.WebhookTriggerParams import com.tencent.devops.process.utils.PIPELINE_NAME import com.tencent.devops.process.yaml.v2.enums.TemplateType diff --git a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlTrigger.kt b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlTrigger.kt index b745a82c200..2fee7f5640b 100644 --- a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlTrigger.kt +++ b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlTrigger.kt @@ -39,7 +39,6 @@ import com.tencent.devops.process.api.service.ServicePipelineSettingResource import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.exception.YamlFormatException import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYaml -import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYamlI import com.tencent.devops.process.yaml.v2.models.Resources import com.tencent.devops.process.yaml.v2.models.ResourcesPools import com.tencent.devops.process.yaml.v2.models.format diff --git a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/util/StreamPipelineUtils.kt b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/util/StreamPipelineUtils.kt index 60205f51603..2750f73a333 100644 --- a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/util/StreamPipelineUtils.kt +++ b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/util/StreamPipelineUtils.kt @@ -35,8 +35,8 @@ import com.tencent.devops.common.pipeline.container.TriggerContainer import com.tencent.devops.common.pipeline.pojo.element.trigger.ManualTriggerElement import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.engine.common.VMUtils -import com.tencent.devops.process.pojo.setting.PipelineModelAndSetting -import com.tencent.devops.process.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting @Suppress("LongParameterList", "ReturnCount") object StreamPipelineUtils { From 9f989b48c9646d364cc08c017aa9c08514c816a7 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 15 Aug 2023 17:53:59 +0800 Subject: [PATCH 066/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0=E8=8E=B7=E5=8F=96=E5=90=AByaml?= =?UTF-8?q?=E5=86=85=E5=AE=B9=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- support-files/i18n/process/message_en_US.properties | 1 + support-files/i18n/process/message_zh_CN.properties | 1 + 2 files changed, 2 insertions(+) diff --git a/support-files/i18n/process/message_en_US.properties b/support-files/i18n/process/message_en_US.properties index 3bfe3adcfbd..6415e2c44c3 100644 --- a/support-files/i18n/process/message_en_US.properties +++ b/support-files/i18n/process/message_en_US.properties @@ -180,6 +180,7 @@ 2101180=You do not have access to the pipeline information for plugin {0}. Please contact the component administrator. 2101181=group ({0}) is already exist 2101182=group label ({0}) is already exist +2101183=Pipeline version ({0}) does not exist ATOM_POST_EXECUTE_TIP=###Tip:this is the post-action hooked by [step{0}]{1}### BK_CI_BUILD_ID=Currently build ID BK_CI_BUILD_JOB_ID=Pipelined JOB ID diff --git a/support-files/i18n/process/message_zh_CN.properties b/support-files/i18n/process/message_zh_CN.properties index de7dccfa7f2..92832dcbcff 100644 --- a/support-files/i18n/process/message_zh_CN.properties +++ b/support-files/i18n/process/message_zh_CN.properties @@ -180,6 +180,7 @@ 2101180=无权访问插件{0}的流水线信息,请联系组件管理员 2101181=分组({0})已存在 2101182=分组标签({0})已存在 +2101183=流水线版本({0})不存在 ATOM_POST_EXECUTE_TIP=###Tip:this is the post-action hooked by [step{0}]{1}### BK_CI_BUILD_ID=当前构建ID BK_CI_BUILD_JOB_ID=流水线JOB ID From 5fdbe85e5ccb14cf91b800facc5d830fdb03ec80 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 15 Aug 2023 21:01:53 +0800 Subject: [PATCH 067/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E4=BF=9D=E5=AD=98=E8=8D=89=E7=A8=BF=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/pipeline/PipelineModelAndYaml.kt | 6 +- .../api/user/UserPipelineVersionResource.kt | 12 ++- .../pojo/pipeline/PipelineResourceVersion.kt | 4 +- .../engine/dao/PipelineResVersionDao.kt | 15 ++-- .../api/UserPipelineVersionResourceImpl.kt | 74 ++++++++++--------- 5 files changed, 60 insertions(+), 51 deletions(-) diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt index cf0c3e5b1f7..8c6eb111623 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt @@ -34,5 +34,9 @@ data class PipelineModelAndYaml( @ApiModelProperty("流水线模型", required = true) val modelAndSetting: PipelineModelAndSetting, @ApiModelProperty("流水线YAML编排(不为空时以YAML为准)", required = false) - val yaml: String? + val yaml: String?, + @ApiModelProperty("版本变更说明", required = false) + val description: String? = null, + @ApiModelProperty("保存草稿时的来源版本", required = false) + val baseVersion: String? = null ) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 1e3844943c9..e9fcb8e3b53 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -37,6 +37,7 @@ import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting +import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult import com.tencent.devops.process.pojo.transfer.PreviewResponse import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation @@ -71,7 +72,7 @@ interface UserPipelineVersionResource { projectId: String, @ApiParam(value = "流水线模型实例请求", required = true) pipeline: TemplateInstanceCreateRequest - ): Result + ): Result @ApiOperation("获取流水线指定版本的两种编排") @GET @@ -112,7 +113,7 @@ interface UserPipelineVersionResource { @ApiOperation("保存流水线编排草稿") @POST @Path("/projects/{projectId}/pipelines/{pipelineId}/saveDraft") - fun savePipeline( + fun savePipelineDraft( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) userId: String, @@ -124,11 +125,8 @@ interface UserPipelineVersionResource { pipelineId: String, @ApiParam(value = "流水线模型与设置", required = true) @Valid - modelAndYaml: PipelineModelAndYaml, - @ApiParam("变更说明", required = false) - @QueryParam("description") - description: String? = null - ): Result + modelAndYaml: PipelineModelAndYaml + ): Result @ApiOperation("保存流水线设置") @POST diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt index 4444fc38bd2..3269669e9e0 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt @@ -65,5 +65,7 @@ data class PipelineResourceVersion( @ApiModelProperty("草稿版本标识", required = false) val status: VersionStatus? = VersionStatus.RELEASED, @ApiModelProperty("分支版本标识", required = false) - val refs: String? = null + val refs: String? = null, + @ApiModelProperty("版本变更说明", required = false) + val description: String? = null ) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt index fbccb666c02..1277af5735b 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt @@ -32,6 +32,7 @@ import com.tencent.devops.common.api.util.timestampmilli import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.enums.VersionStatus import com.tencent.devops.model.process.Tables.T_PIPELINE_RESOURCE_VERSION +import com.tencent.devops.model.process.tables.records.TPipelineResourceVersionRecord import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion import com.tencent.devops.process.pojo.setting.PipelineVersionSimple import org.jooq.DSLContext @@ -57,8 +58,8 @@ class PipelineResVersionDao { settingVersion: Int?, status: VersionStatus?, description: String? - ) { - create( + ): TPipelineResourceVersionRecord? { + return create( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, @@ -89,9 +90,9 @@ class PipelineResVersionDao { settingVersion: Int?, status: VersionStatus?, description: String? - ) { + ): TPipelineResourceVersionRecord? { with(T_PIPELINE_RESOURCE_VERSION) { - dslContext.insertInto(this) + return dslContext.insertInto(this) .set(PROJECT_ID, projectId) .set(PIPELINE_ID, pipelineId) .set(VERSION, version) @@ -114,7 +115,8 @@ class PipelineResVersionDao { .set(SETTING_VERSION, settingVersion) .set(STATUS, status?.name) .set(DESCRIPTION, description) - .execute() + .returning() + .fetchOne() } } @@ -180,7 +182,8 @@ class PipelineResVersionDao { referFlag = record.referFlag, referCount = record.referCount, status = record.status?.let { VersionStatus.valueOf(it) }, - refs = record.refs + refs = record.refs, + description = record.description ) } } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index 521950f0ebc..2fc3bdfc7cc 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -52,6 +52,7 @@ import com.tencent.devops.process.pojo.audit.Audit import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.constant.ProcessMessageCode import com.tencent.devops.process.engine.service.PipelineRepositoryService +import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult import com.tencent.devops.process.pojo.transfer.PreviewResponse import com.tencent.devops.process.pojo.transfer.TransferActionType import com.tencent.devops.process.pojo.transfer.TransferBody @@ -74,39 +75,11 @@ class UserPipelineVersionResourceImpl @Autowired constructor( private val pipelineRepositoryService: PipelineRepositoryService ) : UserPipelineVersionResource { - override fun preview( - userId: String, - projectId: String, - pipelineId: String, - version: Int? - ): Result { - val permission = AuthPermission.VIEW - pipelinePermissionService.validPipelinePermission( - userId = userId, - projectId = projectId, - pipelineId = pipelineId, - permission = permission, - message = MessageUtil.getMessageByLocale( - CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, - I18nUtil.getLanguage(userId), - arrayOf( - userId, - projectId, - permission.getI18n(I18nUtil.getLanguage(userId)), - pipelineId - ) - ) - ) - return Result( - transferService.buildPreview(userId, projectId, pipelineId, version) - ) - } - override fun createPipelineFromTemplate( userId: String, projectId: String, pipeline: TemplateInstanceCreateRequest - ): Result { + ): Result { TODO() } @@ -162,19 +135,48 @@ class UserPipelineVersionResourceImpl @Autowired constructor( return Result( PipelineModelAndYaml( modelAndSetting = modelAndSetting, - yaml = yaml + yaml = yaml, + description = resource.description + ) + ) + } + + override fun preview( + userId: String, + projectId: String, + pipelineId: String, + version: Int? + ): Result { + val permission = AuthPermission.VIEW + pipelinePermissionService.validPipelinePermission( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + permission = permission, + message = MessageUtil.getMessageByLocale( + CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, + I18nUtil.getLanguage(userId), + arrayOf( + userId, + projectId, + permission.getI18n(I18nUtil.getLanguage(userId)), + pipelineId + ) ) ) + return Result( + transferService.buildPreview(userId, projectId, pipelineId, version) + ) } - override fun savePipeline( + override fun savePipelineDraft( userId: String, projectId: String, pipelineId: String, - modelAndYaml: PipelineModelAndYaml, - description: String? - ): Result { + modelAndYaml: PipelineModelAndYaml + ): Result { checkParam(userId, projectId) + // TODO 保存草稿时如果有传YAML先以YAML为准进行校验 val pipelineResult = pipelineInfoFacadeService.editPipeline( userId = userId, projectId = projectId, @@ -184,7 +186,7 @@ class UserPipelineVersionResourceImpl @Autowired constructor( checkPermission = true, checkTemplate = true, saveDraft = true, - description = description + description = modelAndYaml.description ) auditService.createAudit( Audit( @@ -197,7 +199,7 @@ class UserPipelineVersionResourceImpl @Autowired constructor( projectId = projectId ) ) - return Result(true) + return Result(pipelineResult) } override fun saveSetting( From 516423e1e24b153bad5514a09a30ee7230e23654 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Wed, 16 Aug 2023 17:48:30 +0800 Subject: [PATCH 068/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E4=BF=9D=E5=AD=98=E8=8D=89=E7=A8=BF=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/pipeline/enums/VersionStatus.kt | 5 +- .../pojo/TemplateInstanceCreateRequest.kt | 13 ++-- .../api/user/UserPipelineVersionResource.kt | 2 +- .../service/PipelineRepositoryService.kt | 15 +++-- .../api/ServicePipelineResourceImpl.kt | 4 +- .../process/api/UserPipelineResourceImpl.kt | 4 +- .../api/UserPipelineTransferResourceImpl.kt | 57 +++++++++++++++++ .../api/UserPipelineVersionResourceImpl.kt | 61 ++++++++++++++++--- .../service/AtomMarketInitPipelineService.kt | 1 + .../service/PipelineInfoFacadeService.kt | 24 +++++--- .../store/CheckImageInitPipelineService.kt | 1 + .../service/template/TemplateFacadeService.kt | 2 +- .../transfer/PipelineTransferYamlService.kt | 4 -- 13 files changed, 155 insertions(+), 38 deletions(-) diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/enums/VersionStatus.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/enums/VersionStatus.kt index c7a7f3fbddd..fb53d082f52 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/enums/VersionStatus.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/enums/VersionStatus.kt @@ -28,6 +28,7 @@ package com.tencent.devops.common.pipeline.enums enum class VersionStatus(val statusName: String) { - RELEASED("已发布"), - COMMITTING("提交中"); + RELEASED("已发布版本"), + COMMITTING("草稿版本"), + BRANCH("分支版本"); } diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/TemplateInstanceCreateRequest.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/TemplateInstanceCreateRequest.kt index 367d73b30c6..e440df09149 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/TemplateInstanceCreateRequest.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/TemplateInstanceCreateRequest.kt @@ -27,17 +27,20 @@ package com.tencent.devops.common.pipeline.pojo +import com.tencent.devops.common.pipeline.enums.PipelineInstanceTypeEnum import io.swagger.annotations.ApiModelProperty data class TemplateInstanceCreateRequest( @ApiModelProperty("模板ID", required = true) var templateId: String, - @ApiModelProperty("版本REF(不传默认最新)", required = false) - var ref: String?, - @ApiModelProperty("是否使用模板配置", required = false) - var useTemplateSettings: Boolean?, + @ApiModelProperty("模板版本号(为空时默认最新)", required = true) + var templateVersion: Long?, + @ApiModelProperty("是否使用通知配置", required = false) + var useSubscriptionSettings: Boolean?, @ApiModelProperty("是否使用标签配置", required = false) var useLabelSettings: Boolean?, - @ApiModelProperty("是否使用并发配置", required = false) + @ApiModelProperty("是否使用并发组配置", required = false) var useConcurrencyGroup: Boolean?, + @ApiModelProperty("创建实例的模式", required = false) + var instanceType: String? = PipelineInstanceTypeEnum.FREEDOM.type ) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index e9fcb8e3b53..2637184aaf7 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -71,7 +71,7 @@ interface UserPipelineVersionResource { @PathParam("projectId") projectId: String, @ApiParam(value = "流水线模型实例请求", required = true) - pipeline: TemplateInstanceCreateRequest + request: TemplateInstanceCreateRequest ): Result @ApiOperation("获取流水线指定版本的两种编排") diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index bd64aa6090c..386166113d6 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -203,7 +203,9 @@ class PipelineRepositoryService constructor( userId: String, channelCode: ChannelCode, create: Boolean, - useTemplateSettings: Boolean? = false, + useSubscriptionSettings: Boolean? = false, + useLabelSettings: Boolean? = false, + useConcurrencyGroup: Boolean? = false, templateId: String? = null, updateLastModifyUser: Boolean? = true, savedSetting: PipelineSetting? = null, @@ -284,7 +286,9 @@ class PipelineRepositoryService constructor( canElementSkip = canElementSkip, buildNo = buildNo, modelTasks = modelTasks, - useTemplateSettings = useTemplateSettings, + useSubscriptionSettings = useSubscriptionSettings, + useLabelSettings = useLabelSettings, + useConcurrencyGroup = useConcurrencyGroup, templateId = templateId, saveDraft = saveDraft, description = description @@ -583,7 +587,9 @@ class PipelineRepositoryService constructor( canElementSkip: Boolean, buildNo: BuildNo?, modelTasks: Collection, - useTemplateSettings: Boolean? = false, + useSubscriptionSettings: Boolean? = false, + useLabelSettings: Boolean? = false, + useConcurrencyGroup: Boolean? = false, templateId: String? = null, saveDraft: Boolean? = false, description: String? @@ -617,7 +623,8 @@ class PipelineRepositoryService constructor( model.latestVersion = modelVersion if (model.instanceFromTemplate != true) { if (null == pipelineSettingDao.getSetting(transactionContext, projectId, pipelineId)) { - if (templateId != null && useTemplateSettings == true) { + // TODO useSubscriptionSettings/useLabelSettings/useConcurrencyGroup 使用三个参数控制刷新 + if (templateId != null && useSubscriptionSettings == true) { // 沿用模板的配置 val setting = getSetting(projectId, templateId) ?: throw ErrorCodeException(errorCode = ProcessMessageCode.PIPELINE_SETTING_NOT_EXISTS) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt index 2f37fa79be9..5a106eb1fc7 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt @@ -113,8 +113,8 @@ class ServicePipelineResourceImpl @Autowired constructor( model = pipeline, channelCode = channelCode, checkPermission = ChannelCode.isNeedAuth(channelCode), - useTemplateSettings = useTemplateSettings - ) + useSubscriptionSettings = useTemplateSettings + ).pipelineId ) ) } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index 86b04a8b4cf..a4791c9a756 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -156,8 +156,8 @@ class UserPipelineResourceImpl @Autowired constructor( projectId = projectId, model = pipeline, channelCode = ChannelCode.BS, - useTemplateSettings = useTemplateSettings - ) + useSubscriptionSettings = useTemplateSettings + ).pipelineId ) auditService.createAudit( Audit( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt index 154abdc1ff1..21272efd985 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt @@ -27,10 +27,15 @@ package com.tencent.devops.process.api +import com.tencent.devops.common.api.constant.CommonMessageCode import com.tencent.devops.common.api.pojo.Result +import com.tencent.devops.common.api.util.MessageUtil +import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.pipeline.pojo.element.Element import com.tencent.devops.common.web.RestResource +import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.api.user.UserPipelineTransferResource +import com.tencent.devops.process.permission.PipelinePermissionService import com.tencent.devops.process.pojo.transfer.TransferActionType import com.tencent.devops.process.pojo.transfer.TransferBody import com.tencent.devops.process.pojo.transfer.TransferResponse @@ -39,6 +44,7 @@ import org.springframework.beans.factory.annotation.Autowired @RestResource class UserPipelineTransferResourceImpl @Autowired constructor( + private val pipelinePermissionService: PipelinePermissionService, private val transferService: PipelineTransferYamlService ) : UserPipelineTransferResource { override fun transfer( @@ -48,6 +54,23 @@ class UserPipelineTransferResourceImpl @Autowired constructor( actionType: TransferActionType, data: TransferBody ): Result { + val permission = AuthPermission.VIEW + pipelinePermissionService.validPipelinePermission( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + permission = permission, + message = MessageUtil.getMessageByLocale( + CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, + I18nUtil.getLanguage(userId), + arrayOf( + userId, + projectId, + permission.getI18n(I18nUtil.getLanguage(userId)), + pipelineId + ) + ) + ) return Result(transferService.transfer(userId, projectId, pipelineId, actionType, data)) } @@ -57,6 +80,23 @@ class UserPipelineTransferResourceImpl @Autowired constructor( pipelineId: String, data: Element ): Result { + val permission = AuthPermission.VIEW + pipelinePermissionService.validPipelinePermission( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + permission = permission, + message = MessageUtil.getMessageByLocale( + CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, + I18nUtil.getLanguage(userId), + arrayOf( + userId, + projectId, + permission.getI18n(I18nUtil.getLanguage(userId)), + pipelineId + ) + ) + ) return Result(transferService.modelTaskTransfer(userId, projectId, pipelineId, data)) } @@ -66,6 +106,23 @@ class UserPipelineTransferResourceImpl @Autowired constructor( pipelineId: String, yaml: String ): Result { + val permission = AuthPermission.VIEW + pipelinePermissionService.validPipelinePermission( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + permission = permission, + message = MessageUtil.getMessageByLocale( + CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, + I18nUtil.getLanguage(userId), + arrayOf( + userId, + projectId, + permission.getI18n(I18nUtil.getLanguage(userId)), + pipelineId + ) + ) + ) return Result(transferService.yamlTaskTransfer(userId, projectId, pipelineId, yaml)) } } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index 2fc3bdfc7cc..c70387bc4e4 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -46,7 +46,6 @@ import com.tencent.devops.process.audit.service.AuditService import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.engine.service.PipelineVersionFacadeService import com.tencent.devops.process.permission.PipelinePermissionService -import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.audit.Audit import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting @@ -59,6 +58,7 @@ import com.tencent.devops.process.pojo.transfer.TransferBody import com.tencent.devops.process.service.PipelineInfoFacadeService import com.tencent.devops.process.service.PipelineOperationLogService import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService +import com.tencent.devops.process.service.template.TemplateFacadeService import com.tencent.devops.process.service.transfer.PipelineTransferYamlService import org.springframework.beans.factory.annotation.Autowired @@ -72,15 +72,46 @@ class UserPipelineVersionResourceImpl @Autowired constructor( private val pipelineVersionFacadeService: PipelineVersionFacadeService, private val pipelineOperationLogService: PipelineOperationLogService, private val transferService: PipelineTransferYamlService, - private val pipelineRepositoryService: PipelineRepositoryService + private val pipelineRepositoryService: PipelineRepositoryService, + private val templateFacadeService: TemplateFacadeService ) : UserPipelineVersionResource { override fun createPipelineFromTemplate( userId: String, projectId: String, - pipeline: TemplateInstanceCreateRequest + request: TemplateInstanceCreateRequest ): Result { - TODO() + pipelinePermissionService.checkPipelinePermission( + userId = userId, + projectId = projectId, + AuthPermission.CREATE + ) + val templateDetail = templateFacadeService.getTemplate( + userId = userId, + projectId = projectId, + templateId = request.templateId, + version = request.templateVersion + ) + // TODO 区分应用模板的配置 + val templateSetting = templateFacadeService.getTemplateSetting( + userId = userId, + projectId = projectId, + templateId = request.templateId + ) + return Result( + pipelineInfoFacadeService.createPipeline( + userId = userId, + projectId = projectId, + model = templateDetail.template.copy(templateId = request.templateId), + channelCode = ChannelCode.BS, + checkPermission = false, + instanceType = request.instanceType, + saveDraft = true, + useSubscriptionSettings = request.useSubscriptionSettings, + useLabelSettings = request.useLabelSettings, + useConcurrencyGroup = request.useConcurrencyGroup + ) + ) } override fun getVersion( @@ -176,15 +207,31 @@ class UserPipelineVersionResourceImpl @Autowired constructor( modelAndYaml: PipelineModelAndYaml ): Result { checkParam(userId, projectId) - // TODO 保存草稿时如果有传YAML先以YAML为准进行校验 + val permission = AuthPermission.EDIT + pipelinePermissionService.validPipelinePermission( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + permission = permission, + message = MessageUtil.getMessageByLocale( + CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, + I18nUtil.getLanguage(userId), + arrayOf( + userId, + projectId, + permission.getI18n(I18nUtil.getLanguage(userId)), + pipelineId + ) + ) + ) val pipelineResult = pipelineInfoFacadeService.editPipeline( userId = userId, projectId = projectId, pipelineId = pipelineId, model = modelAndYaml.modelAndSetting.model, channelCode = ChannelCode.BS, - checkPermission = true, - checkTemplate = true, + checkPermission = false, + checkTemplate = false, saveDraft = true, description = modelAndYaml.description ) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/AtomMarketInitPipelineService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/AtomMarketInitPipelineService.kt index 9a8c6d8ba0c..2c4f52f6db6 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/AtomMarketInitPipelineService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/AtomMarketInitPipelineService.kt @@ -75,6 +75,7 @@ class AtomMarketInitPipelineService @Autowired constructor( val model = JsonUtil.to(atomMarketInitPipelineReq.pipelineModel, Model::class.java) // 保存流水线信息 val pipelineId = pipelineInfoFacadeService.createPipeline(userId, projectCode, model, ChannelCode.AM) + .pipelineId logger.info("createPipeline result is:$pipelineId") // 异步启动流水线 val startParams = mutableMapOf() // 启动参数 diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index f4d8aecc53c..93379f5bd59 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -199,7 +199,7 @@ class PipelineInfoFacadeService @Autowired constructor( model = model, channelCode = ChannelCode.BS, checkPermission = true - ) + ).pipelineId val newSetting = pipelineSettingFacadeService.rebuildSetting( oldSetting = pipelineModelAndSetting.setting, @@ -251,8 +251,11 @@ class PipelineInfoFacadeService @Autowired constructor( buildNo: BuildNo? = null, param: List? = null, fixTemplateVersion: Long? = null, - useTemplateSettings: Boolean? = false - ): String { + saveDraft: Boolean? = false, + useSubscriptionSettings: Boolean? = false, + useLabelSettings: Boolean? = false, + useConcurrencyGroup: Boolean? = false + ): DeployPipelineResult { val watcher = Watcher(id = "createPipeline|$projectId|$userId|$channelCode|$checkPermission|$instanceType|$fixPipelineId") var success = false @@ -361,23 +364,24 @@ class PipelineInfoFacadeService @Autowired constructor( model } watcher.start("deployPipeline") - pipelineId = pipelineRepositoryService.deployPipeline( + val result = pipelineRepositoryService.deployPipeline( model = instance, projectId = projectId, signPipelineId = fixPipelineId, userId = userId, channelCode = channelCode, create = true, - useTemplateSettings = useTemplateSettings, - templateId = model.templateId, + useSubscriptionSettings = useSubscriptionSettings, + templateId = templateId, description = null - ).pipelineId + ) + pipelineId = result.pipelineId watcher.stop() // 先进行模板关联操作 if (templateId != null) { watcher.start("addLabel") - if (useTemplateSettings == true) { + if (useSubscriptionSettings == true) { val groups = pipelineGroupService.getGroups(userId, projectId, templateId) val labels = ArrayList() groups.forEach { @@ -443,7 +447,7 @@ class PipelineInfoFacadeService @Autowired constructor( ) success = true - return pipelineId + return result } catch (duplicateKeyException: DuplicateKeyException) { logger.info("duplicateKeyException: ${duplicateKeyException.message}") if (pipelineId != null) { @@ -615,7 +619,7 @@ class PipelineInfoFacadeService @Autowired constructor( labels = pipelineCopy.labels ) modelCheckPlugin.clearUpModel(copyMode) - val newPipelineId = createPipeline(userId, projectId, copyMode, channelCode) + val newPipelineId = createPipeline(userId, projectId, copyMode, channelCode).pipelineId val settingInfo = pipelineSettingFacadeService.getSettingInfo(projectId, pipelineId) if (settingInfo != null) { // setting pipeline需替换成新流水线的 diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/store/CheckImageInitPipelineService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/store/CheckImageInitPipelineService.kt index 0ce5531519c..16f5d2e6785 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/store/CheckImageInitPipelineService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/store/CheckImageInitPipelineService.kt @@ -66,6 +66,7 @@ class CheckImageInitPipelineService @Autowired constructor( // 保存流水线信息 val model = JsonUtil.to(checkImageInitPipelineReq.pipelineModel, Model::class.java) val pipelineId = pipelineInfoFacadeService.createPipeline(userId, projectCode, model, ChannelCode.AM) + .pipelineId logger.info("createPipeline result is:$pipelineId") // 异步启动流水线 val startParams = mutableMapOf() // 启动参数 diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt index 35a1038e2c7..9557cb9b768 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt @@ -1287,7 +1287,7 @@ class TemplateFacadeService @Autowired constructor( buildNo = buildNo, param = param, fixTemplateVersion = version - ) + ).pipelineId dslContext.transaction { configuration -> val context = DSL.using(configuration) if (useTemplateSettings) { diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt index ead7a8c4795..6f326a2b184 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt @@ -86,7 +86,6 @@ class PipelineTransferYamlService @Autowired constructor( ): TransferResponse { val watcher = Watcher(id = "yaml and model transfer watcher") - // todo 权限校验 when (actionType) { TransferActionType.FULL_MODEL2YAML -> { watcher.start("step_1|FULL_MODEL2YAML start") @@ -143,7 +142,6 @@ class PipelineTransferYamlService @Autowired constructor( pipelineId: String, data: Element ): String { - // todo 权限校验 val yml = elementTransfer.element2YamlStep(data) ?: throw ErrorCodeException(errorCode = "") return TransferMapper.toYaml(yml) } @@ -154,7 +152,6 @@ class PipelineTransferYamlService @Autowired constructor( pipelineId: String, yaml: String ): Element { - // todo 权限校验 val tYml = TransferMapper.getObjectMapper() .readValue(yaml, object : TypeReference() {}) return elementTransfer.yaml2element(ScriptYmlUtils.preStepToStep(tYml), null) @@ -166,7 +163,6 @@ class PipelineTransferYamlService @Autowired constructor( pipelineId: String, version: Int? ): PreviewResponse { - // todo 权限校验,增加不存在yaml时自动将model转过来 val yml = getPipelineResource(projectId, pipelineId, version)?.yaml ?: "" val pipelineIndex = mutableListOf() val triggerIndex = mutableListOf() From 5bc46e0b83f05ed22d8be71b7b048f428f923ac3 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Wed, 16 Aug 2023 17:48:34 +0800 Subject: [PATCH 069/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E4=BF=9D=E5=AD=98=E8=8D=89=E7=A8=BF=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/api/user/UserPipelineVersionResource.kt | 1 - .../devops/process/service/PipelineSettingVersionService.kt | 1 - 2 files changed, 2 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 2637184aaf7..fa2514dc202 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -34,7 +34,6 @@ import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.PipelineModelAndYaml import com.tencent.devops.common.pipeline.pojo.TemplateInstanceCreateRequest import com.tencent.devops.process.engine.pojo.PipelineResVersion -import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineSettingVersionService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineSettingVersionService.kt index a324754ad8c..20e2cbc01e1 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineSettingVersionService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineSettingVersionService.kt @@ -27,7 +27,6 @@ package com.tencent.devops.process.service -import com.tencent.devops.common.pipeline.enums.ChannelCode import com.tencent.devops.process.dao.PipelineSettingVersionDao import com.tencent.devops.process.pojo.setting.PipelineSettingVersion import org.jooq.DSLContext From 745b503727afdd14c6a28fbcbd56209d6c78ade1 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 17 Aug 2023 10:45:46 +0800 Subject: [PATCH 070/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E4=BF=9D=E5=AD=98=E8=8D=89=E7=A8=BF=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/engine/service/PipelineRepositoryService.kt | 2 -- .../devops/process/api/UserPipelineVersionResourceImpl.kt | 6 ------ .../devops/process/service/PipelineInfoFacadeService.kt | 3 ++- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index 386166113d6..6a3c5675adc 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -204,7 +204,6 @@ class PipelineRepositoryService constructor( channelCode: ChannelCode, create: Boolean, useSubscriptionSettings: Boolean? = false, - useLabelSettings: Boolean? = false, useConcurrencyGroup: Boolean? = false, templateId: String? = null, updateLastModifyUser: Boolean? = true, @@ -287,7 +286,6 @@ class PipelineRepositoryService constructor( buildNo = buildNo, modelTasks = modelTasks, useSubscriptionSettings = useSubscriptionSettings, - useLabelSettings = useLabelSettings, useConcurrencyGroup = useConcurrencyGroup, templateId = templateId, saveDraft = saveDraft, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index c70387bc4e4..d0e0b907bd2 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -92,12 +92,6 @@ class UserPipelineVersionResourceImpl @Autowired constructor( templateId = request.templateId, version = request.templateVersion ) - // TODO 区分应用模板的配置 - val templateSetting = templateFacadeService.getTemplateSetting( - userId = userId, - projectId = projectId, - templateId = request.templateId - ) return Result( pipelineInfoFacadeService.createPipeline( userId = userId, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index 93379f5bd59..b5a746996f8 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -372,6 +372,7 @@ class PipelineInfoFacadeService @Autowired constructor( channelCode = channelCode, create = true, useSubscriptionSettings = useSubscriptionSettings, + useConcurrencyGroup = useConcurrencyGroup, templateId = templateId, description = null ) @@ -381,7 +382,7 @@ class PipelineInfoFacadeService @Autowired constructor( // 先进行模板关联操作 if (templateId != null) { watcher.start("addLabel") - if (useSubscriptionSettings == true) { + if (useLabelSettings == true) { val groups = pipelineGroupService.getGroups(userId, projectId, templateId) val labels = ArrayList() groups.forEach { From d6d68b5954932ac90c10a2fc15f62bea054a0f0f Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 17 Aug 2023 11:38:58 +0800 Subject: [PATCH 071/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=20=E5=A2=9E=E5=8A=A0=E9=85=8D=E7=BD=AE=E5=8F=AF?= =?UTF-8?q?=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pipeline/pojo/setting/PipelineSetting.kt | 6 ++-- .../service/PipelineRepositoryService.kt | 34 +++++++++++++++++-- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/PipelineSetting.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/PipelineSetting.kt index 30d9cd42ccf..0094f6277ab 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/PipelineSetting.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/setting/PipelineSetting.kt @@ -67,13 +67,13 @@ data class PipelineSetting( @ApiModelProperty("并发时,设定的group", required = false) var concurrencyGroup: String? = PIPELINE_SETTING_CONCURRENCY_GROUP_DEFAULT, @ApiModelProperty("并发时,是否相同group取消正在执行的流水线", required = false) - val concurrencyCancelInProgress: Boolean = false, + var concurrencyCancelInProgress: Boolean = false, @ApiModelProperty("是否有操作权限", required = false) var hasPermission: Boolean? = null, @ApiModelProperty("保存流水线编排的最大个数", required = false) val maxPipelineResNum: Int = PIPELINE_RES_NUM_MIN, // 保存流水线编排的最大个数 @ApiModelProperty("并发构建数量限制", required = false) - val maxConRunningQueueSize: Int? = PIPELINE_SETTING_MAX_CON_QUEUE_SIZE_MAX, // MULTIPLE类型时,并发构建数量限制 + var maxConRunningQueueSize: Int? = PIPELINE_SETTING_MAX_CON_QUEUE_SIZE_MAX, // MULTIPLE类型时,并发构建数量限制 @ApiModelProperty("版本", required = false) var version: Int = 1, @field:BkField(patternStyle = BkStyleEnum.BUILD_NUM_RULE_STYLE, required = false) @@ -82,5 +82,5 @@ data class PipelineSetting( @ApiModelProperty("重试时清理引擎变量表", required = false) val cleanVariablesWhenRetry: Boolean? = false, @ApiModelProperty("YAML流水线特殊配置", required = false) - val pipelineAsCodeSettings: PipelineAsCodeSettings? = null + var pipelineAsCodeSettings: PipelineAsCodeSettings? = null ) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index 6a3c5675adc..89ce2ab5984 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -88,13 +88,17 @@ import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion import com.tencent.devops.process.pojo.setting.PipelineModelVersion import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSubscriptionType +import com.tencent.devops.common.pipeline.pojo.setting.Subscription import com.tencent.devops.process.service.PipelineOperationLogService +import com.tencent.devops.process.util.NotifyTemplateUtils import com.tencent.devops.process.utils.PIPELINE_MATRIX_CON_RUNNING_SIZE_MAX import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_CON_QUEUE_SIZE_MAX import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_QUEUE_SIZE_MAX import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_QUEUE_SIZE_MIN import com.tencent.devops.process.utils.PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_MAX import com.tencent.devops.process.utils.PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_MIN +import com.tencent.devops.process.utils.PIPELINE_START_USER_NAME import com.tencent.devops.project.api.service.ServiceAllocIdResource import com.tencent.devops.project.api.service.ServiceProjectResource import org.joda.time.LocalDateTime @@ -204,6 +208,7 @@ class PipelineRepositoryService constructor( channelCode: ChannelCode, create: Boolean, useSubscriptionSettings: Boolean? = false, + useLabelSettings: Boolean? = false, useConcurrencyGroup: Boolean? = false, templateId: String? = null, updateLastModifyUser: Boolean? = true, @@ -286,6 +291,7 @@ class PipelineRepositoryService constructor( buildNo = buildNo, modelTasks = modelTasks, useSubscriptionSettings = useSubscriptionSettings, + useLabelSettings = useLabelSettings, useConcurrencyGroup = useConcurrencyGroup, templateId = templateId, saveDraft = saveDraft, @@ -621,14 +627,38 @@ class PipelineRepositoryService constructor( model.latestVersion = modelVersion if (model.instanceFromTemplate != true) { if (null == pipelineSettingDao.getSetting(transactionContext, projectId, pipelineId)) { - // TODO useSubscriptionSettings/useLabelSettings/useConcurrencyGroup 使用三个参数控制刷新 - if (templateId != null && useSubscriptionSettings == true) { + if (templateId != null && (useSubscriptionSettings == true || useConcurrencyGroup == true)) { // 沿用模板的配置 val setting = getSetting(projectId, templateId) ?: throw ErrorCodeException(errorCode = ProcessMessageCode.PIPELINE_SETTING_NOT_EXISTS) setting.pipelineId = pipelineId setting.pipelineName = model.name setting.version = settingVersion + if (useSubscriptionSettings != true) { + setting.successSubscription = Subscription( + types = setOf(), + groups = emptySet(), + users = "\${$PIPELINE_START_USER_NAME}", + content = NotifyTemplateUtils.getCommonShutdownSuccessContent() + ) + setting.successSubscriptionList = listOf(setting.successSubscription) + setting.failSubscription = Subscription( + types = setOf(PipelineSubscriptionType.EMAIL, PipelineSubscriptionType.RTX), + groups = emptySet(), + users = "\${$PIPELINE_START_USER_NAME}", + content = NotifyTemplateUtils.getCommonShutdownFailureContent() + ) + setting.failSubscriptionList = listOf(setting.failSubscription) + } + if (useConcurrencyGroup != true) { + setting.concurrencyGroup = null + setting.concurrencyCancelInProgress = false + setting.maxConRunningQueueSize = PIPELINE_SETTING_MAX_CON_QUEUE_SIZE_MAX + } + if (useLabelSettings != true) { + setting.labels = listOf() + } + setting.pipelineAsCodeSettings = null pipelineSettingDao.saveSetting(dslContext, setting) } else { // #3311 From 8f7d0ebc6832627ea766a6c3409bcdd6b8202893 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 17 Aug 2023 20:49:37 +0800 Subject: [PATCH 072/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=20=E4=BF=AE=E5=A4=8D=E4=BA=92=E8=BD=AC=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../template/UserPipelineTemplateResource.kt | 1 + .../api/user/UserPipelineVersionResource.kt | 18 ++++++++++++- .../process/pojo/transfer/PreviewResponse.kt | 8 +++--- .../api/UserPipelineVersionResourceImpl.kt | 9 +++++++ .../transfer/PipelineTransferYamlService.kt | 27 ++++++++++++++++--- 5 files changed, 55 insertions(+), 8 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPipelineTemplateResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPipelineTemplateResource.kt index 3841a2eefe5..eaf12771fde 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPipelineTemplateResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/template/UserPipelineTemplateResource.kt @@ -50,6 +50,7 @@ import javax.ws.rs.core.MediaType @Path("/user/template/pipelines") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) +@Suppress("LongParameterList") interface UserPipelineTemplateResource { @ApiOperation("质量红线-获取模版列表") diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index fa2514dc202..2e2e7143193 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -228,7 +228,23 @@ interface UserPipelineVersionResource { pipelineId: String ): Result> - // TODO 回滚接口:回归指定版本作为草稿,覆盖已有草稿 + @ApiOperation("回退草稿为指定历史版本") + @POST + @Path("/projects/{projectId}/rollbackDraft") + fun rollbackDraftFromVersion( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String, + @ApiParam(value = "回退草稿的目标版本", required = true) + @QueryParam("version") + version: Int + ): Result // TODO 模板查询:在新建预览页带简要信息:3个bool diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/PreviewResponse.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/PreviewResponse.kt index 94947764492..f867923e67d 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/PreviewResponse.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/PreviewResponse.kt @@ -35,11 +35,11 @@ data class PreviewResponse( @ApiModelProperty("yaml内容") val yaml: String, @ApiModelProperty("流水线编排") - val pipeline: List?, + val pipeline: List? = listOf(), @ApiModelProperty("触发器配置") - val trigger: List?, + val trigger: List? = listOf(), @ApiModelProperty("通知配置") - val notice: List?, + val notice: List? = listOf(), @ApiModelProperty("基础设置") - val setting: List? + val setting: List? = listOf() ) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index d0e0b907bd2..4eb56dfdbc7 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -416,6 +416,15 @@ class UserPipelineVersionResourceImpl @Autowired constructor( return Result(result) } + override fun rollbackDraftFromVersion( + userId: String, + projectId: String, + pipelineId: String, + version: Int + ): Result { + TODO("Not yet implemented") + } + private fun checkParam(userId: String, projectId: String) { if (userId.isBlank()) { throw ParamBlankException("Invalid userId") diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt index 6f326a2b184..e369610ecc8 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt @@ -39,6 +39,7 @@ import com.tencent.devops.process.pojo.transfer.TransferActionType import com.tencent.devops.process.pojo.transfer.TransferBody import com.tencent.devops.process.pojo.transfer.TransferMark import com.tencent.devops.process.pojo.transfer.TransferResponse +import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService import com.tencent.devops.process.yaml.modelTransfer.ElementTransfer import com.tencent.devops.process.yaml.modelTransfer.ModelTransfer import com.tencent.devops.process.yaml.modelTransfer.TransferMapper @@ -61,6 +62,7 @@ import org.springframework.stereotype.Service class PipelineTransferYamlService @Autowired constructor( private val modelTransfer: ModelTransfer, private val elementTransfer: ElementTransfer, + private val pipelineSettingFacadeService: PipelineSettingFacadeService, private val pipelineRepositoryService: PipelineRepositoryService ) { @@ -163,18 +165,37 @@ class PipelineTransferYamlService @Autowired constructor( pipelineId: String, version: Int? ): PreviewResponse { - val yml = getPipelineResource(projectId, pipelineId, version)?.yaml ?: "" + val resource = getPipelineResource(projectId, pipelineId, version) + ?: return PreviewResponse("") + val setting = pipelineSettingFacadeService.userGetSetting( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + version = resource.settingVersion ?: version ?: 1 + ) + val modelAndSetting = PipelineModelAndSetting( + setting = setting, + model = resource.model + ) + val yaml = resource.yaml ?: transfer( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + actionType = TransferActionType.FULL_MODEL2YAML, + data = TransferBody(modelAndSetting) + ).newYaml ?: return PreviewResponse("") + val pipelineIndex = mutableListOf() val triggerIndex = mutableListOf() val noticeIndex = mutableListOf() val settingIndex = mutableListOf() - TransferMapper.getYamlLevelOneIndex(yml).forEach { (key, value) -> + TransferMapper.getYamlLevelOneIndex(yaml).forEach { (key, value) -> if (key in pipeline_key) pipelineIndex.add(value) if (key in trigger_key) triggerIndex.add(value) if (key in notice_key) noticeIndex.add(value) if (key in setting_key) settingIndex.add(value) } - return PreviewResponse(yml, pipelineIndex, triggerIndex, noticeIndex, settingIndex) + return PreviewResponse(yaml, pipelineIndex, triggerIndex, noticeIndex, settingIndex) } private fun getPipelineResource( From 64f5a29d612cdd114b24207e8e21b55cbf9804f3 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Fri, 18 Aug 2023 10:58:43 +0800 Subject: [PATCH 073/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=20=E4=BF=AE=E5=A4=8D=E4=BA=92=E8=BD=AC=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/api/user/UserPipelineVersionResource.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 2e2e7143193..50f4a180233 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -228,7 +228,7 @@ interface UserPipelineVersionResource { pipelineId: String ): Result> - @ApiOperation("回退草稿为指定历史版本") + @ApiOperation("回滚到指定的历史版本并覆盖草稿") @POST @Path("/projects/{projectId}/rollbackDraft") fun rollbackDraftFromVersion( From ae76d06cd9b7d65c802c32d9cbaa7a67a0783162 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Fri, 18 Aug 2023 11:03:41 +0800 Subject: [PATCH 074/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E4=BC=98=E5=8C=96=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/api/user/UserPipelineVersionResource.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 50f4a180233..be29a58480c 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -230,7 +230,7 @@ interface UserPipelineVersionResource { @ApiOperation("回滚到指定的历史版本并覆盖草稿") @POST - @Path("/projects/{projectId}/rollbackDraft") + @Path("/projects/{projectId}/pipelines/{pipelineId}/rollbackDraft") fun rollbackDraftFromVersion( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -241,7 +241,7 @@ interface UserPipelineVersionResource { @ApiParam("流水线ID", required = true) @PathParam("pipelineId") pipelineId: String, - @ApiParam(value = "回退草稿的目标版本", required = true) + @ApiParam(value = "回回滚目标版本", required = true) @QueryParam("version") version: Int ): Result From ce4e5691130016e7d172d4eeab94c889095d6f92 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Fri, 18 Aug 2023 17:30:00 +0800 Subject: [PATCH 075/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E4=BC=98=E5=8C=96=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/user/UserPipelineVersionResource.kt | 17 ------- .../pojo/pipeline/PipelineResourceVersion.kt | 2 - .../engine/dao/PipelineResVersionDao.kt | 1 - .../api/UserPipelineVersionResourceImpl.kt | 46 +++++-------------- 4 files changed, 12 insertions(+), 54 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index be29a58480c..cf9082bc93f 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -127,23 +127,6 @@ interface UserPipelineVersionResource { modelAndYaml: PipelineModelAndYaml ): Result - @ApiOperation("保存流水线设置") - @POST - @Path("/projects/{projectId}/pipelines/{pipelineId}/saveSetting") - fun saveSetting( - @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) - @HeaderParam(AUTH_HEADER_USER_ID) - userId: String, - @ApiParam("项目ID", required = true) - @PathParam("projectId") - projectId: String, - @ApiParam("流水线ID", required = true) - @PathParam("pipelineId") - pipelineId: String, - @ApiParam(value = "流水线设置", required = true) - setting: PipelineSetting - ): Result - @ApiOperation("获取流水线编排创建人列表(分页)") @GET @Path("/projects/{projectId}/pipelines/{pipelineId}/creatorList") diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt index 3269669e9e0..c2e691ff5b0 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt @@ -64,8 +64,6 @@ data class PipelineResourceVersion( val referCount: Int? = null, @ApiModelProperty("草稿版本标识", required = false) val status: VersionStatus? = VersionStatus.RELEASED, - @ApiModelProperty("分支版本标识", required = false) - val refs: String? = null, @ApiModelProperty("版本变更说明", required = false) val description: String? = null ) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt index 1277af5735b..e19006e1b53 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt @@ -182,7 +182,6 @@ class PipelineResVersionDao { referFlag = record.referFlag, referCount = record.referCount, status = record.status?.let { VersionStatus.valueOf(it) }, - refs = record.refs, description = record.description ) } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index 4eb56dfdbc7..780109b3eff 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -218,6 +218,18 @@ class UserPipelineVersionResourceImpl @Autowired constructor( ) ) ) + // TODO 增加yaml处理和保存 +// val model = try { +// transferService.transfer( +// userId = userId, +// projectId = projectId, +// pipelineId = pipelineId, +// actionType = TransferActionType.FULL_YAML2MODEL, +// data = TransferBody( +// +// ) +// ) +// } val pipelineResult = pipelineInfoFacadeService.editPipeline( userId = userId, projectId = projectId, @@ -243,40 +255,6 @@ class UserPipelineVersionResourceImpl @Autowired constructor( return Result(pipelineResult) } - override fun saveSetting( - userId: String, - projectId: String, - pipelineId: String, - setting: PipelineSetting - ): Result { - checkParam(userId, projectId) - val savedSetting = pipelineSettingFacadeService.saveSetting( - userId = userId, - projectId = projectId, - pipelineId = pipelineId, - setting = setting, - checkPermission = true - ) - pipelineInfoFacadeService.updatePipelineSettingVersion( - userId = userId, - projectId = setting.projectId, - pipelineId = setting.pipelineId, - settingVersion = savedSetting.version - ) - auditService.createAudit( - Audit( - resourceType = AuthResourceType.PIPELINE_DEFAULT.value, - resourceId = pipelineId, - resourceName = setting.pipelineName, - userId = userId, - action = "edit", - actionContent = "Update Setting", - projectId = projectId - ) - ) - return Result(true) - } - override fun creatorList( userId: String, projectId: String, From 96d23ad1bf2e83a738fb42bc8ca55e01aee35849 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 22 Aug 2023 11:28:11 +0800 Subject: [PATCH 076/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/pipeline/PipelineModelAndYaml.kt | 6 +- .../process/api/user/UserPipelineResource.kt | 1 + .../api/user/UserPipelineVersionResource.kt | 1 + .../service/PipelineRepositoryService.kt | 32 +++---- .../engine/control/ContainerControl.kt | 1 + .../process/engine/control/StageControl.kt | 1 + .../process/engine/control/TaskControl.kt | 1 + .../api/ServicePipelineResourceImpl.kt | 1 + .../api/ServicePipelineVersionResourceImpl.kt | 1 + .../process/api/UserPipelineResourceImpl.kt | 1 + .../api/UserPipelineVersionResourceImpl.kt | 48 ++++++---- .../service/PipelineInfoFacadeService.kt | 2 + .../pipeline/PipelineSettingFacadeService.kt | 11 +-- .../service/template/TemplateFacadeService.kt | 2 + .../transfer/PipelineTransferYamlService.kt | 93 ++++++++++--------- 15 files changed, 112 insertions(+), 90 deletions(-) diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt index 8c6eb111623..fa606ab6793 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt @@ -37,6 +37,8 @@ data class PipelineModelAndYaml( val yaml: String?, @ApiModelProperty("版本变更说明", required = false) val description: String? = null, - @ApiModelProperty("保存草稿时的来源版本", required = false) - val baseVersion: String? = null + @ApiModelProperty("草稿的来源版本", required = false) + val baseVersion: Int, + @ApiModelProperty("草稿的来源版本名称", required = false) + val baseVersionName: String? ) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt index 4b45c5edbab..50e399b1047 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt @@ -267,6 +267,7 @@ interface UserPipelineResource { includeDraft: Boolean? = false ): Result + // TODO 当前版本(草稿分开给)、是否为实例化、取掉setting model @ApiOperation("获取流水线编排和设置") @GET @Path("/projects/{projectId}/pipelines/{pipelineId}/resource") diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index cf9082bc93f..830731e3589 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -148,6 +148,7 @@ interface UserPipelineVersionResource { pageSize: Int? ): Result> + // TODO 增加Version搜索同时查名字,增加指定一个版本放在第一页最后一个 @ApiOperation("流水线编排版本列表(搜索、分页)") @GET @Path("/projects/{projectId}/pipelines/{pipelineId}/versions") diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index 89ce2ab5984..464498ac8c8 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -99,6 +99,7 @@ import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_QUEUE_SIZE_MIN import com.tencent.devops.process.utils.PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_MAX import com.tencent.devops.process.utils.PIPELINE_SETTING_WAIT_QUEUE_TIME_MINUTE_MIN import com.tencent.devops.process.utils.PIPELINE_START_USER_NAME +import com.tencent.devops.process.utils.PipelineVersionUtils import com.tencent.devops.project.api.service.ServiceAllocIdResource import com.tencent.devops.project.api.service.ServiceProjectResource import org.joda.time.LocalDateTime @@ -149,15 +150,6 @@ class PipelineRepositoryService constructor( private const val MAX_LEN_FOR_NAME = 255 private val logger = LoggerFactory.getLogger(PipelineRepositoryService::class.java) private const val PIPELINE_SETTING_VERSION_BIZ_TAG_NAME = "PIPELINE_SETTING_VERSION" - private fun getVersionName( - pipelineVersion: Int?, - triggerVersion: Int?, - settingVersion: Int? - ): String { - return if (pipelineVersion == null || triggerVersion == null || settingVersion == null) { - "init" - } else "P$pipelineVersion.T$triggerVersion.$settingVersion" - } @Suppress("ALL") fun PipelineSetting.checkParam() { @@ -714,7 +706,9 @@ class PipelineRepositoryService constructor( } } // 如果不是草稿保存,最新版本永远是新增逻辑 - versionName = getVersionName(pipelineVersion, triggerVersion, settingVersion) + versionName = PipelineVersionUtils.getVersionName( + pipelineVersion, triggerVersion, settingVersion + ) if (saveDraft != true) pipelineResDao.create( dslContext = transactionContext, projectId = projectId, @@ -846,16 +840,16 @@ class PipelineRepositoryService constructor( logger.error("parse process($pipelineId) model fail", ignored) null } ?: return@let - watcher.start("getModelJsonObject") - val originTriggerJson = JSONObject(originModel.stages.first()) - val originPipelineJson = JSONObject(originModel.stages.slice(1 until originModel.stages.size)) - val triggerJson = JSONObject(model.stages.first()) - val pipelineJson = JSONObject(model.stages.slice(1 until model.stages.size)) - watcher.start("getSimilarResult") - if (!originTriggerJson.similar(triggerJson)) triggerVersion++ - if (!originPipelineJson.similar(pipelineJson)) pipelineVersion++ + pipelineVersion = PipelineVersionUtils.getPipelineVersion( + pipelineVersion, originModel, model + ) + triggerVersion = PipelineVersionUtils.getTriggerVersion( + pipelineVersion, originModel, model + ) } - versionName = getVersionName(pipelineVersion, triggerVersion, settingVersion) + versionName = PipelineVersionUtils.getVersionName( + pipelineVersion, triggerVersion, settingVersion + ) watcher.start("updatePipelineResource") if (saveDraft != true) pipelineResDao.create( dslContext = transactionContext, diff --git a/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/ContainerControl.kt b/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/ContainerControl.kt index 4a1d27714d4..22029930917 100644 --- a/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/ContainerControl.kt +++ b/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/ContainerControl.kt @@ -126,6 +126,7 @@ class ContainerControl @Autowired constructor( projectId = container.projectId ) container.execute(watcher, fixEvent) + watcher.start("finish") } finally { containerIdLock.unlock() watcher.stop() diff --git a/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/StageControl.kt b/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/StageControl.kt index 0ba126f1f3c..b802422f9a8 100644 --- a/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/StageControl.kt +++ b/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/StageControl.kt @@ -98,6 +98,7 @@ class StageControl @Autowired constructor( stageIdLock.lock() watcher.start("execute") execute(watcher = watcher) + watcher.start("finish") } finally { stageIdLock.unlock() watcher.stop() diff --git a/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/TaskControl.kt b/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/TaskControl.kt index 3375a642920..d9445f72e0b 100644 --- a/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/TaskControl.kt +++ b/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/TaskControl.kt @@ -85,6 +85,7 @@ class TaskControl @Autowired constructor( containerIdLock.lock() watcher.start("execute") execute() + watcher.start("finish") } finally { containerIdLock.unlock() watcher.stop() diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt index 5a106eb1fc7..f954fd8a765 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt @@ -134,6 +134,7 @@ class ServicePipelineResourceImpl @Autowired constructor( projectId = projectId, pipelineId = pipelineId, model = pipeline, + yaml = null, channelCode = channelCode, checkPermission = ChannelCode.isNeedAuth(channelCode), updateLastModifyUser = updateLastModifyUser diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt index e1ebf152c56..24e97f6f84b 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt @@ -75,6 +75,7 @@ class ServicePipelineVersionResourceImpl @Autowired constructor( projectId = projectId, pipelineId = pipelineId, model = model, + yaml = null, channelCode = ChannelCode.BS, checkPermission = true, checkTemplate = true, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index a4791c9a756..19a58a8c6d4 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -244,6 +244,7 @@ class UserPipelineResourceImpl @Autowired constructor( projectId = projectId, pipelineId = pipelineId, model = pipeline, + yaml = null, saveDraft = saveDraft, channelCode = ChannelCode.BS ) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index 780109b3eff..4d80f9c0147 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -48,7 +48,6 @@ import com.tencent.devops.process.engine.service.PipelineVersionFacadeService import com.tencent.devops.process.permission.PipelinePermissionService import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.audit.Audit -import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.constant.ProcessMessageCode import com.tencent.devops.process.engine.service.PipelineRepositoryService import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult @@ -161,7 +160,9 @@ class UserPipelineVersionResourceImpl @Autowired constructor( PipelineModelAndYaml( modelAndSetting = modelAndSetting, yaml = yaml, - description = resource.description + description = resource.description, + baseVersion = resource.version, + baseVersionName = resource.versionName ) ) } @@ -218,28 +219,43 @@ class UserPipelineVersionResourceImpl @Autowired constructor( ) ) ) - // TODO 增加yaml处理和保存 -// val model = try { -// transferService.transfer( -// userId = userId, -// projectId = projectId, -// pipelineId = pipelineId, -// actionType = TransferActionType.FULL_YAML2MODEL, -// data = TransferBody( -// -// ) -// ) -// } + val baseVersion = pipelineRepositoryService.getPipelineResourceVersion( + projectId = projectId, + pipelineId = pipelineId, + version = modelAndYaml.baseVersion, + includeDraft = true + ) + val transferResult = transferService.transfer( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + actionType = TransferActionType.FULL_YAML2MODEL, + data = TransferBody( + modelAndSetting = modelAndYaml.modelAndSetting, + oldYaml = baseVersion?.yaml ?: "" + ) + ) + val savedSetting = pipelineSettingFacadeService.saveSetting( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + setting = transferResult.modelAndSetting?.setting ?: modelAndYaml.modelAndSetting.setting, + checkPermission = false, + dispatchPipelineUpdateEvent = false, + saveDraft = true + ) val pipelineResult = pipelineInfoFacadeService.editPipeline( userId = userId, projectId = projectId, pipelineId = pipelineId, - model = modelAndYaml.modelAndSetting.model, + model = transferResult.modelAndSetting?.model ?: modelAndYaml.modelAndSetting.model, channelCode = ChannelCode.BS, checkPermission = false, checkTemplate = false, saveDraft = true, - description = modelAndYaml.description + description = modelAndYaml.description, + yaml = transferResult.newYaml, + savedSetting = savedSetting ) auditService.createAudit( Audit( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index b5a746996f8..cc6e8124b19 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -668,6 +668,7 @@ class PipelineInfoFacadeService @Autowired constructor( projectId: String, pipelineId: String, model: Model, + yaml: String?, channelCode: ChannelCode, checkPermission: Boolean = true, checkTemplate: Boolean = true, @@ -834,6 +835,7 @@ class PipelineInfoFacadeService @Autowired constructor( projectId = projectId, pipelineId = pipelineId, model = model, + yaml = null, channelCode = channelCode, checkPermission = checkPermission, checkTemplate = checkTemplate, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt index f1d438bcadd..49afcbd90fd 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt @@ -62,6 +62,7 @@ import com.tencent.devops.process.pojo.setting.UpdatePipelineModelRequest import com.tencent.devops.process.service.PipelineSettingVersionService import com.tencent.devops.process.service.label.PipelineGroupService import com.tencent.devops.process.service.view.PipelineViewGroupService +import com.tencent.devops.process.utils.PipelineVersionUtils import org.json.JSONObject import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired @@ -123,16 +124,8 @@ class PipelineSettingFacadeService @Autowired constructor( projectId = projectId, pipelineId = pipelineId )?.let { origin -> - logger.info("[$projectId]|$pipelineId|saveSetting|origin=\n\n$origin\n\nsetting=\n\n$setting") - val originJson = JSONObject(origin) - val currentJson = JSONObject(setting) - if (currentJson.similar(originJson)) { - origin.version - } else { - origin.version + 1 - } + PipelineVersionUtils.getSettingVersion(setting.version, setting, origin) } ?: 1 - logger.info("[$projectId]|$pipelineId|saveSetting|settingVersion=$settingVersion|") val pipelineName = pipelineRepositoryService.saveSetting( userId = userId, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt index 9557cb9b768..60aa0caf940 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt @@ -1494,6 +1494,8 @@ class TemplateFacadeService @Autowired constructor( projectId = projectId, pipelineId = templateInstanceUpdate.pipelineId, model = instanceModel, + // TODO #9145 修改流水线实例时的yaml覆盖逻辑 + yaml = null, channelCode = ChannelCode.BS, checkPermission = true, checkTemplate = false diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt index e369610ecc8..4e2f346898f 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt @@ -86,54 +86,59 @@ class PipelineTransferYamlService @Autowired constructor( actionType: TransferActionType, data: TransferBody ): TransferResponse { - val watcher = Watcher(id = "yaml and model transfer watcher") - when (actionType) { - TransferActionType.FULL_MODEL2YAML -> { - watcher.start("step_1|FULL_MODEL2YAML start") - val yml = modelTransfer.model2yaml( - ModelTransferInput( - data.modelAndSetting.model, - data.modelAndSetting.setting, - YamlVersion.Version.V3_0 - ) - ) - watcher.start("step_2|mergeYaml") - val newYaml = TransferMapper.mergeYaml(data.oldYaml, TransferMapper.toYaml(yml)) - watcher.stop() - logger.info(watcher.toString()) - return TransferResponse(newYaml = newYaml) - } - TransferActionType.FULL_YAML2MODEL -> { - watcher.start("step_1|FULL_YAML2MODEL start") - val pipelineInfo = pipelineRepositoryService.getPipelineInfo(projectId, pipelineId) - val pYml = TransferMapper.getObjectMapper() - .readValue(data.oldYaml, object : TypeReference() {}) - watcher.start("step_2|parse template") - pYml.replaceTemplate { templateFilter -> - YamlTemplate( - yamlObject = templateFilter, - filePath = TemplatePath(TEMPLATE_ROOT_FILE), - extraParameters = this, - getTemplateMethod = ::getTemplate, - nowRepo = null, - repo = null, - resourcePoolMapExt = null, - conf = YamlTemplateConf( - useOldParametersExpression = false // todo + try { + when (actionType) { + TransferActionType.FULL_MODEL2YAML -> { + watcher.start("step_1|FULL_MODEL2YAML start") + val yml = modelTransfer.model2yaml( + ModelTransferInput( + data.modelAndSetting.model, + data.modelAndSetting.setting, + YamlVersion.Version.V3_0 ) - ).replace() + ) + watcher.start("step_2|mergeYaml") + val newYaml = TransferMapper.mergeYaml(data.oldYaml, TransferMapper.toYaml(yml)) + watcher.stop() + logger.info(watcher.toString()) + return TransferResponse(newYaml = newYaml) + } + TransferActionType.FULL_YAML2MODEL -> { + watcher.start("step_1|FULL_YAML2MODEL start") + val pipelineInfo = pipelineRepositoryService.getPipelineInfo(projectId, pipelineId) + val pYml = TransferMapper.getObjectMapper() + .readValue(data.oldYaml, object : TypeReference() {}) + watcher.start("step_2|parse template") + pYml.replaceTemplate { templateFilter -> + YamlTemplate( + yamlObject = templateFilter, + filePath = TemplatePath(TEMPLATE_ROOT_FILE), + extraParameters = this, + getTemplateMethod = ::getTemplate, + nowRepo = null, + repo = null, + resourcePoolMapExt = null, + conf = YamlTemplateConf( + useOldParametersExpression = false // todo + ) + ).replace() + } + watcher.start("step_3|transfer start") + val input = YamlTransferInput( + userId, projectId, pipelineInfo, pYml + ) + val model = modelTransfer.yaml2Model(input) + val setting = modelTransfer.yaml2Setting(input) + + logger.info(watcher.toString()) + return TransferResponse(modelAndSetting = PipelineModelAndSetting(model, setting)) } - watcher.start("step_3|transfer start") - val input = YamlTransferInput( - userId, projectId, pipelineInfo, pYml - ) - val model = modelTransfer.yaml2Model(input) - val setting = modelTransfer.yaml2Setting(input) - watcher.stop() - logger.info(watcher.toString()) - return TransferResponse(modelAndSetting = PipelineModelAndSetting(model, setting)) } + } catch (t: Throwable) { + logger.warn("PAC|TRANSFER|transferAction") + } finally { + watcher.stop() } return TransferResponse() } From bf12b85fffb4a03f39c03d63920d966e769ec088 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 22 Aug 2023 11:28:35 +0800 Subject: [PATCH 077/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E6=8A=BD=E5=8F=96utils=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/utils/PipelineVersionUtils.kt | 84 +++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/utils/PipelineVersionUtils.kt diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/utils/PipelineVersionUtils.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/utils/PipelineVersionUtils.kt new file mode 100644 index 00000000000..859676ee465 --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/utils/PipelineVersionUtils.kt @@ -0,0 +1,84 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.utils + +import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting +import org.json.JSONObject + +object PipelineVersionUtils { + + fun getVersionName( + pipelineVersion: Int?, + triggerVersion: Int?, + settingVersion: Int? + ): String { + return if (pipelineVersion == null || triggerVersion == null || settingVersion == null) { + "init" + } else "P$pipelineVersion.T$triggerVersion.$settingVersion" + } + + /** + * 根据当前版本号[currVersion], 原编排[originModel], 新编排[originModel]差异计算后得到新版本号 + */ + fun getTriggerVersion( + currVersion: Int, + originModel: Model, + newModel: Model + ): Int { + val originTriggerJson = JSONObject(originModel.stages.first()) + val triggerJson = JSONObject(newModel.stages.first()) + return if (!originTriggerJson.similar(triggerJson)) currVersion + 1 else currVersion + } + + /** + * 根据当前版本号[currVersion], 原编排[originModel], 新编排[originModel]差异计算后得到新版本号 + */ + fun getPipelineVersion( + currVersion: Int, + originModel: Model, + newModel: Model + ): Int { + val originPipelineJson = JSONObject(originModel.stages.slice(1 until originModel.stages.size)) + val pipelineJson = JSONObject(newModel.stages.slice(1 until newModel.stages.size)) + return if (!originPipelineJson.similar(pipelineJson)) currVersion + 1 else currVersion + } + + /** + * 根据当前版本号[currVersion], 原设置[originSetting], 新设置[newSetting]差异计算后得到新版本号 + */ + fun getSettingVersion( + currVersion: Int, + originSetting: PipelineSetting, + newSetting: PipelineSetting + ): Int { + val originJson = JSONObject(originSetting) + val currentJson = JSONObject(newSetting) + return if (!originJson.similar(currentJson)) currVersion + 1 else currVersion + } +} From ea9db05777fbbff19a4cb626dc326bf9b0427926 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 22 Aug 2023 16:46:44 +0800 Subject: [PATCH 078/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E4=BC=98=E5=8C=96=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/user/UserPipelineVersionResource.kt | 14 +++-- .../pojo/pipeline/PipelineResourceVersion.kt | 6 ++- .../engine/dao/PipelineResVersionDao.kt | 15 +++++- .../service/PipelineRepositoryService.kt | 1 - .../PipelineRepositoryVersionService.kt | 51 +++++++++++++++++-- .../api/ServicePipelineVersionResourceImpl.kt | 6 ++- .../process/api/UserPipelineResourceImpl.kt | 6 ++- .../api/UserPipelineVersionResourceImpl.kt | 8 ++- .../service/PipelineVersionFacadeService.kt | 31 +++++++---- .../pipeline/PipelineSettingFacadeService.kt | 1 - 10 files changed, 111 insertions(+), 28 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 830731e3589..76f819d102e 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -35,7 +35,6 @@ import com.tencent.devops.common.pipeline.PipelineModelAndYaml import com.tencent.devops.common.pipeline.pojo.TemplateInstanceCreateRequest import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.pojo.PipelineOperationDetail -import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult import com.tencent.devops.process.pojo.transfer.PreviewResponse import io.swagger.annotations.Api @@ -148,7 +147,6 @@ interface UserPipelineVersionResource { pageSize: Int? ): Result> - // TODO 增加Version搜索同时查名字,增加指定一个版本放在第一页最后一个 @ApiOperation("流水线编排版本列表(搜索、分页)") @GET @Path("/projects/{projectId}/pipelines/{pipelineId}/versions") @@ -162,16 +160,22 @@ interface UserPipelineVersionResource { @ApiParam("流水线ID", required = true) @PathParam("pipelineId") pipelineId: String, - @ApiParam("过滤创建人", required = false) + @ApiParam("跳转定位的版本号", required = false) + @QueryParam("fromVersion") + fromVersion: Int? = null, + @ApiParam("搜索字段:版本名包含字符", required = false) + @QueryParam("versionName") + versionName: String? = null, + @ApiParam("搜索字段:创建人", required = false) @QueryParam("creator") creator: String? = null, - @ApiParam("模糊查询变更说明", required = false) + @ApiParam("搜索字段:变更说明", required = false) @QueryParam("description") description: String? = null, @ApiParam("第几页", required = false, defaultValue = "1") @QueryParam("page") page: Int?, - @ApiParam("每页多少条", required = false, defaultValue = "20") + @ApiParam("每页多少条", required = false, defaultValue = "5") @QueryParam("pageSize") pageSize: Int? ): Result> diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt index c2e691ff5b0..2b8084c6f0f 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt @@ -65,5 +65,9 @@ data class PipelineResourceVersion( @ApiModelProperty("草稿版本标识", required = false) val status: VersionStatus? = VersionStatus.RELEASED, @ApiModelProperty("版本变更说明", required = false) - val description: String? = null + val description: String? = null, + @ApiModelProperty("调试构建ID", required = false) + val debugBuildId: String? = null, + @ApiModelProperty("来源代码库标识(分支名)", required = false) + val pacRefs: String? = null ) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt index e19006e1b53..15e4705f163 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt @@ -182,7 +182,9 @@ class PipelineResVersionDao { referFlag = record.referFlag, referCount = record.referCount, status = record.status?.let { VersionStatus.valueOf(it) }, - description = record.description + description = record.description, + debugBuildId = record.debugBuildId, + pacRefs = record.refs ) } } @@ -220,7 +222,9 @@ class PipelineResVersionDao { pipelineId: String, offset: Int, limit: Int, + excludeVersion: Int?, creator: String?, + versionName: String?, description: String? ): List { val list = mutableListOf() @@ -229,6 +233,15 @@ class PipelineResVersionDao { .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) creator?.let { query.and(CREATOR.eq(creator)) } description?.let { query.and(DESCRIPTION.like("%$description%")) } + versionName?.let { + query.and( + VERSION.like("%$versionName%") + .or(VERSION_NAME.like("%$versionName%")) + ) + } + excludeVersion?.let { + query.and(VERSION.notEqual(excludeVersion)) + } val result = query .orderBy(VERSION.desc()).limit(limit).offset(offset).fetch() result.forEach { record -> diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index 464498ac8c8..9c263f46afb 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -105,7 +105,6 @@ import com.tencent.devops.project.api.service.ServiceProjectResource import org.joda.time.LocalDateTime import org.jooq.DSLContext import org.jooq.impl.DSL -import org.json.JSONObject import org.slf4j.LoggerFactory import org.springframework.stereotype.Service import java.util.concurrent.atomic.AtomicInteger diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt index 7d471f8e06f..4cfde5b2ff0 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt @@ -41,7 +41,7 @@ import org.jooq.impl.DSL import org.springframework.stereotype.Service @Service -@Suppress("LongParameterList") +@Suppress("LongParameterList", "ReturnCount") class PipelineRepositoryVersionService( private val dslContext: DSLContext, private val pipelineResVersionDao: PipelineResVersionDao, @@ -108,17 +108,60 @@ class PipelineRepositoryVersionService( } } + fun getPipelineVersion( + pipelineInfo: PipelineInfo?, + projectId: String, + pipelineId: String, + version: Int + ): PipelineResVersion? { + if (pipelineInfo == null) { + return null + } + val resource = pipelineResVersionDao.getVersionResource( + dslContext = dslContext, + projectId = projectId, + pipelineId = pipelineId, + version = version, + includeDraft = true + ) ?: return null + return PipelineResVersion( + createTime = pipelineInfo.createTime, + creator = pipelineInfo.creator, + canElementSkip = pipelineInfo.canElementSkip, + canManualStartup = pipelineInfo.canManualStartup, + channelCode = pipelineInfo.channelCode, + id = pipelineInfo.id, + lastModifyUser = pipelineInfo.lastModifyUser, + pipelineDesc = pipelineInfo.pipelineDesc, + pipelineId = pipelineInfo.pipelineId, + pipelineName = pipelineInfo.pipelineName, + projectId = pipelineInfo.projectId, + taskCount = pipelineInfo.taskCount, + templateId = pipelineInfo.templateId, + version = resource.version, + versionName = resource.versionName ?: "init", + pipelineVersion = resource.pipelineVersion, + triggerVersion = resource.triggerVersion, + settingVersion = resource.settingVersion, + status = resource.status, + debugBuildId = resource.debugBuildId, + pacRefs = resource.pacRefs + ) + } + fun listPipelineVersion( pipelineInfo: PipelineInfo?, projectId: String, pipelineId: String, offset: Int, limit: Int, + excludeVersion: Int?, + versionName: String?, creator: String?, description: String? - ): Pair> { + ): Pair> { if (pipelineInfo == null) { - return Pair(0, emptyList()) + return Pair(0, mutableListOf()) } val count = pipelineResVersionDao.count( @@ -134,6 +177,8 @@ class PipelineRepositoryVersionService( pipelineId = pipelineId, creator = creator, description = description, + versionName = versionName, + excludeVersion = excludeVersion, offset = offset, limit = limit ) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt index 24e97f6f84b..859e96e2d5b 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt @@ -200,8 +200,10 @@ class ServicePipelineVersionResourceImpl @Autowired constructor( pipelineId = pipelineId, creator = creator?.takeIf { it.isNotBlank() }, description = description?.takeIf { it.isNotBlank() }, - page = page, - pageSize = pageSize + fromVersion = null, + versionName = null, + page = page ?: 1, + pageSize = pageSize ?: 20 ) ) } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index 19a58a8c6d4..a4b07dd7558 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -721,8 +721,10 @@ class UserPipelineResourceImpl @Autowired constructor( pipelineVersionFacadeService.listPipelineVersion( projectId = projectId, pipelineId = pipelineId, - page = page, - pageSize = pageSize + fromVersion = null, + versionName = null, + page = page ?: 1, + pageSize = pageSize ?: 20 ) ) } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index 4d80f9c0147..dab3fe45bbd 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -309,6 +309,8 @@ class UserPipelineVersionResourceImpl @Autowired constructor( userId: String, projectId: String, pipelineId: String, + fromVersion: Int?, + versionName: String?, creator: String?, description: String?, page: Int?, @@ -336,10 +338,12 @@ class UserPipelineVersionResourceImpl @Autowired constructor( pipelineVersionFacadeService.listPipelineVersion( projectId = projectId, pipelineId = pipelineId, + fromVersion = fromVersion, + versionName = versionName, creator = creator?.takeIf { it.isNotBlank() }, description = description?.takeIf { it.isNotBlank() }, - page = page, - pageSize = pageSize + page = page ?: 1, + pageSize = pageSize ?: 5 ) ) } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt index b3c0d20c440..e88b6138f16 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt @@ -86,33 +86,44 @@ class PipelineVersionFacadeService @Autowired constructor( fun listPipelineVersion( projectId: String, pipelineId: String, - page: Int?, - pageSize: Int?, + page: Int, + pageSize: Int, + fromVersion: Int?, + versionName: String?, creator: String? = null, description: String? = null ): Page { - val pageNotNull = page ?: 0 - val pageSizeNotNull = pageSize ?: -1 var slqLimit: SQLLimit? = null - if (pageSizeNotNull != -1) slqLimit = PageUtil.convertPageSizeToSQLLimit(pageNotNull, pageSizeNotNull) + if (pageSize != -1) slqLimit = PageUtil.convertPageSizeToSQLLimit(page, pageSize) val offset = slqLimit?.offset ?: 0 - val limit = slqLimit?.limit ?: -1 - // 数据量不多,直接全拉 + var limit = slqLimit?.limit ?: -1 val pipelineInfo = pipelineRepositoryService.getPipelineInfo(projectId, pipelineId) + // 如果有要插队的版本需要提到第一页,则在查询list时排除,单独查出来放在第一页 + val fromResource = if (fromVersion != null && page == 1) { + limit -= 1 + pipelineRepositoryVersionService.getPipelineVersion( + pipelineInfo = pipelineInfo, + projectId = projectId, + pipelineId = pipelineId, + version = fromVersion + ) + } else null val (size, pipelines) = pipelineRepositoryVersionService.listPipelineVersion( pipelineInfo = pipelineInfo, projectId = projectId, pipelineId = pipelineId, creator = creator, description = description, + versionName = versionName, + excludeVersion = fromVersion, offset = offset, limit = limit ) - + fromResource?.let { pipelines.add(it) } return Page( - page = pageNotNull, - pageSize = pageSizeNotNull, + page = page, + pageSize = pageSize, count = size.toLong(), records = pipelines ) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt index 49afcbd90fd..bb16bbb847c 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt @@ -63,7 +63,6 @@ import com.tencent.devops.process.service.PipelineSettingVersionService import com.tencent.devops.process.service.label.PipelineGroupService import com.tencent.devops.process.service.view.PipelineViewGroupService import com.tencent.devops.process.utils.PipelineVersionUtils -import org.json.JSONObject import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service From 63670439e7e753ce78c06ff8d9fa8788b9c8913a Mon Sep 17 00:00:00 2001 From: yongyiduan Date: Tue, 22 Aug 2023 17:34:24 +0800 Subject: [PATCH 079/852] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=BB=BA/?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=BB=A5=20Code=20=E6=96=B9=E5=BC=8F=E7=BC=96=E6=8E=92?= =?UTF-8?q?=E6=B5=81=E6=B0=B4=E7=BA=BF=20#8125=20core?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/common/api/enums/ScmType.kt | 21 +- .../common-pipeline-yaml/build.gradle.kts | 1 + .../yaml/modelCreate/ModelContainer.kt | 12 +- .../process/yaml/modelCreate/ModelElement.kt | 2 +- .../yaml/modelTransfer/ContainerTransfer.kt | 353 ++++++++++++++++++ .../yaml/modelTransfer/DispatchTransfer.kt | 223 +++++++++++ .../yaml/modelTransfer/ElementTransfer.kt | 40 +- .../yaml/modelTransfer/ModelTransfer.kt | 195 +++++----- .../yaml/modelTransfer/StageTransfer.kt | 11 +- .../modelTransfer/TransferCacheService.kt | 39 +- .../yaml/modelTransfer/TransferMapper.kt | 7 + .../yaml/modelTransfer/TriggerTransfer.kt | 4 +- .../yaml/modelTransfer/VariableDefault.kt | 17 + ...sferModelCreator.kt => TransferCreator.kt} | 2 +- ...lCreatorImpl.kt => TransferCreatorImpl.kt} | 6 +- .../yaml/pojo/ThirdPartyContainerInfo.kt | 4 +- .../process/yaml/utils/StreamDispatchUtils.kt | 6 +- .../devops/process/yaml/v2/models/Notices.kt | 147 +++++++- .../yaml/v2/models/PreScriptBuildYaml.kt | 3 +- .../v2/models/PreTemplateScriptBuildYaml.kt | 4 +- .../process/yaml/v2/models/image/Pool.kt | 19 +- .../process/yaml/v2/models/image/PoolType.kt | 106 +++++- .../devops/process/yaml/v2/models/job/Job.kt | 43 ++- .../yaml/v2/models/stage/StageLabel.kt | 9 + .../yaml/v2/parsers/template/YamlObjects.kt | 42 ++- .../yaml/v2/parsers/template/YamlTemplate.kt | 29 +- .../yaml/v3/models/PreScriptBuildYamlV3.kt | 4 +- .../v3/models/PreTemplateScriptBuildYamlV3.kt | 26 +- .../yaml/v3/models/on/PreTriggerOnV3.kt | 3 +- .../process/pojo/classify/PipelineGroup.kt | 4 +- .../trigger/pojo/ManualPreScriptBuildYaml.kt | 2 +- 31 files changed, 1191 insertions(+), 193 deletions(-) create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ContainerTransfer.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/DispatchTransfer.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/VariableDefault.kt rename src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/{TransferModelCreator.kt => TransferCreator.kt} (98%) rename src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/{TransferModelCreatorImpl.kt => TransferCreatorImpl.kt} (96%) diff --git a/src/backend/ci/core/common/common-api/src/main/kotlin/com/tencent/devops/common/api/enums/ScmType.kt b/src/backend/ci/core/common/common-api/src/main/kotlin/com/tencent/devops/common/api/enums/ScmType.kt index 6ed2ff1b2af..0fc4722606f 100644 --- a/src/backend/ci/core/common/common-api/src/main/kotlin/com/tencent/devops/common/api/enums/ScmType.kt +++ b/src/backend/ci/core/common/common-api/src/main/kotlin/com/tencent/devops/common/api/enums/ScmType.kt @@ -27,13 +27,13 @@ package com.tencent.devops.common.api.enums -enum class ScmType { - CODE_SVN, - CODE_GIT, - CODE_GITLAB, - GITHUB, - CODE_TGIT, - CODE_P4 +enum class ScmType(val alis: String) { + CODE_SVN("svn"), + CODE_GIT("git"), + CODE_GITLAB("gitlab"), + GITHUB("github"), + CODE_TGIT("tgit"), + CODE_P4("p4") ; companion object { @@ -47,5 +47,12 @@ enum class ScmType { CODE_P4 -> 6.toShort() } } + + fun parse(alis: String?): ScmType? { + values().forEach { + if (alis == it.alis) return it + } + return null + } } } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/build.gradle.kts b/src/backend/ci/core/common/common-pipeline-yaml/build.gradle.kts index 06015021c87..fbbdb720f15 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/build.gradle.kts +++ b/src/backend/ci/core/common/common-pipeline-yaml/build.gradle.kts @@ -29,6 +29,7 @@ dependencies { api(project(":core:common:common-webhook:biz-common-webhook")) api(project(":core:common:common-expression")) api(project(":core:store:api-store")) + api(project(":core:auth:api-auth")) api(project(":core:quality:api-quality")) api("org.apache.ant:ant") diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelContainer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelContainer.kt index 13417ee2bf8..81290ef492e 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelContainer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelContainer.kt @@ -56,6 +56,8 @@ import com.tencent.devops.process.constant.ProcessMessageCode import com.tencent.devops.process.pojo.BuildTemplateAcrossInfo import com.tencent.devops.process.yaml.modelCreate.inner.InnerModelCreator import com.tencent.devops.process.yaml.modelTransfer.TransferCacheService +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault import com.tencent.devops.process.yaml.pojo.StreamDispatchInfo import com.tencent.devops.process.yaml.utils.ModelCreateUtil import com.tencent.devops.process.yaml.utils.StreamDispatchUtils @@ -315,9 +317,10 @@ class ModelContainer @Autowired(required = false) constructor( else -> null }, steps = steps, - timeoutMinutes = job.jobControlOption?.timeout, + timeoutMinutes = job.jobControlOption?.timeout.nullIfDefault(VariableDefault.DEFAULT_JOB_TIME_OUT), env = null, - continueOnError = if (job.jobControlOption?.continueWhenFailed == true) true else null, + continueOnError = job.jobControlOption?.continueWhenFailed + .nullIfDefault(VariableDefault.DEFAULT_CONTINUE_WHEN_FAILED), strategy = if (job.matrixGroupFlag == true) { getMatrixFromJob(job.matrixControlOption) } else null, @@ -348,9 +351,10 @@ class ModelContainer @Autowired(required = false) constructor( else -> null }, steps = steps, - timeoutMinutes = job.jobControlOption?.timeout, + timeoutMinutes = job.jobControlOption?.timeout.nullIfDefault(VariableDefault.DEFAULT_JOB_TIME_OUT), env = null, - continueOnError = if (job.jobControlOption?.continueWhenFailed == true) true else null, + continueOnError = job.jobControlOption?.continueWhenFailed + .nullIfDefault(VariableDefault.DEFAULT_CONTINUE_WHEN_FAILED), strategy = if (job.matrixGroupFlag == true) { getMatrixFromJob(job.matrixControlOption) } else null, diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelElement.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelElement.kt index d23c678b888..bcf8ff925d1 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelElement.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelElement.kt @@ -170,7 +170,7 @@ class ModelElement @Autowired(required = false) constructor( if (job.runsOn.agentSelector.isNullOrEmpty()) { linux } else { - when (job.runsOn.agentSelector.first()) { + when (job.runsOn.agentSelector!!.first()) { "linux" -> linux "macos" -> linux "windows" -> WindowsScriptElement( diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ContainerTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ContainerTransfer.kt new file mode 100644 index 00000000000..60ab994707b --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ContainerTransfer.kt @@ -0,0 +1,353 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.modelTransfer + +import com.fasterxml.jackson.databind.ObjectMapper +import com.tencent.devops.common.api.util.YamlUtil +import com.tencent.devops.common.client.Client +import com.tencent.devops.common.pipeline.container.Container +import com.tencent.devops.common.pipeline.container.MutexGroup +import com.tencent.devops.common.pipeline.container.NormalContainer +import com.tencent.devops.common.pipeline.container.VMBuildContainer +import com.tencent.devops.common.pipeline.enums.DependOnType +import com.tencent.devops.common.pipeline.enums.JobRunCondition +import com.tencent.devops.common.pipeline.enums.VMBaseOS +import com.tencent.devops.common.pipeline.option.JobControlOption +import com.tencent.devops.common.pipeline.option.MatrixControlOption +import com.tencent.devops.common.pipeline.pojo.element.Element +import com.tencent.devops.process.pojo.BuildTemplateAcrossInfo +import com.tencent.devops.process.yaml.modelCreate.ModelCommon +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_CONTINUE_WHEN_FAILED +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_JOB_MAX_QUEUE_MINUTES +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_JOB_MAX_RUNNING_MINUTES +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_JOB_TIME_OUT +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_MUTEX_QUEUE_ENABLE +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_MUTEX_QUEUE_LENGTH +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_MUTEX_TIMEOUT_MINUTES +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault +import com.tencent.devops.process.yaml.utils.ModelCreateUtil +import com.tencent.devops.process.yaml.v2.models.IfType +import com.tencent.devops.process.yaml.v2.models.Resources +import com.tencent.devops.process.yaml.v2.models.job.Job +import com.tencent.devops.process.yaml.v2.models.job.JobRunsOnType +import com.tencent.devops.process.yaml.v2.models.job.Mutex +import com.tencent.devops.process.yaml.v2.models.job.PreJob +import com.tencent.devops.process.yaml.v2.models.job.RunsOn +import com.tencent.devops.process.yaml.v2.models.job.Strategy +import com.tencent.devops.process.yaml.v2.models.step.PreStep +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component + +@Component +class ContainerTransfer @Autowired(required = false) constructor( + val client: Client, + val objectMapper: ObjectMapper, + val transferCache: TransferCacheService, + val dispatchTransfer: DispatchTransfer +) { + + fun addVmBuildContainer( + job: Job, + elementList: List, + containerList: MutableList, + jobIndex: Int, + projectCode: String, + finalStage: Boolean = false, + jobEnable: Boolean = true, + resources: Resources? = null, + buildTemplateAcrossInfo: BuildTemplateAcrossInfo? + ) { + val vmContainer = VMBuildContainer( + jobId = job.id, + name = job.name ?: "Job-${jobIndex + 1}", + elements = elementList, + mutexGroup = getMutexModel(job.mutex), + baseOS = getBaseOs(job), + vmNames = setOf(), + maxQueueMinutes = DEFAULT_JOB_MAX_QUEUE_MINUTES, + maxRunningMinutes = job.timeoutMinutes ?: DEFAULT_JOB_MAX_RUNNING_MINUTES, + buildEnv = if (job.runsOn.selfHosted == false) job.runsOn.needs else null, + customBuildEnv = job.env, + jobControlOption = getJobControlOption( + job = job, jobEnable = jobEnable, finalStage = finalStage + ), + dispatchType = dispatchTransfer.makeDispatchType( + job = job, + buildTemplateAcrossInfo = buildTemplateAcrossInfo + ), + matrixGroupFlag = job.strategy != null, + matrixControlOption = getMatrixControlOption(job) + ) + containerList.add(vmContainer) + } + + fun addNormalContainer( + job: Job, + elementList: List, + containerList: MutableList, + jobIndex: Int, + jobEnable: Boolean = true, + finalStage: Boolean = false + ) { + + containerList.add( + NormalContainer( + jobId = job.id, + id = job.id, + name = job.name ?: "Job-${jobIndex + 1}", + elements = elementList, + jobControlOption = getJobControlOption( + job = job, jobEnable = jobEnable, finalStage = finalStage + ), + mutexGroup = getMutexModel(job.mutex), + matrixGroupFlag = job.strategy != null, + matrixControlOption = getMatrixControlOption(job) + ) + ) + } + + fun addYamlNormalContainer( + job: NormalContainer, + steps: List? + ): PreJob { + return PreJob( + name = job.name, + runsOn = RunsOn( + selfHosted = null, + poolName = JobRunsOnType.AGENT_LESS.type + ), + mutex = getMutexYaml(job.mutexGroup), + container = null, + ifField = when (job.jobControlOption?.runCondition) { + JobRunCondition.CUSTOM_CONDITION_MATCH -> job.jobControlOption?.customCondition + JobRunCondition.CUSTOM_VARIABLE_MATCH -> ModelCommon.customVariableMatch( + job.jobControlOption?.customVariables + ) + JobRunCondition.CUSTOM_VARIABLE_MATCH_NOT_RUN -> ModelCommon.customVariableMatchNotRun( + job.jobControlOption?.customVariables + ) + else -> null + }, + steps = steps, + timeoutMinutes = job.jobControlOption?.timeout.nullIfDefault(DEFAULT_JOB_TIME_OUT), + env = null, + continueOnError = job.jobControlOption?.continueWhenFailed.nullIfDefault(DEFAULT_CONTINUE_WHEN_FAILED), + strategy = if (job.matrixGroupFlag == true) { + getMatrixFromJob(job.matrixControlOption) + } else null, + // 蓝盾这边是自定义Job ID + dependOn = if (!job.jobControlOption?.dependOnId.isNullOrEmpty()) { + job.jobControlOption?.dependOnId + } else null + ) + } + + fun addYamlVMBuildContainer( + job: VMBuildContainer, + steps: List? + ): PreJob { + return PreJob( + name = job.name, + runsOn = dispatchTransfer.makeRunsOn(job), + container = null, + services = null, + mutex = getMutexYaml(job.mutexGroup), + ifField = when (job.jobControlOption?.runCondition) { + JobRunCondition.CUSTOM_CONDITION_MATCH -> job.jobControlOption?.customCondition + JobRunCondition.CUSTOM_VARIABLE_MATCH -> ModelCommon.customVariableMatch( + job.jobControlOption?.customVariables + ) + JobRunCondition.CUSTOM_VARIABLE_MATCH_NOT_RUN -> ModelCommon.customVariableMatchNotRun( + job.jobControlOption?.customVariables + ) + else -> null + }, + steps = steps, + timeoutMinutes = job.jobControlOption?.timeout.nullIfDefault(DEFAULT_JOB_TIME_OUT), + env = null, + continueOnError = job.jobControlOption?.continueWhenFailed.nullIfDefault(DEFAULT_CONTINUE_WHEN_FAILED), + strategy = if (job.matrixGroupFlag == true) { + getMatrixFromJob(job.matrixControlOption) + } else null, + dependOn = if (!job.jobControlOption?.dependOnId.isNullOrEmpty()) { + job.jobControlOption?.dependOnId + } else null + ) + } + + @Suppress("UNCHECKED_CAST") + private fun getMatrixControlOption(job: Job): MatrixControlOption? { + + val strategy = job.strategy ?: return null + + with(strategy) { + if (matrix is Map<*, *>) { + val yaml = matrix as MutableMap + val include = if ("include" in yaml.keys && yaml["include"] != null) { + YamlUtil.toYaml(yaml["include"]!!) + } else { + null + } + val exclude = if ("exclude" in yaml.keys && yaml["exclude"] != null) { + YamlUtil.toYaml(yaml["exclude"]!!) + } else { + null + } + val json = matrix + json.remove("include") + json.remove("exclude") + + return MatrixControlOption( + strategyStr = YamlUtil.toYaml(json), + includeCaseStr = include, + excludeCaseStr = exclude, + fastKill = fastKill, + maxConcurrency = maxParallel + ) + } else { + return MatrixControlOption( + strategyStr = matrix.toString(), + fastKill = fastKill, + maxConcurrency = maxParallel + ) + } + } + } + + private fun getJobControlOption( + job: Job, + jobEnable: Boolean = true, + finalStage: Boolean = false + ): JobControlOption { + val timeout = setUpTimeout(job) + return if (!job.ifField.isNullOrBlank()) { + if (finalStage) { + JobControlOption( + timeout = timeout, + timeoutVar = timeout.toString(), + runCondition = when (job.ifField) { + IfType.SUCCESS.name -> JobRunCondition.PREVIOUS_STAGE_SUCCESS + IfType.FAILURE.name -> JobRunCondition.PREVIOUS_STAGE_FAILED + IfType.CANCELLED.name, IfType.CANCELED.name -> JobRunCondition.PREVIOUS_STAGE_CANCEL + else -> JobRunCondition.STAGE_RUNNING + }, + dependOnType = DependOnType.ID, + dependOnId = job.dependOn, + prepareTimeout = job.runsOn.queueTimeoutMinutes, + continueWhenFailed = job.continueOnError + ) + } else { + JobControlOption( + enable = jobEnable, + timeout = timeout, + timeoutVar = timeout.toString(), + runCondition = JobRunCondition.CUSTOM_CONDITION_MATCH, + customCondition = ModelCreateUtil.removeIfBrackets(job.ifField), + dependOnType = DependOnType.ID, + dependOnId = job.dependOn, + prepareTimeout = job.runsOn.queueTimeoutMinutes, + continueWhenFailed = job.continueOnError + ) + } + } else { + JobControlOption( + enable = jobEnable, + timeout = timeout, + timeoutVar = timeout.toString(), + dependOnType = DependOnType.ID, + dependOnId = job.dependOn, + prepareTimeout = job.runsOn.queueTimeoutMinutes, + continueWhenFailed = job.continueOnError + ) + } + } + + private fun setUpTimeout(job: Job) = (job.timeoutMinutes ?: DEFAULT_JOB_TIME_OUT) + + private fun getMutexModel(resource: Mutex?): MutexGroup? { + if (resource == null) { + return null + } + return MutexGroup( + enable = true, + mutexGroupName = resource.label, + queueEnable = resource.queueEnable ?: DEFAULT_MUTEX_QUEUE_ENABLE, + queue = resource.queueLength ?: DEFAULT_MUTEX_QUEUE_LENGTH, + timeout = resource.timeoutMinutes ?: DEFAULT_MUTEX_TIMEOUT_MINUTES + ) + } + + private fun getMutexYaml(resource: MutexGroup?): Mutex? { + if (resource?.mutexGroupName.isNullOrBlank()) { + return null + } + return Mutex( + label = resource?.mutexGroupName!!, + queueEnable = resource.queueEnable.nullIfDefault(DEFAULT_MUTEX_QUEUE_ENABLE), + queueLength = resource.queue.nullIfDefault(DEFAULT_MUTEX_QUEUE_LENGTH), + timeoutMinutes = resource.timeout.nullIfDefault(DEFAULT_MUTEX_TIMEOUT_MINUTES) + ) + } + + private fun getMatrixFromJob( + matrixControlOption: MatrixControlOption? + ): Strategy? { + if (matrixControlOption == null) { + return null + } + return Strategy( + matrix = matrixControlOption.convertMatrixToYamlConfig() ?: return null, + fastKill = matrixControlOption.fastKill, + maxParallel = matrixControlOption.maxConcurrency + ) + } + + private fun getBaseOs(job: Job): VMBaseOS { + val poolName = job.runsOn.poolName + when { + LINUX_TYPE.contains(poolName) -> return VMBaseOS.LINUX + MACOS_TYPE.contains(poolName) -> return VMBaseOS.MACOS + WINDOWS_TYPE.contains(poolName) -> return VMBaseOS.WINDOWS + } + + val selector = job.runsOn.agentSelector?.get(0) + return when { + selector == null -> VMBaseOS.ALL + LINUX_TYPE.contains(selector) -> VMBaseOS.LINUX + MACOS_TYPE.contains(selector) -> VMBaseOS.MACOS + WINDOWS_TYPE.contains(selector) -> VMBaseOS.WINDOWS + else -> VMBaseOS.LINUX + } + } + + companion object { + val LINUX_TYPE = setOf("docker", "linux") + val MACOS_TYPE = setOf("macos-11.4", "macos-12.4", "macos-latest", "macos") + val WINDOWS_TYPE = setOf("windows-2016", "windows") + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/DispatchTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/DispatchTransfer.kt new file mode 100644 index 00000000000..cb04b6d7ba4 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/DispatchTransfer.kt @@ -0,0 +1,223 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.modelTransfer + +import com.fasterxml.jackson.databind.ObjectMapper +import com.tencent.devops.common.api.constant.CommonMessageCode +import com.tencent.devops.common.api.exception.CustomException +import com.tencent.devops.common.api.util.MessageUtil +import com.tencent.devops.common.client.Client +import com.tencent.devops.common.pipeline.container.VMBuildContainer +import com.tencent.devops.common.pipeline.enums.VMBaseOS +import com.tencent.devops.common.pipeline.type.DispatchType +import com.tencent.devops.common.pipeline.type.agent.Credential +import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentDockerInfo +import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentEnvDispatchType +import com.tencent.devops.common.pipeline.type.docker.ImageType +import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.process.constant.ProcessMessageCode +import com.tencent.devops.process.pojo.BuildTemplateAcrossInfo +import com.tencent.devops.process.yaml.modelTransfer.inner.TransferCreator +import com.tencent.devops.process.yaml.utils.StreamDispatchUtils +import com.tencent.devops.process.yaml.v2.models.image.Pool +import com.tencent.devops.process.yaml.v2.models.image.PoolImage +import com.tencent.devops.process.yaml.v2.models.image.PoolType +import com.tencent.devops.process.yaml.v2.models.job.Container3 +import com.tencent.devops.process.yaml.v2.models.job.Job +import com.tencent.devops.process.yaml.v2.models.job.JobRunsOnPoolType +import com.tencent.devops.process.yaml.v2.models.job.RunsOn +import org.json.JSONObject +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component +import javax.ws.rs.core.Response + +@Component +class DispatchTransfer @Autowired(required = false) constructor( + val client: Client, + val objectMapper: ObjectMapper, + final val inner: TransferCreator, + val transferCache: TransferCacheService +) { + + companion object { + private val logger = LoggerFactory.getLogger(DispatchTransfer::class.java) + } + + private val defaultRunsOn = JSONObject( + RunsOn( + container = Container3( + image = inner.defaultImage, + imageType = ImageType.BKSTORE.name + ) + ) + ) + + fun makeDispatchType( + job: Job, + buildTemplateAcrossInfo: BuildTemplateAcrossInfo? + ): DispatchType { + // 第三方构建机 + dispatcherThirdPartyAgent(job, buildTemplateAcrossInfo)?.let { return it } + // windows构建机 + dispatcherWindows(job)?.let { return it } + // macos构建机 + dispatcherMacos(job)?.let { return it } + // linux构建机 + dispatcherLinux(job, buildTemplateAcrossInfo)?.let { return it } + // 转换失败 + throw CustomException( + Response.Status.NOT_FOUND, + MessageUtil.getMessageByLocale( + messageCode = CommonMessageCode.PUBLIC_BUILD_RESOURCE_POOL_NOT_EXIST, + language = I18nUtil.getLanguage(I18nUtil.getRequestUserId()) + ) + ) + } + + fun dispatcherLinux( + job: Job, + buildTemplateAcrossInfo: BuildTemplateAcrossInfo? + ): DispatchType? { + // 公共docker构建机 + if (job.runsOn.poolName == "docker") { + val info = if (job.runsOn.container != null) { + StreamDispatchUtils.parseRunsOnContainer( + job = job, + buildTemplateAcrossInfo = buildTemplateAcrossInfo + ) + } else null + val image = (info?.image ?: inner.defaultImage).split(":") + return PoolType.DockerOnVm.toDispatchType( + Pool( + credentialId = getDockerInfo(job, buildTemplateAcrossInfo)?.credential?.credentialId, + image = PoolImage( + imageCode = image.getOrElse(0) { "" }, + imageVersion = image.getOrElse(1) { "" }, + imageType = info?.imageType + ) + ) + ) + } + return null + } + + fun dispatcherMacos( + job: Job + ): DispatchType? { + return null + } + + fun dispatcherWindows( + job: Job + ): DispatchType? { + return null + } + + fun dispatcherThirdPartyAgent( + job: Job, + buildTemplateAcrossInfo: BuildTemplateAcrossInfo? + ): DispatchType? { + // 第三方构建机 + if (job.runsOn.selfHosted == true) { + return PoolType.SelfHosted.toDispatchType( + with(job.runsOn) { + Pool( + envName = if (poolType == JobRunsOnPoolType.ENV_NAME.name) poolName else null, + workspace = workspace, + envId = if (poolType == JobRunsOnPoolType.ENV_ID.name) poolName else null, + agentId = if (poolType == JobRunsOnPoolType.AGENT_ID.name) poolName else null, + agentName = if (poolType == JobRunsOnPoolType.AGENT_NAME.name) poolName else null, + dockerInfo = getDockerInfo(job, buildTemplateAcrossInfo) + ) + } + ) + } + return null + } + + private fun getDockerInfo( + job: Job, + buildTemplateAcrossInfo: BuildTemplateAcrossInfo? + ): ThirdPartyAgentDockerInfo? { + return if (job.runsOn.container != null) { + val info = StreamDispatchUtils.parseRunsOnContainer( + job = job, + buildTemplateAcrossInfo = buildTemplateAcrossInfo + ) + ThirdPartyAgentDockerInfo( + image = info.image, + credential = Credential( + user = info.userName, + password = info.password, + credentialId = info.credId, + acrossTemplateId = info.acrossTemplateId, + jobId = job.id + ), + options = info.options, + imagePullPolicy = info.imagePullPolicy + ) + } else null + } + + fun makeRunsOn( + job: VMBuildContainer + ): RunsOn? { + val dispatchType = job.dispatchType + if (dispatchType == null) { + logger.warn("job.dispatchType can not be null") + return null + } + val runsOn = dispatch2RunsOn(dispatchType) ?: RunsOn( + selfHosted = null, + poolName = I18nUtil.getCodeLanMessage( + messageCode = ProcessMessageCode.BK_AUTOMATIC_EXPORT_NOT_SUPPORTED + ), + container = null, + agentSelector = null + ) + if (dispatchType is ThirdPartyAgentEnvDispatchType) { + runsOn.agentSelector = when (job.baseOS) { + VMBaseOS.WINDOWS -> listOf("windows") + VMBaseOS.LINUX -> listOf("linux") + VMBaseOS.MACOS -> listOf("macos") + else -> null + } + } + runsOn.needs = job.buildEnv + runsOn.queueTimeoutMinutes = job.jobControlOption?.prepareTimeout + if (JSONObject(runsOn).similar(defaultRunsOn)) { + return null + } + return runsOn + } + + fun dispatch2RunsOn(dispatcher: DispatchType) = + PoolType.SelfHosted.toRunsOn(dispatcher) + ?: PoolType.DockerOnVm.toRunsOn(dispatcher) +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt index 5cdff16ebbd..35405c1b797 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt @@ -44,7 +44,8 @@ import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGithubWebHook import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeTGitWebHookTriggerElement import com.tencent.devops.process.yaml.modelCreate.ModelCommon import com.tencent.devops.process.yaml.modelCreate.ModelCreateException -import com.tencent.devops.process.yaml.modelTransfer.inner.TransferModelCreator +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault +import com.tencent.devops.process.yaml.modelTransfer.inner.TransferCreator import com.tencent.devops.process.yaml.modelTransfer.pojo.CheckoutAtomParam import com.tencent.devops.process.yaml.modelTransfer.pojo.RunAtomParam import com.tencent.devops.process.yaml.modelTransfer.pojo.WebHookTriggerElementChanger @@ -63,7 +64,7 @@ import org.springframework.stereotype.Component class ElementTransfer @Autowired(required = false) constructor( val client: Client, @Autowired(required = false) - val creator: TransferModelCreator, + val creator: TransferCreator, val transferCache: TransferCacheService, val triggerTransfer: TriggerTransfer ) { @@ -133,11 +134,11 @@ class ElementTransfer @Autowired(required = false) constructor( ): Element { val timeout = setupTimeout(step) val additionalOptions = ElementAdditionalOptions( - continueWhenFailed = step.continueOnError ?: false, - timeout = timeout, + continueWhenFailed = step.continueOnError ?: VariableDefault.DEFAULT_CONTINUE_WHEN_FAILED, + timeout = timeout.toLong(), timeoutVar = timeout.toString(), retryWhenFailed = step.retryTimes != null, - retryCount = step.retryTimes ?: 0, + retryCount = step.retryTimes ?: VariableDefault.DEFAULT_RETRY_COUNT, enableCustomEnv = step.env != null, customEnv = getElementEnv(step.env), runCondition = when { @@ -178,7 +179,7 @@ class ElementTransfer @Autowired(required = false) constructor( return element } - private fun setupTimeout(step: Step) = step.timeoutMinutes?.toLong() ?: 480 + private fun setupTimeout(step: Step) = step.timeoutMinutes ?: VariableDefault.DEFAULT_TASK_TIME_OUT private fun makeRunElement( step: Step, @@ -243,10 +244,13 @@ class ElementTransfer @Autowired(required = false) constructor( @Suppress("ComplexMethod") fun element2YamlStep(element: Element): PreStep? { - val retryTimes = element.additionalOptions?.retryCount ?: 0 - val timeoutMinutes = element.additionalOptions?.timeout?.toInt() ?: 480 + val retryTimes = element.additionalOptions?.retryCount.nullIfDefault(VariableDefault.DEFAULT_RETRY_COUNT) + val timeoutMinutes = element.additionalOptions?.timeout?.toInt() + .nullIfDefault(VariableDefault.DEFAULT_TASK_TIME_OUT) val continueOnError = element.additionalOptions?.continueWhenFailed + .nullIfDefault(VariableDefault.DEFAULT_CONTINUE_WHEN_FAILED) val uses = "${element.getAtomCode()}@${element.version}" + val env = element.additionalOptions?.customEnv?.associateBy({ it.key ?: "" }) { it.value }?.ifEmpty { null } return when { element is LinuxScriptElement -> { PreStep( @@ -259,7 +263,7 @@ class ElementTransfer @Autowired(required = false) constructor( timeoutMinutes = timeoutMinutes, continueOnError = continueOnError, retryTimes = retryTimes, - env = null, + env = env, run = element.script, checkout = null, shell = RunAtomParam.ShellType.BASH.shellName @@ -276,7 +280,7 @@ class ElementTransfer @Autowired(required = false) constructor( timeoutMinutes = timeoutMinutes, continueOnError = continueOnError, retryTimes = retryTimes, - env = null, + env = env, run = element.script, checkout = null, shell = RunAtomParam.ShellType.CMD.shellName @@ -292,11 +296,11 @@ class ElementTransfer @Autowired(required = false) constructor( // 插件上的 ifFiled = parseStepIfFiled(element), uses = null, - with = simplifyParams(uses, input), + with = simplifyParams(uses, input).ifEmpty { null }, timeoutMinutes = timeoutMinutes, continueOnError = continueOnError, retryTimes = retryTimes, - env = null, + env = env, run = null, checkout = url, shell = null @@ -315,11 +319,11 @@ class ElementTransfer @Autowired(required = false) constructor( input.filterNot { it.key == RunAtomParam::shell.name || it.key == RunAtomParam::script.name } - ), + ).ifEmpty { null }, timeoutMinutes = timeoutMinutes, continueOnError = continueOnError, retryTimes = retryTimes, - env = null, + env = env, run = input[RunAtomParam::script.name]?.toString(), checkout = null, shell = input[RunAtomParam::shell.name]?.toString() @@ -333,11 +337,11 @@ class ElementTransfer @Autowired(required = false) constructor( // 插件上的 ifFiled = parseStepIfFiled(element), uses = uses, - with = simplifyParams(uses, input), + with = simplifyParams(uses, input).ifEmpty { null }, timeoutMinutes = timeoutMinutes, continueOnError = continueOnError, retryTimes = retryTimes, - env = null, + env = env, run = null, checkout = null, shell = null @@ -351,11 +355,11 @@ class ElementTransfer @Autowired(required = false) constructor( // 插件上的 ifFiled = parseStepIfFiled(element), uses = uses, - with = simplifyParams(uses, input), + with = simplifyParams(uses, input).ifEmpty { null }, timeoutMinutes = timeoutMinutes, continueOnError = continueOnError, retryTimes = retryTimes, - env = null, + env = env, run = null, checkout = null, shell = null diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt index 7f29b60690b..56acf93057b 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt @@ -28,39 +28,42 @@ package com.tencent.devops.process.yaml.modelTransfer import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.client.Client import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.container.Stage import com.tencent.devops.common.pipeline.container.TriggerContainer -import com.tencent.devops.process.api.user.UserPipelineGroupResource -import com.tencent.devops.process.pojo.classify.PipelineGroup -import com.tencent.devops.process.pojo.classify.PipelineGroupCreate -import com.tencent.devops.process.pojo.classify.PipelineLabelCreate import com.tencent.devops.process.pojo.setting.PipelineRunLockType import com.tencent.devops.process.pojo.setting.PipelineSetting -import com.tencent.devops.process.utils.PIPELINE_SETTING_MAX_QUEUE_SIZE_DEFAULT +import com.tencent.devops.process.pojo.setting.Subscription +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault import com.tencent.devops.process.yaml.modelTransfer.pojo.ModelTransferInput import com.tencent.devops.process.yaml.modelTransfer.pojo.YamlTransferInput import com.tencent.devops.process.yaml.pojo.YamlVersion import com.tencent.devops.process.yaml.v2.models.Concurrency import com.tencent.devops.process.yaml.v2.models.GitNotices import com.tencent.devops.process.yaml.v2.models.IPreTemplateScriptBuildYaml +import com.tencent.devops.process.yaml.v2.models.IfType +import com.tencent.devops.process.yaml.v2.models.Notices +import com.tencent.devops.process.yaml.v2.models.PacNotices import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYaml import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYamlI +import com.tencent.devops.process.yaml.v2.models.PreTemplateScriptBuildYaml import com.tencent.devops.process.yaml.v2.models.Variable import com.tencent.devops.process.yaml.v2.models.on.TriggerOn import com.tencent.devops.process.yaml.v2.models.stage.PreStage import com.tencent.devops.process.yaml.v3.models.PreScriptBuildYamlV3 +import com.tencent.devops.process.yaml.v3.models.PreTemplateScriptBuildYamlV3 import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component -import java.util.concurrent.TimeUnit @Component class ModelTransfer @Autowired constructor( val client: Client, val modelStage: StageTransfer, - val modelElement: ElementTransfer + val modelElement: ElementTransfer, + val transferCache: TransferCacheService ) { companion object { @@ -68,7 +71,7 @@ class ModelTransfer @Autowired constructor( } fun yaml2Labels(yamlInput: YamlTransferInput): List { - return preparePipelineLabels(yamlInput.userId, yamlInput.projectCode, yamlInput.yaml) + return preparePipelineLabels(yamlInput.projectCode, yamlInput.yaml) } fun yaml2Setting(yamlInput: YamlTransferInput): PipelineSetting { @@ -80,20 +83,49 @@ class ModelTransfer @Autowired constructor( desc = yamlInput.pipelineInfo?.pipelineDesc ?: "", concurrencyGroup = yaml.concurrency?.group, // Cancel-In-Progress 配置group后默认为true - concurrencyCancelInProgress = yaml.concurrency?.cancelInProgress - ?: yaml.concurrency?.group?.let { true } - ?: true, + concurrencyCancelInProgress = yaml.concurrency?.cancelInProgress ?: false, runLockType = when { yaml.concurrency?.group != null -> PipelineRunLockType.GROUP_LOCK else -> PipelineRunLockType.MULTIPLE }, - waitQueueTimeMinute = yaml.concurrency?.queueTimeoutMinutes ?: TimeUnit.HOURS.toMinutes(8).toInt(), - maxQueueSize = yaml.concurrency?.queueLength ?: PIPELINE_SETTING_MAX_QUEUE_SIZE_DEFAULT, + waitQueueTimeMinute = yaml.concurrency?.queueTimeoutMinutes + ?: VariableDefault.DEFAULT_WAIT_QUEUE_TIME_MINUTE, + maxQueueSize = yaml.concurrency?.queueLength ?: VariableDefault.DEFAULT_PIPELINE_SETTING_MAX_QUEUE_SIZE, labels = yaml2Labels(yamlInput), - pipelineAsCodeSettings = yamlInput.asCodeSettings + pipelineAsCodeSettings = yamlInput.asCodeSettings, + successSubscriptionList = yamlNotice2Setting( + projectId = yamlInput.projectCode, + notices = yaml.notices?.filter { it.checkNotifyForSuccess() } + ), + failSubscriptionList = yamlNotice2Setting( + projectId = yamlInput.projectCode, + notices = yaml.notices?.filter { it.checkNotifyForFail() } + ) ) } + private fun yamlNotice2Setting(projectId: String, notices: List?): List { + if (notices.isNullOrEmpty()) return listOf(Subscription()) + return notices.map { + val res = it.toSubscription() + prepareModelGroups(projectId, res) + } + } + + private fun prepareModelGroups(projectId: String, notice: Subscription): Subscription { + if (notice.groups.isEmpty()) return notice + val info = transferCache.getProjectGroupAndUsers(projectId)?.associateBy { it.displayName } ?: return notice + val groups = notice.groups.map { info[it]?.roleName ?: "" }.toSet() + return notice.copy(groups = groups) + } + + private fun prepareYamlGroups(projectId: String, notice: PacNotices): PacNotices { + if (notice.groups.isNullOrEmpty()) return notice + val info = transferCache.getProjectGroupAndUsers(projectId)?.associateBy { it.roleName } ?: return notice + val groups = notice.groups.mapNotNull { info[it]?.displayName } + return notice.copy(groups = groups) + } + fun yaml2Model( yamlInput: YamlTransferInput ): Model { @@ -137,61 +169,93 @@ class ModelTransfer @Autowired constructor( ) } - fun model2yaml(modelInput: ModelTransferInput): PreScriptBuildYamlI { + fun model2yaml(modelInput: ModelTransferInput): IPreTemplateScriptBuildYaml { val stages = mutableListOf() modelInput.model.stages.forEachIndexed { index, stage -> if (index == 0 || stage.finally) return@forEachIndexed val ymlStage = modelStage.model2YamlStage(stage) stages.add(ymlStage) } - val label = modelInput.model.labels.ifEmpty { null } + val label = prepareYamlLabels(modelInput.setting).ifEmpty { null } val triggerOn = getTriggerOn(modelInput.model) val variables = getVariableFromModel(modelInput.model) - val finally = modelStage.model2YamlStage(modelInput.model.stages.last()).jobs + val lastStage = modelInput.model.stages.last() + val finally = if (lastStage.finally) modelStage.model2YamlStage(lastStage).jobs else null val concurrency = getConcurrency(modelInput.setting) - val notices = ""// TODO: 2023/7/17 return when (modelInput.version) { - YamlVersion.Version.V2_0 -> PreScriptBuildYaml( + YamlVersion.Version.V2_0 -> PreTemplateScriptBuildYaml( version = "v2.0", name = modelInput.model.name, label = label, triggerOn = triggerOn[modelInput.defaultScmType]?.toPreV2(), variables = variables, - stages = stages, + stages = TransferMapper.anyTo(stages), extends = null, resources = null, - notices = null, + notices = makeNoticesV2(modelInput.setting), finally = finally, concurrency = concurrency ) - YamlVersion.Version.V3_0 -> PreScriptBuildYamlV3( + YamlVersion.Version.V3_0 -> PreTemplateScriptBuildYamlV3( version = "v3.0", name = modelInput.model.name, label = label, - triggerOn = triggerOn.map { it.value.toPreV3() }, + triggerOn = triggerOn.map { on -> + on.value.toPreV3().also { it.type = on.key.alis } + }.ifEmpty { null }?.let { if (it.size == 1) it.first() else it }, variables = variables, - stages = stages, + stages = TransferMapper.anyTo(stages), extends = null, resources = null, - notices = null, + notices = makeNoticesV3(modelInput.setting), finally = finally, concurrency = concurrency ) } } - private fun getNotices(setting: PipelineSetting): List { - return emptyList() + private fun makeNoticesV2(setting: PipelineSetting): List { + val res = mutableListOf() + setting.successSubscriptionList?.forEach { + if (it.types.isNotEmpty()) { + res.add(GitNotices(it, IfType.SUCCESS.name)) + } + } + setting.failSubscriptionList?.forEach { + if (it.types.isNotEmpty()) { + res.add(GitNotices(it, IfType.FAILURE.name)) + } + } + return res + } + + private fun makeNoticesV3(setting: PipelineSetting): List { + val res = mutableListOf() + setting.successSubscriptionList?.forEach { + if (it.types.isNotEmpty()) { + val notice = PacNotices(it, IfType.SUCCESS.name) + res.add(prepareYamlGroups(setting.projectId, notice)) + } + } + setting.failSubscriptionList?.forEach { + if (it.types.isNotEmpty()) { + val notice = PacNotices(it, IfType.FAILURE.name) + res.add(prepareYamlGroups(setting.projectId, notice)) + } + } + return res } private fun getConcurrency(setting: PipelineSetting): Concurrency? { if (setting.runLockType == PipelineRunLockType.GROUP_LOCK) { return Concurrency( group = setting.concurrencyGroup, - cancelInProgress = setting.concurrencyCancelInProgress, - queueLength = setting.maxQueueSize, + cancelInProgress = setting.concurrencyCancelInProgress.nullIfDefault(false), + queueLength = setting.maxQueueSize + .nullIfDefault(VariableDefault.DEFAULT_PIPELINE_SETTING_MAX_QUEUE_SIZE), queueTimeoutMinutes = setting.waitQueueTimeMinute + .nullIfDefault(VariableDefault.DEFAULT_WAIT_QUEUE_TIME_MINUTE) ) } return null @@ -217,75 +281,30 @@ class ModelTransfer @Autowired constructor( @Suppress("NestedBlockDepth") private fun preparePipelineLabels( - userId: String, projectCode: String, yaml: IPreTemplateScriptBuildYaml ): List { - val gitCIPipelineLabels = mutableListOf() - - try { - // 获取当前项目下存在的标签组 - val pipelineGroups = client.get(UserPipelineGroupResource::class) - .getGroups(userId, projectCode) - .data + val ymlLabel = yaml.label ?: return emptyList() + val labels = mutableListOf() - yaml.label?.forEach { - // 要设置的标签组不存在,新建标签组和标签(同名) - if (!checkPipelineLabel(it, pipelineGroups)) { - client.get(UserPipelineGroupResource::class).addGroup( - userId, - PipelineGroupCreate( - projectId = projectCode, - name = it - ) - ) - - val pipelineGroup = getPipelineGroup(it, userId, projectCode) - if (pipelineGroup != null) { - client.get(UserPipelineGroupResource::class).addLabel( - userId = userId, - projectId = projectCode, - pipelineLabel = PipelineLabelCreate( - groupId = pipelineGroup.id, - name = it - ) - ) - } - } - - // 保证标签已创建成功后,取label加密ID - val pipelineGroup = getPipelineGroup(it, userId, projectCode) - gitCIPipelineLabels.add(pipelineGroup!!.labels[0].id) + transferCache.getPipelineLabel(projectCode)?.forEach { group -> + group.labels.forEach { + if (ymlLabel.contains(it.name)) labels.add(it.id) } - } catch (e: Exception) { - logger.warn("$userId|$projectCode preparePipelineLabels error.", e) } - - return gitCIPipelineLabels + return labels } - private fun checkPipelineLabel(gitciPipelineLabel: String, pipelineGroups: List?): Boolean { - pipelineGroups?.forEach { pipelineGroup -> - pipelineGroup.labels.forEach { - if (it.name == gitciPipelineLabel) { - return true - } - } - } - - return false - } + private fun prepareYamlLabels( + pipelineSetting: PipelineSetting + ): List { + val labels = mutableListOf() - private fun getPipelineGroup(labelGroupName: String, userId: String, projectId: String): PipelineGroup? { - val pipelineGroups = client.get(UserPipelineGroupResource::class) - .getGroups(userId, projectId) - .data - pipelineGroups?.forEach { - if (it.name == labelGroupName) { - return it + transferCache.getPipelineLabel(pipelineSetting.projectId)?.forEach { group -> + group.labels.forEach { + if (pipelineSetting.labels.contains(it.id)) labels.add(it.name) } } - - return null + return labels } } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt index 8e9ef890257..c0ed0f57cc8 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt @@ -48,7 +48,6 @@ import com.tencent.devops.common.pipeline.pojo.element.atom.ManualReviewParamTyp import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.engine.common.VMUtils import com.tencent.devops.process.yaml.modelCreate.ModelCommon -import com.tencent.devops.process.yaml.modelCreate.ModelContainer import com.tencent.devops.process.yaml.modelCreate.ModelCreateException import com.tencent.devops.process.yaml.modelTransfer.pojo.YamlTransferInput import com.tencent.devops.process.yaml.utils.ModelCreateUtil @@ -56,6 +55,7 @@ import com.tencent.devops.process.yaml.v2.models.Variable import com.tencent.devops.process.yaml.v2.models.job.Job import com.tencent.devops.process.yaml.v2.models.job.JobRunsOnType import com.tencent.devops.process.yaml.v2.models.stage.PreStage +import com.tencent.devops.process.yaml.v2.models.stage.StageLabel import com.tencent.devops.process.yaml.v2.stageCheck.PreFlow import com.tencent.devops.process.yaml.v2.stageCheck.PreStageCheck import com.tencent.devops.process.yaml.v2.stageCheck.PreStageReviews @@ -70,7 +70,7 @@ import com.tencent.devops.process.yaml.v2.models.stage.Stage as StreamV2Stage class StageTransfer @Autowired(required = false) constructor( val client: Client, val objectMapper: ObjectMapper, - val modelContainer: ModelContainer, + val modelContainer: ContainerTransfer, val modelElement: ElementTransfer ) { companion object { @@ -200,7 +200,7 @@ class StageTransfer @Autowired(required = false) constructor( } return PreStage( name = stage.name, - label = stage.tag?.ifEmpty { null }, + label = maskYamlStageLabel(stage.tag).ifEmpty { null }, ifField = when (stage.stageControlOption?.runCondition) { StageRunCondition.CUSTOM_CONDITION_MATCH -> stage.stageControlOption?.customCondition StageRunCondition.CUSTOM_VARIABLE_MATCH -> ModelCommon.customVariableMatch( @@ -219,6 +219,11 @@ class StageTransfer @Autowired(required = false) constructor( ) } + private fun maskYamlStageLabel(tags: List?): List { + if (tags.isNullOrEmpty()) return emptyList() + return tags.map { StageLabel.parseById(it).value } + } + private fun getCheckInForStage(stage: Stage): PreStageCheck? { val reviews = PreStageReviews( flows = stage.checkIn?.reviewGroups?.map { PreFlow(it.name, it.reviewers) }, diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferCacheService.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferCacheService.kt index c50eb117e85..36e9db3a00c 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferCacheService.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferCacheService.kt @@ -1,7 +1,13 @@ package com.tencent.devops.process.yaml.modelTransfer import com.github.benmanes.caffeine.cache.Caffeine +import com.tencent.devops.auth.api.service.ServiceProjectAuthResource +import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE +import com.tencent.devops.common.auth.api.pojo.BkAuthGroupAndUserList import com.tencent.devops.common.client.Client +import com.tencent.devops.common.client.ClientTokenService +import com.tencent.devops.process.api.service.ServicePipelineGroupResource +import com.tencent.devops.process.pojo.classify.PipelineGroup import com.tencent.devops.store.api.atom.ServiceMarketAtomResource import com.tencent.devops.store.api.image.service.ServiceStoreImageResource import com.tencent.devops.store.pojo.atom.ElementThirdPartySearchParam @@ -13,7 +19,8 @@ import java.util.concurrent.TimeUnit @Service class TransferCacheService @Autowired constructor( - private val client: Client + private val client: Client, + private val tokenService: ClientTokenService ) { companion object { @@ -42,11 +49,39 @@ class TransferCacheService @Autowired constructor( imageCode = imageCode, imageVersion = imageVersion ).data - }.onFailure { logger.warn("get $key default value error.") }.getOrNull() + }.onFailure { logger.warn("get $key ImageInfoByCodeAndVersion value error.") }.getOrNull() + } + + private val projectGroupAndUsersCache = Caffeine.newBuilder() + .maximumSize(1000) + .expireAfterWrite(10, TimeUnit.MINUTES) + .build?> { key -> + kotlin.runCatching { + client.get(ServiceProjectAuthResource::class) + .getProjectGroupAndUserList( + token = tokenService.getSystemToken(null)!!, + projectCode = key + ).data + }.onFailure { logger.warn("get $key ProjectGroupAndUserList error.") }.getOrNull() + } + + private val pipelineLabel = Caffeine.newBuilder() + .maximumSize(1000) + .expireAfterWrite(10, TimeUnit.MINUTES) + .build?> { projectId -> + kotlin.runCatching { + client.get(ServicePipelineGroupResource::class) + .getGroups(AUTH_HEADER_USER_ID_DEFAULT_VALUE, projectId) + .data + }.onFailure { logger.warn("get $projectId default value error.") }.getOrNull() } fun getAtomDefaultValue(key: String) = atomDefaultValueCache.get(key) ?: emptyMap() fun getStoreImageInfo(imageCode: String, imageVersion: String?) = storeImageInfoCache.get("$imageCode@@${imageVersion ?: ""}") + + fun getProjectGroupAndUsers(projectId: String) = projectGroupAndUsersCache.get(projectId) + + fun getPipelineLabel(projectId: String) = pipelineLabel.get(projectId) } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferMapper.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferMapper.kt index 2e0efd0ffce..04a80e3822b 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferMapper.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferMapper.kt @@ -2,6 +2,7 @@ package com.tencent.devops.process.yaml.modelTransfer import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.core.io.IOContext +import com.fasterxml.jackson.core.type.TypeReference import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider @@ -355,7 +356,9 @@ object TransferMapper { private val yamlObjectMapper = ObjectMapper( CustomYAMLFactoryBuilder.enable(YAMLGenerator.Feature.LITERAL_BLOCK_STYLE) .enable(YAMLGenerator.Feature.MINIMIZE_QUOTES) + .disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER) .disable(YAMLGenerator.Feature.SPLIT_LINES) + .disable(YAMLGenerator.Feature.USE_NATIVE_TYPE_ID) .stringQuotingChecker(CustomStringQuotingChecker()).build() ).setSerializationInclusion(JsonInclude.Include.NON_NULL).apply { registerKotlinModule().setFilterProvider( @@ -410,6 +413,10 @@ object TransferMapper { return getObjectMapper().writeValueAsString(bean)!! } + fun anyTo(any: Any?): T = getObjectMapper().readValue( + getObjectMapper().writeValueAsString(any), object : TypeReference() {} + ) + /** * 获得 yaml 第一层级的坐标定位信息 */ diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt index 85a6f2a207c..8b655017b31 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt @@ -39,7 +39,7 @@ import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeTGitWebHookTr import com.tencent.devops.common.pipeline.pojo.element.trigger.ManualTriggerElement import com.tencent.devops.common.pipeline.pojo.element.trigger.enums.CodeEventType import com.tencent.devops.common.web.utils.I18nUtil -import com.tencent.devops.process.yaml.modelTransfer.inner.TransferModelCreator +import com.tencent.devops.process.yaml.modelTransfer.inner.TransferCreator import com.tencent.devops.process.yaml.modelTransfer.pojo.WebHookTriggerElementChanger import com.tencent.devops.process.yaml.v2.models.on.IssueRule import com.tencent.devops.process.yaml.v2.models.on.MrRule @@ -56,7 +56,7 @@ import org.springframework.stereotype.Component class TriggerTransfer @Autowired(required = false) constructor( val client: Client, @Autowired(required = false) - val creator: TransferModelCreator, + val creator: TransferCreator, val transferCache: TransferCacheService ) { companion object { diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/VariableDefault.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/VariableDefault.kt new file mode 100644 index 00000000000..c74f09bc7f4 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/VariableDefault.kt @@ -0,0 +1,17 @@ +package com.tencent.devops.process.yaml.modelTransfer + +object VariableDefault { + const val DEFAULT_TASK_TIME_OUT = 480 + const val DEFAULT_JOB_TIME_OUT = 480 + const val DEFAULT_WAIT_QUEUE_TIME_MINUTE = 480 + const val DEFAULT_RETRY_COUNT = 0 + const val DEFAULT_CONTINUE_WHEN_FAILED = false + const val DEFAULT_PIPELINE_SETTING_MAX_QUEUE_SIZE = 10 + const val DEFAULT_JOB_MAX_QUEUE_MINUTES = 60 + const val DEFAULT_JOB_MAX_RUNNING_MINUTES = 60 + const val DEFAULT_MUTEX_QUEUE_LENGTH = 5 + const val DEFAULT_MUTEX_TIMEOUT_MINUTES = 900 + const val DEFAULT_MUTEX_QUEUE_ENABLE = false + + fun T.nullIfDefault(value: T) = if (this == value) null else this +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreator.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreator.kt similarity index 98% rename from src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreator.kt rename to src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreator.kt index afe5f18d644..509dc629242 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreator.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreator.kt @@ -34,7 +34,7 @@ import com.tencent.devops.process.yaml.v2.models.step.Step /** * ModelCreate的内部类,用来放一些不同使用者的不同方法和参数 */ -interface TransferModelCreator { +interface TransferCreator { // 控制run插件是否是研发商店插件 val marketRunTask: Boolean diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreatorImpl.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreatorImpl.kt similarity index 96% rename from src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreatorImpl.kt rename to src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreatorImpl.kt index e3caf5247ff..05557d6cd23 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferModelCreatorImpl.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreatorImpl.kt @@ -39,8 +39,8 @@ import javax.ws.rs.core.Response @Primary @Component -class TransferModelCreatorImpl @Autowired constructor( -) : TransferModelCreator { +class TransferCreatorImpl @Autowired constructor( +) : TransferCreator { @Value("\${marketRun.enable:#{false}}") private val marketRunTaskData: Boolean = false @@ -51,7 +51,7 @@ class TransferModelCreatorImpl @Autowired constructor( private val runPlugInVersionData: String? = null @Value("\${container.defaultImage:#{null}}") - private val defaultImageData: String = "http://mirrors.tencent.com/ci/tlinux3_ci:1.5.0" + private val defaultImageData: String = "mirrors.tencent.com/ci/tlinux3_ci:2.5.0" companion object { private const val STREAM_CHECK_AUTH_TYPE = "AUTH_USER_TOKEN" diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/ThirdPartyContainerInfo.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/ThirdPartyContainerInfo.kt index bf6b3a6fadc..5831dbd89ca 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/ThirdPartyContainerInfo.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/ThirdPartyContainerInfo.kt @@ -28,6 +28,7 @@ package com.tencent.devops.process.yaml.pojo import com.tencent.devops.common.pipeline.type.agent.DockerOptions +import com.tencent.devops.common.pipeline.type.docker.ImageType data class ThirdPartyContainerInfo( val image: String, @@ -36,5 +37,6 @@ data class ThirdPartyContainerInfo( val credId: String?, val acrossTemplateId: String?, val options: DockerOptions?, - val imagePullPolicy: String? + val imagePullPolicy: String?, + val imageType: ImageType? = ImageType.THIRD, ) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/utils/StreamDispatchUtils.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/utils/StreamDispatchUtils.kt index d46973a14b7..f3d7797fe7d 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/utils/StreamDispatchUtils.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/utils/StreamDispatchUtils.kt @@ -220,7 +220,8 @@ object StreamDispatchUtils { credId = null, acrossTemplateId = null, options = container.options, - imagePullPolicy = container.imagePullPolicy + imagePullPolicy = container.imagePullPolicy, + imageType = ImageType.valueOf(container.imageType ?: ImageType.THIRD.name) ) } catch (e: Exception) { val container = YamlUtil.getObjectMapper().readValue( @@ -235,7 +236,8 @@ object StreamDispatchUtils { credId = container.credentials, acrossTemplateId = buildTemplateAcrossInfo?.templateId, options = container.options, - imagePullPolicy = container.imagePullPolicy + imagePullPolicy = container.imagePullPolicy, + imageType = ImageType.valueOf(container.imageType ?: ImageType.THIRD.name) ) } } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Notices.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Notices.kt index 6f1a96df5e1..32ede2a89e1 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Notices.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Notices.kt @@ -30,26 +30,33 @@ package com.tencent.devops.process.yaml.v2.models import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.process.pojo.pipeline.PipelineSubscriptionType +import com.tencent.devops.process.pojo.setting.Subscription +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault import io.swagger.annotations.ApiModelProperty +import java.util.TreeSet /** * model Stream 通知类型基类 */ @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -open class Notices( - val type: String, - open val receivers: Set? -) +interface Notices { + fun toSubscription() = Subscription() + + fun checkNotifyForSuccess() = false + + fun checkNotifyForFail() = false +} /** * model Stream Yaml基本通知 */ @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -class GitNotices( - type: String, - receivers: Set?, +data class GitNotices( + val type: String, + val receivers: Set?, val title: String?, val content: String?, val ccs: Set?, @@ -59,7 +66,125 @@ class GitNotices( @ApiModelProperty(name = "chat-id") @JsonProperty("chat-id") val chatId: Set? -) : Notices(type, receivers) +) : Notices { + + constructor(subscription: Subscription, ifField: String?) : this( + type = subscription.types.map { PacNotices.toNotifyType(it) }.toMutableList().also { + if (subscription.wechatGroupFlag) it.add(NotifyType.RTX_GROUP.yamlText) + }.first(), + receivers = subscription.users.split(",").ifEmpty { null }?.toSet(), + title = null, + content = subscription.content.ifEmpty { null }, + ccs = null, + ifField = ifField, + chatId = subscription.wechatGroup.split(",").ifEmpty { null }?.toSet() + ) + + override fun toSubscription() = Subscription( + types = setOf(PacNotices.toPipelineSubscriptionType(type)), + groups = emptySet(), + users = receivers?.joinToString(",") ?: "", + wechatGroupFlag = type.contains(NotifyType.RTX_GROUP.yamlText), + wechatGroup = chatId?.joinToString(",") ?: "", + wechatGroupMarkdownFlag = false, + detailFlag = false, + content = content ?: "" + ) + + override fun checkNotifyForSuccess(): Boolean { + return ifField == null || ifField == IfType.SUCCESS.name || ifField == IfType.ALWAYS.name + } + + override fun checkNotifyForFail(): Boolean { + return ifField == null || ifField == IfType.FAILURE.name || ifField == IfType.ALWAYS.name + } +} + +/** + * pac 通知 + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class PacNotices( + @ApiModelProperty(name = "if") + @JsonProperty("if") + val ifField: String?, + val type: List, + val receivers: List?, + val groups: List?, + val content: String?, + @ApiModelProperty(name = "chat-id") + @JsonProperty("chat-id") + val chatId: List?, + @ApiModelProperty(name = "notify-markdown") + @JsonProperty("notify-markdown") + val notifyMarkdown: Boolean?, + @ApiModelProperty(name = "notify-detail-url") + @JsonProperty("notify-detail-url") + val notifyDetail: Boolean? +) : Notices { + + constructor(subscription: Subscription, ifField: String?) : this( + type = subscription.types.map { toNotifyType(it) }.toMutableList().also { + if (subscription.wechatGroupFlag) it.add(NotifyType.RTX_GROUP.yamlText) + }, + receivers = subscription.users.ifBlank { null }?.split(",")?.toSet()?.toList(), + groups = subscription.groups.ifEmpty { null }?.toList(), + content = subscription.content.ifEmpty { null }, + ifField = ifField, + chatId = subscription.wechatGroup.ifBlank { null }?.split(",")?.toSet()?.toList(), + notifyMarkdown = subscription.wechatGroupMarkdownFlag.nullIfDefault(false), + notifyDetail = subscription.detailFlag.nullIfDefault(false) + ) + + companion object { + fun toPipelineSubscriptionType(type: String) = when (type) { + NotifyType.EMAIL.yamlText -> PipelineSubscriptionType.EMAIL + NotifyType.RTX_CUSTOM.yamlText -> PipelineSubscriptionType.RTX + NotifyType.SMS.yamlText -> PipelineSubscriptionType.SMS + else -> PipelineSubscriptionType.RTX + } + + fun toNotifyType(type: PipelineSubscriptionType) = when (type) { + PipelineSubscriptionType.EMAIL -> NotifyType.EMAIL.yamlText + PipelineSubscriptionType.RTX -> NotifyType.RTX_CUSTOM.yamlText + PipelineSubscriptionType.SMS -> NotifyType.SMS.yamlText + else -> NotifyType.RTX_GROUP.yamlText + } + } + + override fun toSubscription() = Subscription( + types = type.map { toPipelineSubscriptionType(it) }.toSet(), + groups = groups?.toSet() ?: emptySet(), + users = receivers?.joinToString(",") ?: "", + wechatGroupFlag = type.contains(NotifyType.RTX_GROUP.yamlText), + wechatGroup = chatId?.joinToString(",") ?: "", + wechatGroupMarkdownFlag = notifyMarkdown ?: false, + detailFlag = notifyDetail ?: false, + content = content ?: "" + ) + + override fun checkNotifyForSuccess(): Boolean { + return ifField == null || ifField == IfType.SUCCESS.name || ifField == IfType.ALWAYS.name + } + + override fun checkNotifyForFail(): Boolean { + return ifField == null || ifField == IfType.FAILURE.name || ifField == IfType.ALWAYS.name + } +} + +enum class NotifyType(val yamlText: String) { + // 企业微信客服 + SMS("sms"), + + RTX_CUSTOM("wework-message"), + + // 邮件 + EMAIL("email"), + + // 企业微信群 + RTX_GROUP("wework-chat"); +} /** * model Stream 质量红线通知 @@ -67,6 +192,6 @@ class GitNotices( @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) class GateNotices( - type: String, - receivers: Set? -) : Notices(type, receivers) + val type: String, + val receivers: Set? +) : Notices diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreScriptBuildYaml.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreScriptBuildYaml.kt index 0c8b969847c..4de17bc070d 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreScriptBuildYaml.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreScriptBuildYaml.kt @@ -50,7 +50,6 @@ interface PreScriptBuildYamlI : YamlVersion { var steps: List? var extends: Extends? var resources: Resources? - var notices: List? var finally: Map? val concurrency: Concurrency? } @@ -74,7 +73,7 @@ data class PreScriptBuildYaml( override var steps: List? = null, override var extends: Extends? = null, override var resources: Resources?, - override var notices: List?, + var notices: List?, override var finally: Map? = null, override val concurrency: Concurrency? = null ) : PreScriptBuildYamlI { diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt index 5a73c782957..408cf7221cd 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt @@ -44,7 +44,7 @@ import com.tencent.devops.process.yaml.v3.models.PreTemplateScriptBuildYamlV3 @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, - include = JsonTypeInfo.As.PROPERTY, + include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "version", defaultImpl = PreTemplateScriptBuildYaml::class ) @@ -56,7 +56,7 @@ interface IPreTemplateScriptBuildYaml : YamlVersion { val version: String? val name: String? val label: List? - val notices: List? + val notices: List? val concurrency: Concurrency? fun replaceTemplate(f: (param: ITemplateFilter) -> PreScriptBuildYamlI) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/Pool.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/Pool.kt index 3bbdeeee2d3..756152eaa4d 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/Pool.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/Pool.kt @@ -30,23 +30,34 @@ package com.tencent.devops.process.yaml.v2.models.image import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.tencent.devops.common.pipeline.enums.VMBaseOS +import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentDockerInfo +import com.tencent.devops.common.pipeline.type.docker.ImageType @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class Pool( - val container: String?, - val credential: Credential?, - val third: Boolean?, + val container: String? = null, + val credentialId: String? = null, + val third: Boolean? = null, val performanceConfigId: String? = "0", val env: Map? = mapOf(), val type: PoolType? = null, val agentName: String? = null, val agentId: String? = null, val envName: String? = null, + val envProjectId: String? = null, val envId: String? = null, val os: VMBaseOS? = null, val workspace: String? = null, - val buildType: BuildType? = BuildType.DEVCLOUD + val buildType: BuildType? = BuildType.DEVCLOUD, + val dockerInfo: ThirdPartyAgentDockerInfo? = null, + val image: PoolImage? = null +) + +data class PoolImage( + val imageCode: String, + val imageVersion: String, + val imageType: ImageType? = ImageType.THIRD ) enum class BuildType { diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/PoolType.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/PoolType.kt index b64431e5a23..09522a54019 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/PoolType.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/PoolType.kt @@ -30,10 +30,17 @@ package com.tencent.devops.process.yaml.v2.models.image import com.tencent.devops.common.api.exception.OperationException import com.tencent.devops.common.pipeline.type.DispatchType import com.tencent.devops.common.pipeline.type.agent.AgentType +import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentDockerInfo import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentEnvDispatchType import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentIDDispatchType import com.tencent.devops.common.pipeline.type.docker.DockerDispatchType import com.tencent.devops.common.pipeline.type.docker.ImageType +import com.tencent.devops.process.yaml.v2.models.job.Container2 +import com.tencent.devops.process.yaml.v2.models.job.Container3 +import com.tencent.devops.process.yaml.v2.models.job.Credentials +import com.tencent.devops.process.yaml.v2.models.job.JobRunsOnPoolType +import com.tencent.devops.process.yaml.v2.models.job.JobRunsOnType +import com.tencent.devops.process.yaml.v2.models.job.RunsOn import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -42,9 +49,11 @@ enum class PoolType { DockerOnVm { override fun transfer(pool: Pool): DispatchType { return DockerDispatchType( - dockerBuildVersion = pool.container, - imageType = ImageType.THIRD, - credentialId = pool.credential?.credentialId + dockerBuildVersion = pool.container ?: pool.image?.imageCode, + imageType = pool.image?.imageType ?: ImageType.THIRD, + credentialId = pool.credentialId, + imageVersion = pool.image?.imageVersion, + imageCode = pool.image?.imageCode ) } @@ -53,41 +62,105 @@ enum class PoolType { throw OperationException("当pool.type=$this, container参数不能为空") } } + + override fun transfer(dispatcher: DispatchType): RunsOn? { + if (dispatcher is DockerDispatchType) { + return RunsOn( + poolName = JobRunsOnType.DOCKER.type, + container = when (dispatcher.imageType) { + ImageType.BKSTORE, ImageType.THIRD -> Container2( + image = "${dispatcher.dockerBuildVersion}:${dispatcher.imageVersion}", + credentials = dispatcher.credentialId + ) + else -> null + } + ) + } + return null + } }, SelfHosted { override fun transfer(pool: Pool): DispatchType { if (!pool.envName.isNullOrBlank()) { return ThirdPartyAgentEnvDispatchType( - envProjectId = null, - envName = pool.envName!!, + envProjectId = pool.envProjectId, + envName = pool.envName, workspace = pool.workspace, agentType = AgentType.NAME, - dockerInfo = null + dockerInfo = pool.dockerInfo ) } else if (!pool.envId.isNullOrBlank()) { return ThirdPartyAgentEnvDispatchType( - envProjectId = null, - envName = pool.envId!!, + envProjectId = pool.envProjectId, + envName = pool.envId, workspace = pool.workspace, agentType = AgentType.ID, - dockerInfo = null + dockerInfo = pool.dockerInfo ) } else if (!pool.agentId.isNullOrBlank()) { return ThirdPartyAgentIDDispatchType( - displayName = pool.agentId!!, + displayName = pool.agentId, workspace = pool.workspace, agentType = AgentType.ID, - dockerInfo = null + dockerInfo = pool.dockerInfo ) } else { return ThirdPartyAgentIDDispatchType( displayName = pool.agentName!!, workspace = pool.workspace, agentType = AgentType.NAME, - dockerInfo = null + dockerInfo = pool.dockerInfo + ) + } + } + + override fun transfer(dispatcher: DispatchType): RunsOn? { + if (dispatcher is ThirdPartyAgentEnvDispatchType) { + return RunsOn( + selfHosted = true, + poolName = dispatcher.envName, + poolType = if (dispatcher.agentType == AgentType.NAME) { + JobRunsOnPoolType.ENV_NAME.name + } else { + JobRunsOnPoolType.ENV_ID.name + }, + workspace = dispatcher.workspace, + container = makeContainer(dispatcher.dockerInfo) + ) + } + if (dispatcher is ThirdPartyAgentIDDispatchType) { + return RunsOn( + selfHosted = true, + poolName = dispatcher.displayName, + poolType = if (dispatcher.agentType == AgentType.NAME) { + JobRunsOnPoolType.AGENT_NAME.name + } else { + JobRunsOnPoolType.AGENT_ID.name + }, + workspace = dispatcher.workspace, + container = makeContainer(dispatcher.dockerInfo) ) } + return null + } + + private fun makeContainer(dockerInfo: ThirdPartyAgentDockerInfo?): Container3? { + if (dockerInfo == null) return null + return Container3( + image = dockerInfo.image, + imageType = null, + credentials = with(dockerInfo.credential) { + when { + this == null -> null + credentialId != null -> dockerInfo.credential?.credentialId + user != null && password != null -> Credentials(user!!, password!!) + else -> null + } + }, + options = dockerInfo.options, + imagePullPolicy = dockerInfo.imagePullPolicy + ) } override fun validatePool(pool: Pool) { @@ -109,6 +182,15 @@ enum class PoolType { */ protected abstract fun transfer(pool: Pool): DispatchType + /** + * 转换runsOn + */ + protected abstract fun transfer(dispatcher: DispatchType): RunsOn? + + fun toRunsOn(dispatcher: DispatchType): RunsOn? { + return this.transfer(dispatcher) + } + fun toDispatchType(pool: Pool): DispatchType { this.validatePool(pool) return this.transfer(pool) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/job/Job.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/job/Job.kt index 7d7c453ab8b..95fb40524ba 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/job/Job.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/job/Job.kt @@ -29,6 +29,7 @@ package com.tencent.devops.process.yaml.v2.models.job import com.fasterxml.jackson.annotation.JsonProperty import com.tencent.devops.common.pipeline.type.agent.DockerOptions +import com.tencent.devops.common.pipeline.type.docker.ImageType import com.tencent.devops.process.yaml.v2.models.step.Step import io.swagger.annotations.ApiModelProperty @@ -68,18 +69,29 @@ data class Job( data class Container( val image: String, - val credentials: Credentials?, - val options: DockerOptions?, + val imageType: String? = ImageType.THIRD.name, + val credentials: Credentials? = null, + val options: DockerOptions? = null, @JsonProperty("image-pull-policy") - val imagePullPolicy: String? + val imagePullPolicy: String? = null ) data class Container2( val image: String, - val credentials: String?, - val options: DockerOptions?, + val imageType: String? = ImageType.THIRD.name, + val credentials: String? = null, + val options: DockerOptions? = null, @JsonProperty("image-pull-policy") - val imagePullPolicy: String? + val imagePullPolicy: String? = null +) + +data class Container3( + val image: String, + val imageType: String? = ImageType.THIRD.name, + val credentials: Any? = null, + val options: DockerOptions? = null, + @JsonProperty("image-pull-policy") + val imagePullPolicy: String? = null ) enum class ImagePullPolicyEnum(val type: String) { @@ -119,16 +131,18 @@ data class RunsOn( @ApiModelProperty(name = "pool-name") @JsonProperty("pool-name") var poolName: String = JobRunsOnType.DOCKER.type, + @JsonProperty("pool-type") + val poolType: String? = JobRunsOnPoolType.ENV_NAME.name, val container: Any? = null, @ApiModelProperty(name = "agent-selector") @JsonProperty("agent-selector") - val agentSelector: List? = null, + var agentSelector: List? = null, val workspace: String? = null, val xcode: String? = null, @ApiModelProperty(name = "queue-timeout-minutes") @JsonProperty("queue-timeout-minutes") - val queueTimeoutMinutes: Int? = null, - val needs: Map? = null + var queueTimeoutMinutes: Int? = null, + var needs: Map? = null ) enum class JobRunsOnType(val type: String) { @@ -139,10 +153,19 @@ enum class JobRunsOnType(val type: String) { LOCAL("local") } +enum class JobRunsOnPoolType { + ENV_NAME, + ENV_ID, + AGENT_ID, + AGENT_NAME +} + data class Mutex( val label: String, @JsonProperty("queue-length") val queueLength: Int? = 0, @JsonProperty("timeout-minutes") - val timeoutMinutes: Int? = 10 + val timeoutMinutes: Int? = 10, + @JsonProperty("queue-enable") + val queueEnable: Boolean? = false ) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/stage/StageLabel.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/stage/StageLabel.kt index fd7eb872469..bf75a7d855b 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/stage/StageLabel.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/stage/StageLabel.kt @@ -35,4 +35,13 @@ enum class StageLabel( APPROVE("Approve", "5168be68b9764edb91aa5b866e51a1a8"), DEPLOY("Deploy", "53b4d3f38e3e425cb1aaa97aa1b37857"), TEST("Test", "d0a06f6986fa4670af65ccad7bb49d3a"); + + companion object { + fun parseById(id: String): StageLabel { + values().forEach { + if (it.id == id) return it + } + return BUILD + } + } } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlObjects.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlObjects.kt index db1b000478e..a3201161d3a 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlObjects.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlObjects.kt @@ -37,6 +37,7 @@ import com.tencent.devops.process.yaml.v2.enums.TemplateType import com.tencent.devops.process.yaml.v2.exception.YamlFormatException import com.tencent.devops.process.yaml.v2.models.GitNotices import com.tencent.devops.process.yaml.v2.models.MetaData +import com.tencent.devops.process.yaml.v2.models.PacNotices import com.tencent.devops.process.yaml.v2.models.ResourcesPools import com.tencent.devops.process.yaml.v2.models.TemplateInfo import com.tencent.devops.process.yaml.v2.models.Variable @@ -282,7 +283,7 @@ object YamlObjects { ) } - fun getNotice(fromPath: TemplatePath, notice: Map): GitNotices { + fun getNoticeV2(fromPath: TemplatePath, notice: Map): GitNotices { return GitNotices( type = notice["type"].toString(), title = notice["title"]?.toString(), @@ -301,7 +302,44 @@ object YamlObjects { chatId = if (notice["chat-id"] == null) { null } else { - transValue>(fromPath, "receivers", notice["chat-id"]).toSet() + transValue>(fromPath, "chat-id", notice["chat-id"]).toSet() + } + ) + } + + fun getNoticeV3(fromPath: TemplatePath, notice: Map): PacNotices { + return PacNotices( + type = if (notice["receivers"] == null) { + emptyList() + } else { + transValue(fromPath, "type", notice["type"]) + }, + receivers = if (notice["receivers"] == null) { + null + } else { + transValue>(fromPath, "receivers", notice["receivers"]) + }, + groups = if (notice["groups"] == null) { + null + } else { + transValue>(fromPath, "groups", notice["groups"]) + }, + content = notice["content"]?.toString(), + ifField = notice["if"]?.toString(), + chatId = if (notice["chat-id"] == null) { + null + } else { + transValue>(fromPath, "chat-id", notice["chat-id"]) + }, + notifyMarkdown = if (notice["notify-markdown"] == null) { + null + } else { + transValue(fromPath, "notify-markdown", notice["notify-markdown"]) + }, + notifyDetail = if (notice["notify-detail-url"] == null) { + null + } else { + transValue(fromPath, "notify-detail-url", notice["notify-detail-url"]) } ) } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlTemplate.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlTemplate.kt index 120241ad291..586e266099e 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlTemplate.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlTemplate.kt @@ -28,7 +28,9 @@ package com.tencent.devops.process.yaml.v2.parsers.template import com.fasterxml.jackson.core.JsonProcessingException +import com.fasterxml.jackson.core.type.TypeReference import com.tencent.devops.common.api.constant.CommonMessageCode.ERROR_YAML_FORMAT_EXCEPTION_LENGTH_LIMIT_EXCEEDED +import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.pojo.YamlVersion @@ -37,6 +39,8 @@ import com.tencent.devops.process.yaml.v2.exception.YamlFormatException import com.tencent.devops.process.yaml.v2.models.Extends import com.tencent.devops.process.yaml.v2.models.GitNotices import com.tencent.devops.process.yaml.v2.models.ITemplateFilter +import com.tencent.devops.process.yaml.v2.models.PacNotices +import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYaml import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYamlI import com.tencent.devops.process.yaml.v2.models.PreTemplateScriptBuildYaml import com.tencent.devops.process.yaml.v2.models.Repositories @@ -225,12 +229,23 @@ class YamlTemplate( ) } // notices只用做一次模板替换没有嵌套模板 - if (templateObject["notices"] != null) { + if (templateObject["notices"] != null && preYamlObject is PreScriptBuildYaml) { val notices = mutableListOf() val temNotices = YamlObjects.transValue>>(filePath, "notices", templateObject["notices"]) temNotices.forEach { - notices.add(YamlObjects.getNotice(filePath, it)) + notices.add(YamlObjects.getNoticeV2(filePath, it)) + } + preYamlObject.notices = notices + } + + // notices只用做一次模板替换没有嵌套模板 + if (templateObject["notices"] != null && preYamlObject is PreScriptBuildYamlV3) { + val notices = mutableListOf() + val temNotices = + YamlObjects.transValue>>(filePath, "notices", templateObject["notices"]) + temNotices.forEach { + notices.add(YamlObjects.getNoticeV3(filePath, it)) } preYamlObject.notices = notices } @@ -247,14 +262,16 @@ class YamlTemplate( } private fun replaceTriggerOn( - triggerOn: List>, + triggerOn: Any, preYamlObject: PreScriptBuildYamlI, deepTree: TemplateDeepTreeNode ) { if (preYamlObject.yamlVersion() != YamlVersion.Version.V3_0) return - val triggerOnV3s = mutableListOf() - triggerOn.forEach { value -> - triggerOnV3s.add(YamlObjects.getTriggerOnV3(value)) + val triggerOnV3s = when (triggerOn) { + // 简写方式 + is Map<*, *> -> listOf(JsonUtil.anyTo(triggerOn, object : TypeReference() {})) + is List<*> -> JsonUtil.anyTo(triggerOn, object : TypeReference>() {}) + else -> null } (preYamlObject as PreScriptBuildYamlV3).triggerOn = triggerOnV3s } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreScriptBuildYamlV3.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreScriptBuildYamlV3.kt index f01aecdf956..a2fd2f23469 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreScriptBuildYamlV3.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreScriptBuildYamlV3.kt @@ -33,7 +33,7 @@ import com.fasterxml.jackson.annotation.JsonProperty import com.tencent.devops.process.yaml.pojo.YamlVersion import com.tencent.devops.process.yaml.v2.models.Concurrency import com.tencent.devops.process.yaml.v2.models.Extends -import com.tencent.devops.process.yaml.v2.models.GitNotices +import com.tencent.devops.process.yaml.v2.models.PacNotices import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYamlI import com.tencent.devops.process.yaml.v2.models.Resources import com.tencent.devops.process.yaml.v2.models.Variable @@ -61,7 +61,7 @@ data class PreScriptBuildYamlV3( override var steps: List? = null, override var extends: Extends? = null, override var resources: Resources?, - override var notices: List?, + var notices: List?, override var finally: Map? = null, override val concurrency: Concurrency? = null ) : PreScriptBuildYamlI { diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYamlV3.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYamlV3.kt index 68b3480d317..baa4fc15a0a 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYamlV3.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYamlV3.kt @@ -31,13 +31,15 @@ import com.fasterxml.jackson.annotation.JsonIgnore import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.core.type.TypeReference import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.process.yaml.pojo.YamlVersion import com.tencent.devops.process.yaml.v2.models.Concurrency import com.tencent.devops.process.yaml.v2.models.Extends -import com.tencent.devops.process.yaml.v2.models.GitNotices import com.tencent.devops.process.yaml.v2.models.IPreTemplateScriptBuildYaml import com.tencent.devops.process.yaml.v2.models.ITemplateFilter +import com.tencent.devops.process.yaml.v2.models.PacNotices import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYamlI import com.tencent.devops.process.yaml.v2.models.Resources import com.tencent.devops.process.yaml.v2.models.Variable @@ -55,14 +57,14 @@ data class PreTemplateScriptBuildYamlV3( override val name: String?, override val label: List? = null, @JsonProperty("on") - var triggerOn: List?, + var triggerOn: Any?, override val variables: Map?, override val stages: List>?, override val jobs: Map? = null, override val steps: List>? = null, override val extends: Extends?, override val resources: Resources?, - override val notices: List?, + override val notices: List?, override var finally: Map?, override val concurrency: Concurrency? = null ) : IPreTemplateScriptBuildYaml, ITemplateFilter { @@ -73,7 +75,7 @@ data class PreTemplateScriptBuildYamlV3( version = version, name = name, label = label, - triggerOn = triggerOn, + triggerOn = makeRunsOn(), resources = resources, notices = notices, concurrency = concurrency @@ -96,7 +98,8 @@ data class PreTemplateScriptBuildYamlV3( } override fun formatTriggerOn(default: ScmType): Map { - return triggerOn?.associateBy({ it.type ?: default }, { ScriptYmlUtils.formatTriggerOn(it) }) ?: emptyMap() + return makeRunsOn()?.associateBy({ ScmType.parse(it.type) ?: default }, { ScriptYmlUtils.formatTriggerOn(it) }) + ?: emptyMap() } override fun formatStages(): List { @@ -117,4 +120,17 @@ data class PreTemplateScriptBuildYamlV3( private fun checkInitialized() { if (!this::preYaml.isInitialized) throw RuntimeException("need replaceTemplate before") } + + private fun makeRunsOn(): List? { + if (triggerOn == null) return null + // 简写方式 + if (triggerOn is Map<*, *>) { + val new = JsonUtil.anyTo(triggerOn, object : TypeReference() {}) + return listOf(new) + } + if (triggerOn is List<*>) { + return JsonUtil.anyTo(triggerOn, object : TypeReference>() {}) + } + return null + } } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PreTriggerOnV3.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PreTriggerOnV3.kt index b8a4c91e4f4..d8c0e8b4a55 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PreTriggerOnV3.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PreTriggerOnV3.kt @@ -30,7 +30,6 @@ package com.tencent.devops.process.yaml.v3.models.on import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty -import com.tencent.devops.common.api.enums.ScmType import com.tencent.devops.process.yaml.pojo.YamlVersion import com.tencent.devops.process.yaml.v2.models.on.DeleteRule import com.tencent.devops.process.yaml.v2.models.on.IPreTriggerOn @@ -45,7 +44,7 @@ import io.swagger.annotations.ApiModelProperty data class PreTriggerOnV3( val name: String?, var repoHashId: String?, - var type: ScmType?, + var type: String?, val credentials: String?, override val push: Any?, override val tag: Any?, diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/classify/PipelineGroup.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/classify/PipelineGroup.kt index 9cfe7b60598..ad10d96180b 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/classify/PipelineGroup.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/classify/PipelineGroup.kt @@ -30,9 +30,9 @@ package com.tencent.devops.process.pojo.classify import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty -@ApiModel("流水线模型") +@ApiModel("流水线标签组模型") data class PipelineGroup( - @ApiModelProperty("流水线id", required = false) + @ApiModelProperty("id", required = false) val id: String, @ApiModelProperty("项目id", required = false) val projectId: String, diff --git a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/pojo/ManualPreScriptBuildYaml.kt b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/pojo/ManualPreScriptBuildYaml.kt index 7ec61158284..b012e43df6c 100644 --- a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/pojo/ManualPreScriptBuildYaml.kt +++ b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/pojo/ManualPreScriptBuildYaml.kt @@ -60,7 +60,7 @@ class ManualPreScriptBuildYaml( override var steps: List? = null, override var extends: Extends? = null, override var resources: Resources?, - override var notices: List?, + var notices: List?, override var finally: Map? = null, override val concurrency: Concurrency? = null ) : PreScriptBuildYamlI { From c5906648dbf007ed1f21ff9ee12f4f5cdbf10648 Mon Sep 17 00:00:00 2001 From: yongyiduan Date: Tue, 22 Aug 2023 17:56:01 +0800 Subject: [PATCH 080/852] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=BB=BA/?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=BB=A5=20Code=20=E6=96=B9=E5=BC=8F=E7=BC=96=E6=8E=92?= =?UTF-8?q?=E6=B5=81=E6=B0=B4=E7=BA=BF=20#8125=20core?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/tencent/devops/process/yaml/v2/models/Notices.kt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Notices.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Notices.kt index 32ede2a89e1..12a3abb0a3b 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Notices.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Notices.kt @@ -30,11 +30,10 @@ package com.tencent.devops.process.yaml.v2.models import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty -import com.tencent.devops.process.pojo.pipeline.PipelineSubscriptionType -import com.tencent.devops.process.pojo.setting.Subscription +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSubscriptionType +import com.tencent.devops.common.pipeline.pojo.setting.Subscription import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault import io.swagger.annotations.ApiModelProperty -import java.util.TreeSet /** * model Stream 通知类型基类 From fca38ec9d320574739a63a8112a739acb6337be3 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Wed, 23 Aug 2023 10:05:44 +0800 Subject: [PATCH 081/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E4=BC=98=E5=8C=96=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/api/user/UserPipelineResource.kt | 19 ------- .../api/user/UserPipelineVersionResource.kt | 21 ++++++++ .../process/engine/pojo/PipelineResVersion.kt | 2 +- .../process/api/UserPipelineResourceImpl.kt | 45 +--------------- .../api/UserPipelineVersionResourceImpl.kt | 52 +++++++++++++++++++ 5 files changed, 75 insertions(+), 64 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt index 50e399b1047..13d7e81aa1a 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt @@ -267,25 +267,6 @@ interface UserPipelineResource { includeDraft: Boolean? = false ): Result - // TODO 当前版本(草稿分开给)、是否为实例化、取掉setting model - @ApiOperation("获取流水线编排和设置") - @GET - @Path("/projects/{projectId}/pipelines/{pipelineId}/resource") - fun getPipelineResourceAndSetting( - @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) - @HeaderParam(AUTH_HEADER_USER_ID) - userId: String, - @ApiParam("项目ID", required = true) - @PathParam("projectId") - projectId: String, - @ApiParam("流水线ID", required = true) - @PathParam("pipelineId") - pipelineId: String, - @QueryParam("draft") - @DefaultValue("false") - includeDraft: Boolean? = false - ): Result - @ApiOperation("获取流水线编排版本") @GET @Path("/{projectId}/{pipelineId}/{version}") diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 76f819d102e..89bb268d945 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -36,12 +36,14 @@ import com.tencent.devops.common.pipeline.pojo.TemplateInstanceCreateRequest import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult +import com.tencent.devops.process.pojo.setting.PipelineResourceAndSetting import com.tencent.devops.process.pojo.transfer.PreviewResponse import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation import io.swagger.annotations.ApiParam import javax.validation.Valid import javax.ws.rs.Consumes +import javax.ws.rs.DefaultValue import javax.ws.rs.GET import javax.ws.rs.HeaderParam import javax.ws.rs.POST @@ -58,6 +60,25 @@ import javax.ws.rs.core.MediaType @Suppress("LongParameterList") interface UserPipelineVersionResource { + // TODO #8161 当前版本(草稿分开给)、是否为实例化、取掉setting model + @ApiOperation("获取流水线编排和设置") + @GET + @Path("/projects/{projectId}/pipelines/{pipelineId}/resource") + fun getPipelineResourceAndSetting( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("流水线ID", required = true) + @PathParam("pipelineId") + pipelineId: String, + @QueryParam("draft") + @DefaultValue("false") + includeDraft: Boolean? = false + ): Result + @ApiOperation("通过指定模板创建流水线") @POST @Path("/projects/{projectId}/createPipelineWithTemplate") diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt index ee59dd18268..2b6c0a7bccf 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt @@ -50,7 +50,7 @@ data class PipelineResVersion( val createTime: Long = 0, @ApiModelProperty("更新时间") val updateTime: Long = 0, - @ApiModelProperty("创建者") + @ApiModelProperty("版本创建者") val creator: String, @ApiModelProperty("上一次的更新者") val lastModifyUser: String, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index a4b07dd7558..75a4e340c88 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -362,50 +362,6 @@ class UserPipelineResourceImpl @Autowired constructor( return Result(pipeline) } - override fun getPipelineResourceAndSetting( - userId: String, - projectId: String, - pipelineId: String, - includeDraft: Boolean? - ): Result { - checkParam(userId, projectId) - val detailInfo = pipelineListFacadeService.getPipelineDetail(userId, projectId, pipelineId) - val resource = pipelineInfoFacadeService.getPipelineResourceVersion( - userId = userId, - projectId = projectId, - pipelineId = pipelineId, - includeDraft = includeDraft, - channelCode = ChannelCode.BS - ) - val setting = pipelineSettingFacadeService.userGetSetting( - userId = userId, - projectId = projectId, - pipelineId = pipelineId, - version = resource.settingVersion ?: resource.version, - detailInfo = detailInfo - ) - pipelineRecentUseService.record(userId, projectId, pipelineId) - return Result( - PipelineResourceAndSetting( - pipelineInfo = detailInfo?.let { - PipelineDetail( - pipelineId = it.pipelineId, - pipelineName = it.pipelineName, - hasCollect = it.hasCollect, - canManualStartup = it.canManualStartup, - hasPermission = it.hasPermission, - pipelineDesc = it.pipelineDesc, - creator = it.creator, - createTime = it.createTime, - updateTime = it.updateTime, - viewNames = it.viewNames - ) - }, - pipelineResource = resource, - setting = setting - ) - ) - } override fun getVersion(userId: String, projectId: String, pipelineId: String, version: Int): Result { checkParam(userId, projectId) @@ -420,6 +376,7 @@ class UserPipelineResourceImpl @Autowired constructor( ) } + override fun generateRemoteToken( userId: String, projectId: String, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index dab3fe45bbd..18c2e44abe9 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -35,6 +35,7 @@ import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.auth.api.AuthResourceType +import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.PipelineModelAndYaml import com.tencent.devops.common.pipeline.enums.ChannelCode import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting @@ -50,12 +51,16 @@ import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.audit.Audit import com.tencent.devops.process.constant.ProcessMessageCode import com.tencent.devops.process.engine.service.PipelineRepositoryService +import com.tencent.devops.process.pojo.PipelineDetail import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult +import com.tencent.devops.process.pojo.setting.PipelineResourceAndSetting import com.tencent.devops.process.pojo.transfer.PreviewResponse import com.tencent.devops.process.pojo.transfer.TransferActionType import com.tencent.devops.process.pojo.transfer.TransferBody import com.tencent.devops.process.service.PipelineInfoFacadeService +import com.tencent.devops.process.service.PipelineListFacadeService import com.tencent.devops.process.service.PipelineOperationLogService +import com.tencent.devops.process.service.PipelineRecentUseService import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService import com.tencent.devops.process.service.template.TemplateFacadeService import com.tencent.devops.process.service.transfer.PipelineTransferYamlService @@ -64,6 +69,7 @@ import org.springframework.beans.factory.annotation.Autowired @RestResource @Suppress("ALL") class UserPipelineVersionResourceImpl @Autowired constructor( + private val pipelineListFacadeService: PipelineListFacadeService, private val pipelineSettingFacadeService: PipelineSettingFacadeService, private val pipelinePermissionService: PipelinePermissionService, private val pipelineInfoFacadeService: PipelineInfoFacadeService, @@ -72,9 +78,55 @@ class UserPipelineVersionResourceImpl @Autowired constructor( private val pipelineOperationLogService: PipelineOperationLogService, private val transferService: PipelineTransferYamlService, private val pipelineRepositoryService: PipelineRepositoryService, + private val pipelineRecentUseService: PipelineRecentUseService, private val templateFacadeService: TemplateFacadeService ) : UserPipelineVersionResource { + override fun getPipelineResourceAndSetting( + userId: String, + projectId: String, + pipelineId: String, + includeDraft: Boolean? + ): Result { + checkParam(userId, projectId) + val detailInfo = pipelineListFacadeService.getPipelineDetail(userId, projectId, pipelineId) + val resource = pipelineInfoFacadeService.getPipelineResourceVersion( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + includeDraft = includeDraft, + channelCode = ChannelCode.BS + ) + val setting = pipelineSettingFacadeService.userGetSetting( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + version = resource.settingVersion ?: resource.version, + detailInfo = detailInfo + ) + pipelineRecentUseService.record(userId, projectId, pipelineId) + return Result( + PipelineResourceAndSetting( + pipelineInfo = detailInfo?.let { + PipelineDetail( + pipelineId = it.pipelineId, + pipelineName = it.pipelineName, + hasCollect = it.hasCollect, + canManualStartup = it.canManualStartup, + hasPermission = it.hasPermission, + pipelineDesc = it.pipelineDesc, + creator = it.creator, + createTime = it.createTime, + updateTime = it.updateTime, + viewNames = it.viewNames + ) + }, + pipelineResource = resource, + setting = setting + ) + ) + } + override fun createPipelineFromTemplate( userId: String, projectId: String, From 912324843f5eecad8eb727d6a82cc697985ae041 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 24 Aug 2023 14:49:02 +0800 Subject: [PATCH 082/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E5=A2=9E=E5=8A=A0=E5=89=8D=E7=AB=AF=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E5=AD=97=E6=AE=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/pipeline/PipelineModelWithYaml.kt | 44 +++++++++++++++++++ ...aml.kt => PipelineModelWithYamlRequest.kt} | 10 ++--- .../api/user/UserPipelineVersionResource.kt | 7 +-- .../api/UserPipelineVersionResourceImpl.kt | 13 +++--- 4 files changed, 59 insertions(+), 15 deletions(-) create mode 100644 src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelWithYaml.kt rename src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/{PipelineModelAndYaml.kt => PipelineModelWithYamlRequest.kt} (89%) diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelWithYaml.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelWithYaml.kt new file mode 100644 index 00000000000..38bf51a54a9 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelWithYaml.kt @@ -0,0 +1,44 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.common.pipeline + +import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting +import io.swagger.annotations.ApiModelProperty + +data class PipelineModelWithYaml( + @ApiModelProperty("版本号(流水线唯一递增)", required = true) + val version: Int, + @ApiModelProperty("版本名称", required = true) + val versionName: String?, + @ApiModelProperty("流水线模型", required = true) + val modelAndSetting: PipelineModelAndSetting, + @ApiModelProperty("流水线YAML编排(不为空时以YAML为准)", required = false) + val yaml: String?, + @ApiModelProperty("版本变更说明", required = false) + val description: String? +) diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelWithYamlRequest.kt similarity index 89% rename from src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt rename to src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelWithYamlRequest.kt index fa606ab6793..3324134d79d 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelAndYaml.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelWithYamlRequest.kt @@ -30,15 +30,13 @@ package com.tencent.devops.common.pipeline import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting import io.swagger.annotations.ApiModelProperty -data class PipelineModelAndYaml( +data class PipelineModelWithYamlRequest( + @ApiModelProperty("草稿的来源版本(前端保存时传递)", required = true) + val baseVersion: Int, @ApiModelProperty("流水线模型", required = true) val modelAndSetting: PipelineModelAndSetting, @ApiModelProperty("流水线YAML编排(不为空时以YAML为准)", required = false) val yaml: String?, @ApiModelProperty("版本变更说明", required = false) - val description: String? = null, - @ApiModelProperty("草稿的来源版本", required = false) - val baseVersion: Int, - @ApiModelProperty("草稿的来源版本名称", required = false) - val baseVersionName: String? + val description: String? = null ) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 89bb268d945..672bc7fd3e2 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -31,7 +31,8 @@ import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE import com.tencent.devops.common.api.pojo.Page import com.tencent.devops.common.api.pojo.Result -import com.tencent.devops.common.pipeline.PipelineModelAndYaml +import com.tencent.devops.common.pipeline.PipelineModelWithYaml +import com.tencent.devops.common.pipeline.PipelineModelWithYamlRequest import com.tencent.devops.common.pipeline.pojo.TemplateInstanceCreateRequest import com.tencent.devops.process.engine.pojo.PipelineResVersion import com.tencent.devops.process.pojo.PipelineOperationDetail @@ -109,7 +110,7 @@ interface UserPipelineVersionResource { @ApiParam("流水线编排版本", required = true) @PathParam("version") version: Int - ): Result + ): Result @ApiOperation("触发前配置") @GET @@ -144,7 +145,7 @@ interface UserPipelineVersionResource { pipelineId: String, @ApiParam(value = "流水线模型与设置", required = true) @Valid - modelAndYaml: PipelineModelAndYaml + modelAndYaml: PipelineModelWithYamlRequest ): Result @ApiOperation("获取流水线编排创建人列表(分页)") diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index 18c2e44abe9..c8ad195ec4f 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -36,7 +36,8 @@ import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.auth.api.AuthResourceType import com.tencent.devops.common.pipeline.Model -import com.tencent.devops.common.pipeline.PipelineModelAndYaml +import com.tencent.devops.common.pipeline.PipelineModelWithYaml +import com.tencent.devops.common.pipeline.PipelineModelWithYamlRequest import com.tencent.devops.common.pipeline.enums.ChannelCode import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting import com.tencent.devops.common.pipeline.pojo.TemplateInstanceCreateRequest @@ -164,7 +165,7 @@ class UserPipelineVersionResourceImpl @Autowired constructor( projectId: String, pipelineId: String, version: Int - ): Result { + ): Result { val permission = AuthPermission.VIEW pipelinePermissionService.validPipelinePermission( userId = userId, @@ -209,12 +210,12 @@ class UserPipelineVersionResourceImpl @Autowired constructor( data = TransferBody(modelAndSetting) ).newYaml return Result( - PipelineModelAndYaml( + PipelineModelWithYaml( modelAndSetting = modelAndSetting, yaml = yaml, description = resource.description, - baseVersion = resource.version, - baseVersionName = resource.versionName + version = resource.version, + versionName = resource.versionName ) ) } @@ -251,7 +252,7 @@ class UserPipelineVersionResourceImpl @Autowired constructor( userId: String, projectId: String, pipelineId: String, - modelAndYaml: PipelineModelAndYaml + modelAndYaml: PipelineModelWithYamlRequest ): Result { checkParam(userId, projectId) val permission = AuthPermission.EDIT From ca95e783d3073c0f5cf7410fbe3b0035f096cbc3 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 24 Aug 2023 14:50:13 +0800 Subject: [PATCH 083/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E7=89=88=E6=9C=AC=E8=AE=A1=E7=AE=97=E5=BC=82?= =?UTF-8?q?=E5=B8=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/service/pipeline/PipelineSettingFacadeService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt index bb16bbb847c..e14fd10eef8 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt @@ -123,7 +123,7 @@ class PipelineSettingFacadeService @Autowired constructor( projectId = projectId, pipelineId = pipelineId )?.let { origin -> - PipelineVersionUtils.getSettingVersion(setting.version, setting, origin) + PipelineVersionUtils.getSettingVersion(origin.version, origin, setting) } ?: 1 val pipelineName = pipelineRepositoryService.saveSetting( From 22476b464c7bccfd8681c516731b4b382b67cf17 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 24 Aug 2023 16:24:05 +0800 Subject: [PATCH 084/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E6=94=B9=E8=BF=9Bdetail=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../inner/TransferCreatorImpl.kt | 3 +- .../yaml/pojo/ThirdPartyContainerInfo.kt | 2 +- .../process/api/user/UserPipelineResource.kt | 1 - .../api/user/UserPipelineVersionResource.kt | 8 +-- .../devops/process/pojo/PipelineDetail.kt | 6 +++ .../process/api/UserPipelineResourceImpl.kt | 4 -- .../api/UserPipelineVersionResourceImpl.kt | 52 ++++++++----------- 7 files changed, 33 insertions(+), 43 deletions(-) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreatorImpl.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreatorImpl.kt index 05557d6cd23..3ffe994096d 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreatorImpl.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreatorImpl.kt @@ -39,8 +39,7 @@ import javax.ws.rs.core.Response @Primary @Component -class TransferCreatorImpl @Autowired constructor( -) : TransferCreator { +class TransferCreatorImpl @Autowired constructor() : TransferCreator { @Value("\${marketRun.enable:#{false}}") private val marketRunTaskData: Boolean = false diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/ThirdPartyContainerInfo.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/ThirdPartyContainerInfo.kt index 5831dbd89ca..232677e13fd 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/ThirdPartyContainerInfo.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/pojo/ThirdPartyContainerInfo.kt @@ -38,5 +38,5 @@ data class ThirdPartyContainerInfo( val acrossTemplateId: String?, val options: DockerOptions?, val imagePullPolicy: String?, - val imageType: ImageType? = ImageType.THIRD, + val imageType: ImageType? = ImageType.THIRD ) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt index 13d7e81aa1a..f9e11c91cae 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt @@ -51,7 +51,6 @@ import com.tencent.devops.process.pojo.classify.PipelineViewPipelinePage import com.tencent.devops.process.pojo.pipeline.BatchDeletePipeline import com.tencent.devops.process.pojo.pipeline.PipelineCount import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting -import com.tencent.devops.process.pojo.setting.PipelineResourceAndSetting import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index 672bc7fd3e2..e113e1eeeb5 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -35,9 +35,9 @@ import com.tencent.devops.common.pipeline.PipelineModelWithYaml import com.tencent.devops.common.pipeline.PipelineModelWithYamlRequest import com.tencent.devops.common.pipeline.pojo.TemplateInstanceCreateRequest import com.tencent.devops.process.engine.pojo.PipelineResVersion +import com.tencent.devops.process.pojo.PipelineDetail import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult -import com.tencent.devops.process.pojo.setting.PipelineResourceAndSetting import com.tencent.devops.process.pojo.transfer.PreviewResponse import io.swagger.annotations.Api import io.swagger.annotations.ApiOperation @@ -62,9 +62,9 @@ import javax.ws.rs.core.MediaType interface UserPipelineVersionResource { // TODO #8161 当前版本(草稿分开给)、是否为实例化、取掉setting model - @ApiOperation("获取流水线编排和设置") + @ApiOperation("获取流水线信息") @GET - @Path("/projects/{projectId}/pipelines/{pipelineId}/resource") + @Path("/projects/{projectId}/pipelines/{pipelineId}/detail") fun getPipelineResourceAndSetting( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) @@ -78,7 +78,7 @@ interface UserPipelineVersionResource { @QueryParam("draft") @DefaultValue("false") includeDraft: Boolean? = false - ): Result + ): Result @ApiOperation("通过指定模板创建流水线") @POST diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetail.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetail.kt index 4e29e3c225d..e24822e7f56 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetail.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetail.kt @@ -40,6 +40,12 @@ data class PipelineDetail( val hasCollect: Boolean, @ApiModelProperty("是否可以手动触发") val canManualStartup: Boolean, + @ApiModelProperty("是否从模板实例化") + val instanceFromTemplate: Boolean, + @ApiModelProperty("最新的发布版本(只有草稿则为空)") + val latestVersion: Int?, + @ApiModelProperty("最新的发布版本名称(只有草稿则为空)") + val latestVersionName: String?, @ApiModelProperty("是否有编辑权限") val hasPermission: Boolean, @ApiModelProperty("流水线描述") diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index 75a4e340c88..93090431112 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -57,7 +57,6 @@ import com.tencent.devops.process.pojo.Permission import com.tencent.devops.process.pojo.Pipeline import com.tencent.devops.process.pojo.PipelineCollation import com.tencent.devops.process.pojo.PipelineCopy -import com.tencent.devops.process.pojo.PipelineDetail import com.tencent.devops.process.pojo.PipelineId import com.tencent.devops.process.pojo.PipelineName import com.tencent.devops.process.pojo.PipelineRemoteToken @@ -72,7 +71,6 @@ import com.tencent.devops.process.pojo.pipeline.BatchDeletePipeline import com.tencent.devops.process.pojo.pipeline.PipelineCount import com.tencent.devops.process.pojo.pipeline.enums.PipelineRuleBusCodeEnum import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting -import com.tencent.devops.process.pojo.setting.PipelineResourceAndSetting import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.engine.service.PipelineRepositoryService.Companion.checkParam import com.tencent.devops.process.service.PipelineInfoFacadeService @@ -362,7 +360,6 @@ class UserPipelineResourceImpl @Autowired constructor( return Result(pipeline) } - override fun getVersion(userId: String, projectId: String, pipelineId: String, version: Int): Result { checkParam(userId, projectId) return Result( @@ -376,7 +373,6 @@ class UserPipelineResourceImpl @Autowired constructor( ) } - override fun generateRemoteToken( userId: String, projectId: String, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index c8ad195ec4f..86a520585c8 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -35,7 +35,6 @@ import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.auth.api.AuthResourceType -import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.PipelineModelWithYaml import com.tencent.devops.common.pipeline.PipelineModelWithYamlRequest import com.tencent.devops.common.pipeline.enums.ChannelCode @@ -54,7 +53,6 @@ import com.tencent.devops.process.constant.ProcessMessageCode import com.tencent.devops.process.engine.service.PipelineRepositoryService import com.tencent.devops.process.pojo.PipelineDetail import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult -import com.tencent.devops.process.pojo.setting.PipelineResourceAndSetting import com.tencent.devops.process.pojo.transfer.PreviewResponse import com.tencent.devops.process.pojo.transfer.TransferActionType import com.tencent.devops.process.pojo.transfer.TransferBody @@ -88,42 +86,34 @@ class UserPipelineVersionResourceImpl @Autowired constructor( projectId: String, pipelineId: String, includeDraft: Boolean? - ): Result { + ): Result { checkParam(userId, projectId) val detailInfo = pipelineListFacadeService.getPipelineDetail(userId, projectId, pipelineId) - val resource = pipelineInfoFacadeService.getPipelineResourceVersion( - userId = userId, - projectId = projectId, - pipelineId = pipelineId, - includeDraft = includeDraft, - channelCode = ChannelCode.BS - ) - val setting = pipelineSettingFacadeService.userGetSetting( - userId = userId, + ?: throw ErrorCodeException( + errorCode = ProcessMessageCode.ERROR_NO_PIPELINE_EXISTS_BY_ID, + params = arrayOf(pipelineId) + ) + val latestResource = pipelineRepositoryService.getPipelineResourceVersion( projectId = projectId, pipelineId = pipelineId, - version = resource.settingVersion ?: resource.version, - detailInfo = detailInfo + includeDraft = includeDraft ) pipelineRecentUseService.record(userId, projectId, pipelineId) return Result( - PipelineResourceAndSetting( - pipelineInfo = detailInfo?.let { - PipelineDetail( - pipelineId = it.pipelineId, - pipelineName = it.pipelineName, - hasCollect = it.hasCollect, - canManualStartup = it.canManualStartup, - hasPermission = it.hasPermission, - pipelineDesc = it.pipelineDesc, - creator = it.creator, - createTime = it.createTime, - updateTime = it.updateTime, - viewNames = it.viewNames - ) - }, - pipelineResource = resource, - setting = setting + PipelineDetail( + pipelineId = detailInfo.pipelineId, + pipelineName = detailInfo.pipelineName, + hasCollect = detailInfo.hasCollect, + instanceFromTemplate = detailInfo.instanceFromTemplate, + canManualStartup = detailInfo.canManualStartup, + hasPermission = detailInfo.hasPermission, + pipelineDesc = detailInfo.pipelineDesc, + creator = detailInfo.creator, + createTime = detailInfo.createTime, + updateTime = detailInfo.updateTime, + viewNames = detailInfo.viewNames, + latestVersion = latestResource?.version, + latestVersionName = latestResource?.versionName ) ) } From 8998f89b54c331d5d8b844a35fd01f001cede648 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 24 Aug 2023 16:53:05 +0800 Subject: [PATCH 085/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E6=94=B9=E8=BF=9Bdetail=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/user/UserPipelineVersionResource.kt | 3 +-- .../devops/process/pojo/PipelineDetail.kt | 9 ++++++--- .../api/UserPipelineVersionResourceImpl.kt | 16 +++++++++++++--- 3 files changed, 20 insertions(+), 8 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index e113e1eeeb5..c8ef8b7eb3f 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -61,11 +61,10 @@ import javax.ws.rs.core.MediaType @Suppress("LongParameterList") interface UserPipelineVersionResource { - // TODO #8161 当前版本(草稿分开给)、是否为实例化、取掉setting model @ApiOperation("获取流水线信息") @GET @Path("/projects/{projectId}/pipelines/{pipelineId}/detail") - fun getPipelineResourceAndSetting( + fun getPipelineDetail( @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) @HeaderParam(AUTH_HEADER_USER_ID) userId: String, diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetail.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetail.kt index e24822e7f56..a4ee92a2ada 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetail.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/PipelineDetail.kt @@ -27,6 +27,7 @@ package com.tencent.devops.process.pojo +import com.tencent.devops.common.pipeline.pojo.setting.PipelineRunLockType import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @@ -43,9 +44,9 @@ data class PipelineDetail( @ApiModelProperty("是否从模板实例化") val instanceFromTemplate: Boolean, @ApiModelProperty("最新的发布版本(只有草稿则为空)") - val latestVersion: Int?, + val version: Int?, @ApiModelProperty("最新的发布版本名称(只有草稿则为空)") - val latestVersionName: String?, + val versionName: String?, @ApiModelProperty("是否有编辑权限") val hasPermission: Boolean, @ApiModelProperty("流水线描述") @@ -57,5 +58,7 @@ data class PipelineDetail( @ApiModelProperty("更新时间") val updateTime: Long = 0, @ApiModelProperty("流水线组名称列表", required = false) - var viewNames: List? = null + var viewNames: List? = null, + @ApiModelProperty("Lock 类型", required = false) + val runLockType: PipelineRunLockType? = null ) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index 86a520585c8..6d8b80e12fe 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -81,7 +81,7 @@ class UserPipelineVersionResourceImpl @Autowired constructor( private val templateFacadeService: TemplateFacadeService ) : UserPipelineVersionResource { - override fun getPipelineResourceAndSetting( + override fun getPipelineDetail( userId: String, projectId: String, pipelineId: String, @@ -98,6 +98,15 @@ class UserPipelineVersionResourceImpl @Autowired constructor( pipelineId = pipelineId, includeDraft = includeDraft ) + val setting = latestResource?.let { + pipelineSettingFacadeService.userGetSetting( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + version = latestResource.settingVersion ?: latestResource.version, + detailInfo = detailInfo + ) + } pipelineRecentUseService.record(userId, projectId, pipelineId) return Result( PipelineDetail( @@ -112,8 +121,9 @@ class UserPipelineVersionResourceImpl @Autowired constructor( createTime = detailInfo.createTime, updateTime = detailInfo.updateTime, viewNames = detailInfo.viewNames, - latestVersion = latestResource?.version, - latestVersionName = latestResource?.versionName + version = latestResource?.version, + versionName = latestResource?.versionName, + runLockType = setting?.runLockType ) ) } From 4acf2988e66d5e76d0e4d49b8862f272ba1b69c8 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Fri, 25 Aug 2023 17:24:44 +0800 Subject: [PATCH 086/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E6=96=B0=E5=A2=9E=E8=8D=89=E7=A8=BF=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/ServicePipelineVersionResource.kt | 4 +- .../process/api/user/UserPipelineResource.kt | 4 +- .../api/user/UserPipelineVersionResource.kt | 5 +- ...neResVersion.kt => PipelineVersionInfo.kt} | 10 +-- .../pojo/pipeline/PipelineResourceVersion.kt | 4 +- .../pojo/setting/PipelineVersionSimple.kt | 4 +- ...pelineResDao.kt => PipelineResourceDao.kt} | 4 +- ...onDao.kt => PipelineResourceVersionDao.kt} | 13 ++- .../service/PipelineRepositoryService.kt | 88 +++++++++++-------- .../PipelineRepositoryVersionService.kt | 36 ++++---- .../service/record/BaseBuildRecordService.kt | 12 +-- .../record/ContainerBuildRecordService.kt | 12 +-- .../record/PipelineBuildRecordService.kt | 12 +-- .../service/record/StageBuildRecordService.kt | 12 +-- .../service/record/TaskBuildRecordService.kt | 12 +-- .../service/PipelineOperationLogService.kt | 6 +- .../api/ServicePipelineVersionResourceImpl.kt | 4 +- .../process/api/UserPipelineResourceImpl.kt | 4 +- .../api/UserPipelineVersionResourceImpl.kt | 4 +- .../engine/service/AgentPipelineRefService.kt | 6 +- .../service/PipelineAtomStatisticsService.kt | 6 +- .../service/PipelineVersionFacadeService.kt | 4 +- .../engine/service/PipelineWebhookService.kt | 6 +- .../service/PipelineAtomReplaceCronService.kt | 8 +- .../PipelineAtomRollBackCronService.kt | 2 + .../service/PipelineInfoFacadeService.kt | 14 ++- .../service/template/TemplateFacadeService.kt | 10 +-- 27 files changed, 167 insertions(+), 139 deletions(-) rename src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/{PipelineResVersion.kt => PipelineVersionInfo.kt} (92%) rename src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/{PipelineResDao.kt => PipelineResourceDao.kt} (99%) rename src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/{PipelineResVersionDao.kt => PipelineResourceVersionDao.kt} (97%) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt index 59bf3b34a74..94905f035ec 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineVersionResource.kt @@ -33,7 +33,7 @@ import com.tencent.devops.common.api.pojo.Page import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.enums.ChannelCode -import com.tencent.devops.process.engine.pojo.PipelineResVersion +import com.tencent.devops.process.engine.pojo.PipelineVersionInfo import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import io.swagger.annotations.Api @@ -153,7 +153,7 @@ interface ServicePipelineVersionResource { @ApiParam("渠道号,默认为BS", required = false) @QueryParam("channelCode") channelCode: ChannelCode - ): Result> + ): Result> @ApiOperation("获取流水线操作日志列表(分页)") @GET diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt index f9e11c91cae..f4eb6eb1e3d 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt @@ -34,7 +34,7 @@ import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.pojo.MatrixPipelineInfo import com.tencent.devops.process.engine.pojo.PipelineInfo -import com.tencent.devops.process.engine.pojo.PipelineResVersion +import com.tencent.devops.process.engine.pojo.PipelineVersionInfo import com.tencent.devops.process.pojo.Permission import com.tencent.devops.process.pojo.Pipeline import com.tencent.devops.process.pojo.PipelineCollation @@ -575,7 +575,7 @@ interface UserPipelineResource { @ApiParam("每页多少条", required = false, defaultValue = "20") @QueryParam("pageSize") pageSize: Int? - ): Result> + ): Result> @ApiOperation("校验matrix yaml格式") @POST diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index c8ef8b7eb3f..ab33395ca8e 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -34,7 +34,7 @@ import com.tencent.devops.common.api.pojo.Result import com.tencent.devops.common.pipeline.PipelineModelWithYaml import com.tencent.devops.common.pipeline.PipelineModelWithYamlRequest import com.tencent.devops.common.pipeline.pojo.TemplateInstanceCreateRequest -import com.tencent.devops.process.engine.pojo.PipelineResVersion +import com.tencent.devops.process.engine.pojo.PipelineVersionInfo import com.tencent.devops.process.pojo.PipelineDetail import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.pipeline.DeployPipelineResult @@ -168,6 +168,7 @@ interface UserPipelineVersionResource { pageSize: Int? ): Result> + // TODO 给出主路径的bool @ApiOperation("流水线编排版本列表(搜索、分页)") @GET @Path("/projects/{projectId}/pipelines/{pipelineId}/versions") @@ -199,7 +200,7 @@ interface UserPipelineVersionResource { @ApiParam("每页多少条", required = false, defaultValue = "5") @QueryParam("pageSize") pageSize: Int? - ): Result> + ): Result> @ApiOperation("获取流水线操作日志列表(分页)") @GET diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineVersionInfo.kt similarity index 92% rename from src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt rename to src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineVersionInfo.kt index 2b6c0a7bccf..4a6206f18d9 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineResVersion.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/engine/pojo/PipelineVersionInfo.kt @@ -33,7 +33,7 @@ import io.swagger.annotations.ApiModel import io.swagger.annotations.ApiModelProperty @ApiModel("流水线信息") -data class PipelineResVersion( +data class PipelineVersionInfo( @ApiModelProperty("项目ID") val projectId: String, @ApiModelProperty("流水线DI") @@ -76,10 +76,10 @@ data class PipelineResVersion( val triggerVersion: Int? = null, @ApiModelProperty("配置版本号", required = false) val settingVersion: Int? = null, - @ApiModelProperty("草稿版本标识", required = false) + @ApiModelProperty("草稿版本状态标识", required = false) val status: VersionStatus? = VersionStatus.RELEASED, + @ApiModelProperty("该版本的来源版本(空时一定为主路径)", required = false) + val baseVersion: Int? = null, @ApiModelProperty("调试构建ID", required = false) - val debugBuildId: String? = null, - @ApiModelProperty("来源代码库标识(分支名)", required = false) - val pacRefs: String? = null + val debugBuildId: String? = null ) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt index 2b8084c6f0f..36bbf79fbc7 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineResourceVersion.kt @@ -68,6 +68,6 @@ data class PipelineResourceVersion( val description: String? = null, @ApiModelProperty("调试构建ID", required = false) val debugBuildId: String? = null, - @ApiModelProperty("来源代码库标识(分支名)", required = false) - val pacRefs: String? = null + @ApiModelProperty("该版本的来源版本(空时一定为主路径)", required = false) + val baseVersion: Int? = null ) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineVersionSimple.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineVersionSimple.kt index 8b1faf127e1..bf3622b0803 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineVersionSimple.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineVersionSimple.kt @@ -57,6 +57,6 @@ data class PipelineVersionSimple( val status: VersionStatus? = VersionStatus.RELEASED, @ApiModelProperty("调试构建ID", required = false) val debugBuildId: String? = null, - @ApiModelProperty("来源代码库标识(分支名)", required = false) - val pacRefs: String? = null + @ApiModelProperty("该版本的来源版本(空时一定为主路径)", required = false) + val baseVersion: Int? = null ) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceDao.kt similarity index 99% rename from src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt rename to src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceDao.kt index 14ec8cfcb14..13abf5b2b94 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceDao.kt @@ -44,7 +44,7 @@ import java.time.LocalDateTime @Suppress("TooManyFunctions", "LongParameterList", "ReturnCount") @Repository -class PipelineResDao { +class PipelineResourceDao { fun create( dslContext: DSLContext, @@ -270,6 +270,6 @@ class PipelineResDao { } companion object { - private val logger = LoggerFactory.getLogger(PipelineResDao::class.java) + private val logger = LoggerFactory.getLogger(PipelineResourceDao::class.java) } } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceVersionDao.kt similarity index 97% rename from src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt rename to src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceVersionDao.kt index 15e4705f163..81421338a55 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceVersionDao.kt @@ -42,7 +42,7 @@ import java.time.LocalDateTime @Suppress("Unused", "LongParameterList", "ReturnCount", "TooManyFunctions") @Repository -class PipelineResVersionDao { +class PipelineResourceVersionDao { fun create( dslContext: DSLContext, @@ -52,6 +52,7 @@ class PipelineResVersionDao { version: Int, versionName: String, model: Model, + baseVersion: Int, yaml: String?, pipelineVersion: Int?, triggerVersion: Int?, @@ -68,6 +69,7 @@ class PipelineResVersionDao { versionName = versionName, modelStr = JsonUtil.toJson(model, formatted = false), yamlStr = yaml, + baseVersion = baseVersion, pipelineVersion = pipelineVersion, triggerVersion = triggerVersion, settingVersion = settingVersion, @@ -84,6 +86,7 @@ class PipelineResVersionDao { version: Int, versionName: String = "init", modelStr: String, + baseVersion: Int, yamlStr: String?, pipelineVersion: Int?, triggerVersion: Int?, @@ -106,10 +109,12 @@ class PipelineResVersionDao { .set(SETTING_VERSION, settingVersion) .set(STATUS, status?.name) .set(DESCRIPTION, description) + .set(BASE_VERSION, baseVersion) .onDuplicateKeyUpdate() .set(MODEL, modelStr) .set(CREATOR, creator) .set(VERSION_NAME, versionName) + .set(BASE_VERSION, baseVersion) .set(PIPELINE_VERSION, pipelineVersion) .set(TRIGGER_VERSION, triggerVersion) .set(SETTING_VERSION, settingVersion) @@ -184,7 +189,7 @@ class PipelineResVersionDao { status = record.status?.let { VersionStatus.valueOf(it) }, description = record.description, debugBuildId = record.debugBuildId, - pacRefs = record.refs + baseVersion = record.baseVersion ) } } @@ -259,7 +264,7 @@ class PipelineResVersionDao { settingVersion = record.settingVersion, status = record.status?.let { VersionStatus.valueOf(it) }, debugBuildId = record.debugBuildId, - pacRefs = record.refs + baseVersion = record.baseVersion ) ) } @@ -294,7 +299,7 @@ class PipelineResVersionDao { settingVersion = record.settingVersion, status = record.status?.let { VersionStatus.valueOf(it) }, debugBuildId = record.debugBuildId, - pacRefs = record.refs + baseVersion = record.baseVersion ) ) } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index 9c263f46afb..88f36a81aa8 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -68,8 +68,8 @@ import com.tencent.devops.process.engine.control.lock.PipelineModelLock import com.tencent.devops.process.engine.dao.PipelineBuildSummaryDao import com.tencent.devops.process.engine.dao.PipelineInfoDao import com.tencent.devops.process.engine.dao.PipelineModelTaskDao -import com.tencent.devops.process.engine.dao.PipelineResDao -import com.tencent.devops.process.engine.dao.PipelineResVersionDao +import com.tencent.devops.process.engine.dao.PipelineResourceDao +import com.tencent.devops.process.engine.dao.PipelineResourceVersionDao import com.tencent.devops.process.engine.dao.template.TemplatePipelineDao import com.tencent.devops.process.engine.pojo.PipelineInfo import com.tencent.devops.process.engine.pojo.PipelineModelTask @@ -127,14 +127,14 @@ class PipelineRepositoryService constructor( private val modelTaskIdGenerator: ModelTaskIdGenerator, private val dslContext: DSLContext, private val pipelineInfoDao: PipelineInfoDao, - private val pipelineResDao: PipelineResDao, + private val pipelineResourceDao: PipelineResourceDao, private val pipelineModelTaskDao: PipelineModelTaskDao, private val pipelineSettingDao: PipelineSettingDao, private val pipelineBuildSummaryDao: PipelineBuildSummaryDao, private val pipelineJobMutexGroupService: PipelineJobMutexGroupService, private val modelCheckPlugin: ModelCheckPlugin, private val templatePipelineDao: TemplatePipelineDao, - private val pipelineResVersionDao: PipelineResVersionDao, + private val pipelineResourceVersionDao: PipelineResourceVersionDao, private val pipelineSettingVersionDao: PipelineSettingVersionDao, private val pipelineViewGroupDao: PipelineViewGroupDao, private val versionConfigure: VersionConfigure, @@ -198,6 +198,8 @@ class PipelineRepositoryService constructor( userId: String, channelCode: ChannelCode, create: Boolean, + yamlStr: String?, + baseVersion: Int?, useSubscriptionSettings: Boolean? = false, useLabelSettings: Boolean? = false, useConcurrencyGroup: Boolean? = false, @@ -219,8 +221,6 @@ class PipelineRepositoryService constructor( create = create, channelCode = channelCode ) - // TODO 增加互转处理 - val yamlStr = null val buildNo = (model.stages[0].containers[0] as TriggerContainer).buildNo val triggerContainer = model.stages[0].containers[0] as TriggerContainer @@ -235,7 +235,7 @@ class PipelineRepositoryService constructor( } } } - + // TODO #8161 保存接口的 saveDraft 字段变成status枚举参数 return if (!create) { val pipelineSetting = savedSetting ?: pipelineSettingDao.getSetting(dslContext, projectId, pipelineId) @@ -253,7 +253,8 @@ class PipelineRepositoryService constructor( setting = pipelineSetting, updateLastModifyUser = updateLastModifyUser, saveDraft = saveDraft, - description = description + description = description, + baseVersion = baseVersion ) operationLogService.addOperationLog( userId = userId, @@ -286,7 +287,8 @@ class PipelineRepositoryService constructor( useConcurrencyGroup = useConcurrencyGroup, templateId = templateId, saveDraft = saveDraft, - description = description + description = description, + baseVersion = baseVersion ) operationLogService.addOperationLog( userId = userId, @@ -582,6 +584,7 @@ class PipelineRepositoryService constructor( canElementSkip: Boolean, buildNo: BuildNo?, modelTasks: Collection, + baseVersion: Int?, useSubscriptionSettings: Boolean? = false, useLabelSettings: Boolean? = false, useConcurrencyGroup: Boolean? = false, @@ -708,7 +711,7 @@ class PipelineRepositoryService constructor( versionName = PipelineVersionUtils.getVersionName( pipelineVersion, triggerVersion, settingVersion ) - if (saveDraft != true) pipelineResDao.create( + if (saveDraft != true) pipelineResourceDao.create( dslContext = transactionContext, projectId = projectId, pipelineId = pipelineId, @@ -721,7 +724,7 @@ class PipelineRepositoryService constructor( settingVersion = settingVersion ) // 同步记录到历史版本表 - pipelineResVersionDao.create( + pipelineResourceVersionDao.create( dslContext = transactionContext, projectId = projectId, pipelineId = pipelineId, @@ -729,6 +732,7 @@ class PipelineRepositoryService constructor( version = 1, model = model, yaml = yamlStr, + baseVersion = baseVersion ?: 0, versionName = versionName ?: "init", pipelineVersion = modelVersion, triggerVersion = triggerVersion, @@ -778,6 +782,7 @@ class PipelineRepositoryService constructor( setting: PipelineSetting? = null, updateLastModifyUser: Boolean? = true, saveDraft: Boolean? = false, + baseVersion: Int?, description: String? ): DeployPipelineResult { val taskCount: Int = model.taskCount() @@ -790,7 +795,8 @@ class PipelineRepositoryService constructor( dslContext.transaction { configuration -> val transactionContext = DSL.using(configuration) watcher.start("updatePipelineInfo") - version = if (updateLastModifyUser != null && updateLastModifyUser == false) { + // 写入INFO表后进行了version的自动+1 + version = if (updateLastModifyUser == false) { pipelineInfoDao.update( dslContext = transactionContext, projectId = projectId, @@ -826,7 +832,7 @@ class PipelineRepositoryService constructor( model.latestVersion = version // 如果不是草稿保存,最新版本永远是新增逻辑 watcher.start("getOriginModel") - val latestResRecord = pipelineResDao.getLatestVersionRecord( + val latestResRecord = pipelineResourceDao.getLatestVersionRecord( transactionContext, projectId, pipelineId ) var pipelineVersion = latestResRecord?.pipelineVersion ?: version @@ -850,7 +856,7 @@ class PipelineRepositoryService constructor( pipelineVersion, triggerVersion, settingVersion ) watcher.start("updatePipelineResource") - if (saveDraft != true) pipelineResDao.create( + if (saveDraft != true) pipelineResourceDao.create( dslContext = transactionContext, projectId = projectId, pipelineId = pipelineId, @@ -862,7 +868,8 @@ class PipelineRepositoryService constructor( triggerVersion = triggerVersion, settingVersion = settingVersion ) - pipelineResVersionDao.create( + // 对于新保存的版本如果没有指定基准版本则默认为上一个版本 + pipelineResourceVersionDao.create( dslContext = transactionContext, projectId = projectId, pipelineId = pipelineId, @@ -875,26 +882,28 @@ class PipelineRepositoryService constructor( triggerVersion = triggerVersion, settingVersion = settingVersion, status = if (saveDraft == true) VersionStatus.COMMITTING else VersionStatus.RELEASED, - description = description + description = description, + baseVersion = baseVersion ?: (version - 1) ) // 针对新增version表做的数据迁移 watcher.start("updatePipelineResourceVersion") - if (version > 1 && pipelineResVersionDao.getVersionModelString( - dslContext = transactionContext, - projectId = projectId, - pipelineId = pipelineId, - version = version - 1 - ) == null - ) { + val lastVersionRecord = pipelineResourceVersionDao.getVersionResource( + dslContext = transactionContext, + projectId = projectId, + pipelineId = pipelineId, + version = version - 1 + ) + if (version > 1 && lastVersionRecord == null) { // 当ResVersion表中缺失上一个有效版本时需从Res表迁移数据(版本间流水线模型对比有用) - val lastVersionModelStr = pipelineResDao.getVersionModelString( + // TODO 将保存时才转移到ResVersion的逻辑改成双写同步写入 + val lastVersionModelStr = pipelineResourceDao.getVersionModelString( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, version = version - 1 ) if (!lastVersionModelStr.isNullOrEmpty()) { - pipelineResVersionDao.create( + pipelineResourceVersionDao.create( dslContext = transactionContext, projectId = projectId, pipelineId = pipelineId, @@ -906,7 +915,8 @@ class PipelineRepositoryService constructor( triggerVersion = null, settingVersion = null, status = VersionStatus.RELEASED, - description = description + description = description, + baseVersion = (version - 1).coerceAtLeast(0) ) } } @@ -916,14 +926,14 @@ class PipelineRepositoryService constructor( projectId = projectId, pipelineId = pipelineId ) - pipelineResDao.deleteEarlyVersion( + pipelineResourceDao.deleteEarlyVersion( dslContext = transactionContext, projectId = projectId, pipelineId = pipelineId, beforeVersion = version ) setting?.maxPipelineResNum?.let { - pipelineResVersionDao.deleteEarlyVersion( + pipelineResourceVersionDao.deleteEarlyVersion( dslContext = transactionContext, projectId = projectId, pipelineId = pipelineId, @@ -989,7 +999,7 @@ class PipelineRepositoryService constructor( * 批量获取model */ fun listModel(projectId: String, pipelineIds: Collection): Map { - return pipelineResDao.listModelString( + return pipelineResourceDao.listModelString( dslContext = dslContext, projectId = projectId, pipelineIds = pipelineIds @@ -1004,14 +1014,14 @@ class PipelineRepositoryService constructor( ): Model? { var modelString: String? if (version == null) { // 取最新版,直接从旧版本表读 - modelString = pipelineResDao.getVersionModelString( + modelString = pipelineResourceDao.getVersionModelString( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, version = null ) ?: return null } else { - modelString = pipelineResVersionDao.getVersionModelString( + modelString = pipelineResourceVersionDao.getVersionModelString( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, @@ -1020,7 +1030,7 @@ class PipelineRepositoryService constructor( ) if (modelString.isNullOrBlank()) { // 兼容处理:取不到再从旧的版本表取 - modelString = pipelineResDao.getVersionModelString( + modelString = pipelineResourceDao.getVersionModelString( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, @@ -1038,13 +1048,13 @@ class PipelineRepositoryService constructor( includeDraft: Boolean? = false ): PipelineResourceVersion? { return if (version == null) { // 取最新版,直接从旧版本表读 - pipelineResDao.getLatestVersionResource( + pipelineResourceDao.getLatestVersionResource( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId ) ?: return null } else { - pipelineResVersionDao.getVersionResource( + pipelineResourceVersionDao.getVersionResource( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, @@ -1086,9 +1096,9 @@ class PipelineRepositoryService constructor( if (delete) { pipelineInfoDao.delete(transactionContext, projectId, pipelineId) - pipelineResVersionDao.deleteAllVersion(transactionContext, projectId, pipelineId) + pipelineResourceVersionDao.deleteAllVersion(transactionContext, projectId, pipelineId) pipelineSettingVersionDao.deleteAllVersion(transactionContext, projectId, pipelineId) - pipelineResDao.deleteAllVersion(transactionContext, projectId, pipelineId) + pipelineResourceDao.deleteAllVersion(transactionContext, projectId, pipelineId) pipelineSettingDao.delete(transactionContext, projectId, pipelineId) templatePipelineDao.delete(transactionContext, projectId, pipelineId) pipelineViewGroupDao.delete(transactionContext, projectId, pipelineId) @@ -1334,7 +1344,7 @@ class PipelineRepositoryService constructor( val lock = PipelineModelLock(redisOperation, pipelineModelVersion.pipelineId) try { lock.lock() - pipelineResDao.updatePipelineModel(dslContext, userId, pipelineModelVersion) + pipelineResourceDao.updatePipelineModel(dslContext, userId, pipelineModelVersion) } finally { lock.unlock() } @@ -1504,7 +1514,7 @@ class PipelineRepositoryService constructor( pipelineId: String, settingVersion: Int ) { - val version = pipelineResDao.updateSettingVersion( + val version = pipelineResourceDao.updateSettingVersion( dslContext = dslContext, userId = userId, projectId = projectId, @@ -1513,7 +1523,7 @@ class PipelineRepositoryService constructor( ) // 同步刷新流水线版本历史中关联的设置版本号 if (version != null) { - pipelineResVersionDao.updateSettingVersion( + pipelineResourceVersionDao.updateSettingVersion( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt index 4cfde5b2ff0..88074deaaf8 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryVersionService.kt @@ -33,9 +33,9 @@ import com.tencent.devops.process.constant.ProcessMessageCode import com.tencent.devops.process.dao.PipelineSettingVersionDao import com.tencent.devops.process.engine.control.lock.PipelineVersionLock import com.tencent.devops.process.engine.dao.PipelineBuildDao -import com.tencent.devops.process.engine.dao.PipelineResVersionDao +import com.tencent.devops.process.engine.dao.PipelineResourceVersionDao import com.tencent.devops.process.engine.pojo.PipelineInfo -import com.tencent.devops.process.engine.pojo.PipelineResVersion +import com.tencent.devops.process.engine.pojo.PipelineVersionInfo import org.jooq.DSLContext import org.jooq.impl.DSL import org.springframework.stereotype.Service @@ -44,7 +44,7 @@ import org.springframework.stereotype.Service @Suppress("LongParameterList", "ReturnCount") class PipelineRepositoryVersionService( private val dslContext: DSLContext, - private val pipelineResVersionDao: PipelineResVersionDao, + private val pipelineResourceVersionDao: PipelineResourceVersionDao, private val pipelineSettingVersionDao: PipelineSettingVersionDao, private val pipelineBuildDao: PipelineBuildDao, private val redisOperation: RedisOperation @@ -54,7 +54,7 @@ class PipelineRepositoryVersionService( PipelineVersionLock(redisOperation, pipelineId, resourceVersion).use { versionLock -> versionLock.lock() // 查询流水线版本记录 - val pipelineVersionInfo = pipelineResVersionDao.getPipelineVersionSimple( + val pipelineVersionInfo = pipelineResourceVersionDao.getPipelineVersionSimple( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, @@ -71,7 +71,7 @@ class PipelineRepositoryVersionService( ) // 更新流水线版本关联构建记录信息 - pipelineResVersionDao.updatePipelineVersionReferInfo( + pipelineResourceVersionDao.updatePipelineVersionReferInfo( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, @@ -100,7 +100,7 @@ class PipelineRepositoryVersionService( } dslContext.transaction { t -> val transactionContext = DSL.using(t) - pipelineResVersionDao.deleteByVer(transactionContext, projectId, pipelineId, version) + pipelineResourceVersionDao.deleteByVer(transactionContext, projectId, pipelineId, version) pipelineSettingVersionDao.deleteByVer(transactionContext, projectId, pipelineId, version) } } finally { @@ -113,18 +113,18 @@ class PipelineRepositoryVersionService( projectId: String, pipelineId: String, version: Int - ): PipelineResVersion? { + ): PipelineVersionInfo? { if (pipelineInfo == null) { return null } - val resource = pipelineResVersionDao.getVersionResource( + val resource = pipelineResourceVersionDao.getVersionResource( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, version = version, includeDraft = true ) ?: return null - return PipelineResVersion( + return PipelineVersionInfo( createTime = pipelineInfo.createTime, creator = pipelineInfo.creator, canElementSkip = pipelineInfo.canElementSkip, @@ -145,7 +145,7 @@ class PipelineRepositoryVersionService( settingVersion = resource.settingVersion, status = resource.status, debugBuildId = resource.debugBuildId, - pacRefs = resource.pacRefs + baseVersion = resource.baseVersion ) } @@ -159,19 +159,19 @@ class PipelineRepositoryVersionService( versionName: String?, creator: String?, description: String? - ): Pair> { + ): Pair> { if (pipelineInfo == null) { return Pair(0, mutableListOf()) } - val count = pipelineResVersionDao.count( + val count = pipelineResourceVersionDao.count( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, creator = creator, description = description ) - val result = pipelineResVersionDao.listPipelineVersion( + val result = pipelineResourceVersionDao.listPipelineVersion( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, @@ -182,11 +182,11 @@ class PipelineRepositoryVersionService( offset = offset, limit = limit ) - val list = mutableListOf() + val list = mutableListOf() result.forEach { list.add( - PipelineResVersion( + PipelineVersionInfo( createTime = pipelineInfo.createTime, creator = pipelineInfo.creator, canElementSkip = pipelineInfo.canElementSkip, @@ -207,7 +207,7 @@ class PipelineRepositoryVersionService( settingVersion = it.settingVersion, status = it.status, debugBuildId = it.debugBuildId, - pacRefs = it.pacRefs + baseVersion = it.baseVersion ) ) } @@ -225,12 +225,12 @@ class PipelineRepositoryVersionService( return Pair(0, emptyList()) } - val count = pipelineResVersionDao.countVersionCreator( + val count = pipelineResourceVersionDao.countVersionCreator( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId ) - val result = pipelineResVersionDao.getVersionCreatorInPage( + val result = pipelineResourceVersionDao.getVersionCreatorInPage( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/BaseBuildRecordService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/BaseBuildRecordService.kt index 933500cc669..f9c9f56065f 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/BaseBuildRecordService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/BaseBuildRecordService.kt @@ -53,8 +53,8 @@ import com.tencent.devops.common.websocket.enum.RefreshType import com.tencent.devops.process.dao.record.BuildRecordModelDao import com.tencent.devops.process.engine.control.lock.PipelineBuildRecordLock import com.tencent.devops.process.engine.dao.PipelineBuildDao -import com.tencent.devops.process.engine.dao.PipelineResDao -import com.tencent.devops.process.engine.dao.PipelineResVersionDao +import com.tencent.devops.process.engine.dao.PipelineResourceDao +import com.tencent.devops.process.engine.dao.PipelineResourceVersionDao import com.tencent.devops.process.engine.pojo.event.PipelineBuildWebSocketPushEvent import com.tencent.devops.process.engine.service.PipelineElementService import com.tencent.devops.process.pojo.BuildStageStatus @@ -77,8 +77,8 @@ open class BaseBuildRecordService( private val redisOperation: RedisOperation, private val stageTagService: StageTagService, private val recordModelService: PipelineRecordModelService, - private val pipelineResDao: PipelineResDao, - private val pipelineResVersionDao: PipelineResVersionDao, + private val pipelineResourceDao: PipelineResourceDao, + private val pipelineResourceVersionDao: PipelineResourceVersionDao, private val pipelineElementService: PipelineElementService ) { @@ -161,9 +161,9 @@ open class BaseBuildRecordService( ): Model? { val watcher = Watcher(id = "getRecordModel#$buildId") watcher.start("getVersionModelString") - val resourceStr = pipelineResVersionDao.getVersionModelString( + val resourceStr = pipelineResourceVersionDao.getVersionModelString( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, version = version - ) ?: pipelineResDao.getVersionModelString( + ) ?: pipelineResourceDao.getVersionModelString( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/ContainerBuildRecordService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/ContainerBuildRecordService.kt index 3b1498e2c2a..978f756ba59 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/ContainerBuildRecordService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/ContainerBuildRecordService.kt @@ -45,8 +45,8 @@ import com.tencent.devops.process.dao.record.BuildRecordTaskDao import com.tencent.devops.process.engine.common.BuildTimeCostUtils.generateContainerTimeCost import com.tencent.devops.process.engine.common.BuildTimeCostUtils.generateMatrixTimeCost import com.tencent.devops.process.engine.dao.PipelineBuildDao -import com.tencent.devops.process.engine.dao.PipelineResDao -import com.tencent.devops.process.engine.dao.PipelineResVersionDao +import com.tencent.devops.process.engine.dao.PipelineResourceDao +import com.tencent.devops.process.engine.dao.PipelineResourceVersionDao import com.tencent.devops.process.engine.service.PipelineElementService import com.tencent.devops.process.engine.service.detail.ContainerBuildDetailService import com.tencent.devops.process.engine.utils.ContainerUtils @@ -69,9 +69,9 @@ class ContainerBuildRecordService( private val recordTaskDao: BuildRecordTaskDao, private val containerBuildDetailService: ContainerBuildDetailService, recordModelService: PipelineRecordModelService, - pipelineResDao: PipelineResDao, + pipelineResourceDao: PipelineResourceDao, pipelineBuildDao: PipelineBuildDao, - pipelineResVersionDao: PipelineResVersionDao, + pipelineResourceVersionDao: PipelineResourceVersionDao, pipelineElementService: PipelineElementService, stageTagService: StageTagService, buildRecordModelDao: BuildRecordModelDao, @@ -84,9 +84,9 @@ class ContainerBuildRecordService( pipelineEventDispatcher = pipelineEventDispatcher, redisOperation = redisOperation, recordModelService = recordModelService, - pipelineResDao = pipelineResDao, + pipelineResourceDao = pipelineResourceDao, pipelineBuildDao = pipelineBuildDao, - pipelineResVersionDao = pipelineResVersionDao, + pipelineResourceVersionDao = pipelineResourceVersionDao, pipelineElementService = pipelineElementService ) { diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/PipelineBuildRecordService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/PipelineBuildRecordService.kt index 686b10fb290..a10a9a04199 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/PipelineBuildRecordService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/PipelineBuildRecordService.kt @@ -61,8 +61,8 @@ import com.tencent.devops.process.dao.record.BuildRecordTaskDao import com.tencent.devops.process.engine.common.BuildTimeCostUtils.generateBuildTimeCost import com.tencent.devops.process.engine.dao.PipelineBuildDao import com.tencent.devops.process.engine.dao.PipelineBuildSummaryDao -import com.tencent.devops.process.engine.dao.PipelineResDao -import com.tencent.devops.process.engine.dao.PipelineResVersionDao +import com.tencent.devops.process.engine.dao.PipelineResourceDao +import com.tencent.devops.process.engine.dao.PipelineResourceVersionDao import com.tencent.devops.process.engine.dao.PipelineTriggerReviewDao import com.tencent.devops.process.engine.pojo.BuildInfo import com.tencent.devops.process.engine.service.PipelineBuildDetailService @@ -107,9 +107,9 @@ class PipelineBuildRecordService @Autowired constructor( private val recordContainerDao: BuildRecordContainerDao, private val recordTaskDao: BuildRecordTaskDao, recordModelService: PipelineRecordModelService, - pipelineResDao: PipelineResDao, + pipelineResourceDao: PipelineResourceDao, pipelineBuildDao: PipelineBuildDao, - pipelineResVersionDao: PipelineResVersionDao, + pipelineResourceVersionDao: PipelineResourceVersionDao, pipelineElementService: PipelineElementService, redisOperation: RedisOperation, stageTagService: StageTagService, @@ -121,9 +121,9 @@ class PipelineBuildRecordService @Autowired constructor( pipelineEventDispatcher = pipelineEventDispatcher, redisOperation = redisOperation, recordModelService = recordModelService, - pipelineResDao = pipelineResDao, + pipelineResourceDao = pipelineResourceDao, pipelineBuildDao = pipelineBuildDao, - pipelineResVersionDao = pipelineResVersionDao, + pipelineResourceVersionDao = pipelineResourceVersionDao, pipelineElementService = pipelineElementService ) { diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/StageBuildRecordService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/StageBuildRecordService.kt index 47de0920f2b..a2debf3c657 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/StageBuildRecordService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/StageBuildRecordService.kt @@ -41,8 +41,8 @@ import com.tencent.devops.process.dao.record.BuildRecordStageDao import com.tencent.devops.process.dao.record.BuildRecordTaskDao import com.tencent.devops.process.engine.common.BuildTimeCostUtils.generateStageTimeCost import com.tencent.devops.process.engine.dao.PipelineBuildDao -import com.tencent.devops.process.engine.dao.PipelineResDao -import com.tencent.devops.process.engine.dao.PipelineResVersionDao +import com.tencent.devops.process.engine.dao.PipelineResourceDao +import com.tencent.devops.process.engine.dao.PipelineResourceVersionDao import com.tencent.devops.process.engine.pojo.PipelineBuildStageControlOption import com.tencent.devops.process.engine.service.PipelineElementService import com.tencent.devops.process.engine.service.detail.StageBuildDetailService @@ -65,8 +65,8 @@ class StageBuildRecordService( private val stageBuildDetailService: StageBuildDetailService, private val pipelineBuildDao: PipelineBuildDao, recordModelService: PipelineRecordModelService, - pipelineResDao: PipelineResDao, - pipelineResVersionDao: PipelineResVersionDao, + pipelineResourceDao: PipelineResourceDao, + pipelineResourceVersionDao: PipelineResourceVersionDao, pipelineElementService: PipelineElementService, stageTagService: StageTagService, buildRecordModelDao: BuildRecordModelDao, @@ -79,9 +79,9 @@ class StageBuildRecordService( pipelineEventDispatcher = pipelineEventDispatcher, redisOperation = redisOperation, recordModelService = recordModelService, - pipelineResDao = pipelineResDao, + pipelineResourceDao = pipelineResourceDao, pipelineBuildDao = pipelineBuildDao, - pipelineResVersionDao = pipelineResVersionDao, + pipelineResourceVersionDao = pipelineResourceVersionDao, pipelineElementService = pipelineElementService ) { diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/TaskBuildRecordService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/TaskBuildRecordService.kt index 55954c666bb..de4262f4fe6 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/TaskBuildRecordService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/record/TaskBuildRecordService.kt @@ -45,8 +45,8 @@ import com.tencent.devops.process.dao.record.BuildRecordModelDao import com.tencent.devops.process.dao.record.BuildRecordTaskDao import com.tencent.devops.process.engine.common.BuildTimeCostUtils.generateTaskTimeCost import com.tencent.devops.process.engine.dao.PipelineBuildDao -import com.tencent.devops.process.engine.dao.PipelineResDao -import com.tencent.devops.process.engine.dao.PipelineResVersionDao +import com.tencent.devops.process.engine.dao.PipelineResourceDao +import com.tencent.devops.process.engine.dao.PipelineResourceVersionDao import com.tencent.devops.process.engine.pojo.PipelineTaskStatusInfo import com.tencent.devops.process.engine.service.PipelineElementService import com.tencent.devops.process.engine.service.detail.TaskBuildDetailService @@ -79,9 +79,9 @@ class TaskBuildRecordService( private val containerBuildRecordService: ContainerBuildRecordService, private val taskBuildDetailService: TaskBuildDetailService, recordModelService: PipelineRecordModelService, - pipelineResDao: PipelineResDao, + pipelineResourceDao: PipelineResourceDao, pipelineBuildDao: PipelineBuildDao, - pipelineResVersionDao: PipelineResVersionDao, + pipelineResourceVersionDao: PipelineResourceVersionDao, pipelineElementService: PipelineElementService, stageTagService: StageTagService, buildRecordModelDao: BuildRecordModelDao, @@ -94,9 +94,9 @@ class TaskBuildRecordService( pipelineEventDispatcher = pipelineEventDispatcher, redisOperation = redisOperation, recordModelService = recordModelService, - pipelineResDao = pipelineResDao, + pipelineResourceDao = pipelineResourceDao, pipelineBuildDao = pipelineBuildDao, - pipelineResVersionDao = pipelineResVersionDao, + pipelineResourceVersionDao = pipelineResourceVersionDao, pipelineElementService = pipelineElementService ) { diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt index 0f3286165c7..b317d4ce6f4 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/service/PipelineOperationLogService.kt @@ -32,7 +32,7 @@ import com.tencent.devops.common.api.pojo.Page import com.tencent.devops.common.api.util.PageUtil import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.engine.dao.PipelineOperationLogDao -import com.tencent.devops.process.engine.dao.PipelineResVersionDao +import com.tencent.devops.process.engine.dao.PipelineResourceVersionDao import com.tencent.devops.process.enums.OperationLogType import com.tencent.devops.process.pojo.PipelineOperationDetail import com.tencent.devops.process.pojo.setting.PipelineVersionSimple @@ -45,7 +45,7 @@ import org.springframework.stereotype.Service class PipelineOperationLogService @Autowired constructor( private val dslContext: DSLContext, private val pipelineOperationLogDao: PipelineOperationLogDao, - private val pipelineResVersionDao: PipelineResVersionDao + private val pipelineResourceVersionDao: PipelineResourceVersionDao ) { fun addOperationLog( @@ -97,7 +97,7 @@ class PipelineOperationLogService @Autowired constructor( val versions = mutableSetOf() opList.forEach { versions.add(it.version) } val versionMap = mutableMapOf() - pipelineResVersionDao.listPipelineVersionInList( + pipelineResourceVersionDao.listPipelineVersionInList( dslContext = dslContext, projectId = projectId, pipelineId = pipelineId, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt index 859e96e2d5b..77e00b3b506 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt @@ -40,7 +40,7 @@ import com.tencent.devops.common.web.RestResource import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.api.service.ServicePipelineVersionResource import com.tencent.devops.process.audit.service.AuditService -import com.tencent.devops.process.engine.pojo.PipelineResVersion +import com.tencent.devops.process.engine.pojo.PipelineVersionInfo import com.tencent.devops.process.engine.service.PipelineVersionFacadeService import com.tencent.devops.process.permission.PipelinePermissionService import com.tencent.devops.process.pojo.PipelineOperationDetail @@ -175,7 +175,7 @@ class ServicePipelineVersionResourceImpl @Autowired constructor( page: Int?, pageSize: Int?, channelCode: ChannelCode - ): Result> { + ): Result> { checkParam(userId, projectId) val permission = AuthPermission.VIEW pipelinePermissionService.validPipelinePermission( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index 93090431112..2d5e0095811 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -49,7 +49,7 @@ import com.tencent.devops.process.audit.service.AuditService import com.tencent.devops.process.constant.ProcessMessageCode import com.tencent.devops.process.constant.ProcessMessageCode.PIPELINE_LIST_LENGTH_LIMIT import com.tencent.devops.process.engine.pojo.PipelineInfo -import com.tencent.devops.process.engine.pojo.PipelineResVersion +import com.tencent.devops.process.engine.pojo.PipelineVersionInfo import com.tencent.devops.process.engine.service.PipelineVersionFacadeService import com.tencent.devops.process.engine.service.rule.PipelineRuleService import com.tencent.devops.process.permission.PipelinePermissionService @@ -668,7 +668,7 @@ class UserPipelineResourceImpl @Autowired constructor( pipelineId: String, page: Int?, pageSize: Int? - ): Result> { + ): Result> { checkParam(userId, projectId) return Result( pipelineVersionFacadeService.listPipelineVersion( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index 6d8b80e12fe..82a654b4c08 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -44,7 +44,7 @@ import com.tencent.devops.common.web.RestResource import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.api.user.UserPipelineVersionResource import com.tencent.devops.process.audit.service.AuditService -import com.tencent.devops.process.engine.pojo.PipelineResVersion +import com.tencent.devops.process.engine.pojo.PipelineVersionInfo import com.tencent.devops.process.engine.service.PipelineVersionFacadeService import com.tencent.devops.process.permission.PipelinePermissionService import com.tencent.devops.process.pojo.PipelineOperationDetail @@ -368,7 +368,7 @@ class UserPipelineVersionResourceImpl @Autowired constructor( description: String?, page: Int?, pageSize: Int? - ): Result> { + ): Result> { checkParam(userId, projectId) val permission = AuthPermission.VIEW pipelinePermissionService.validPipelinePermission( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/AgentPipelineRefService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/AgentPipelineRefService.kt index f4dc02b1773..bca3f38c7fb 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/AgentPipelineRefService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/AgentPipelineRefService.kt @@ -35,7 +35,7 @@ import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentIDDispatchTy import com.tencent.devops.environment.api.thirdPartyAgent.ServiceThirdPartyAgentResource import com.tencent.devops.environment.pojo.AgentPipelineRefInfo import com.tencent.devops.environment.pojo.AgentPipelineRefRequest -import com.tencent.devops.process.engine.dao.PipelineResDao +import com.tencent.devops.process.engine.dao.PipelineResourceDao import org.jooq.DSLContext import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired @@ -46,13 +46,13 @@ class AgentPipelineRefService @Autowired constructor( private val client: Client, private val dslContext: DSLContext, private val objectMapper: ObjectMapper, - private val pipelineResDao: PipelineResDao + private val pipelineResourceDao: PipelineResourceDao ) { fun updateAgentPipelineRef(userId: String, action: String, projectId: String, pipelineId: String) { logger.info("updateAgentPipelineRef, [$userId|$action|$projectId|$pipelineId]") var model: Model? = null if (action != "delete_pipeline") { - val modelString = pipelineResDao.getLatestVersionModelString(dslContext, projectId, pipelineId) + val modelString = pipelineResourceDao.getLatestVersionModelString(dslContext, projectId, pipelineId) if (modelString.isNullOrBlank()) { logger.warn("model not found: [$userId|$action|$projectId|$pipelineId]") return diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineAtomStatisticsService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineAtomStatisticsService.kt index 3a1e5671a6b..c036bde01e6 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineAtomStatisticsService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineAtomStatisticsService.kt @@ -31,7 +31,7 @@ import com.tencent.devops.common.api.exception.ErrorCodeException import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.client.Client import com.tencent.devops.common.pipeline.Model -import com.tencent.devops.process.engine.dao.PipelineResVersionDao +import com.tencent.devops.process.engine.dao.PipelineResourceVersionDao import com.tencent.devops.store.api.common.ServiceStoreStatisticResource import com.tencent.devops.store.pojo.common.StoreStatisticPipelineNumUpdate import com.tencent.devops.store.pojo.common.enums.StoreTypeEnum @@ -47,7 +47,7 @@ import java.util.concurrent.Executors */ @Service class PipelineAtomStatisticsService @Autowired constructor( - private val pipelineResVersionDao: PipelineResVersionDao, + private val pipelineResourceVersionDao: PipelineResourceVersionDao, private val dslContext: DSLContext, private val client: Client ) { @@ -140,6 +140,6 @@ class PipelineAtomStatisticsService @Autowired constructor( } private fun getVersionModelString(projectId: String, pipelineId: String, version: Int?): String? { - return pipelineResVersionDao.getVersionModelString(dslContext, projectId, pipelineId, version) + return pipelineResourceVersionDao.getVersionModelString(dslContext, projectId, pipelineId, version) } } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt index e88b6138f16..05cfc13d798 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineVersionFacadeService.kt @@ -34,7 +34,7 @@ import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.api.util.PageUtil import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.web.utils.I18nUtil -import com.tencent.devops.process.engine.pojo.PipelineResVersion +import com.tencent.devops.process.engine.pojo.PipelineVersionInfo import com.tencent.devops.process.permission.PipelinePermissionService import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service @@ -92,7 +92,7 @@ class PipelineVersionFacadeService @Autowired constructor( versionName: String?, creator: String? = null, description: String? = null - ): Page { + ): Page { var slqLimit: SQLLimit? = null if (pageSize != -1) slqLimit = PageUtil.convertPageSizeToSQLLimit(page, pageSize) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineWebhookService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineWebhookService.kt index f4eaced2395..b806ab5ae20 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineWebhookService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineWebhookService.kt @@ -58,7 +58,7 @@ import com.tencent.devops.common.webhook.util.WebhookUtils import com.tencent.devops.notify.api.service.ServiceNotifyMessageTemplateResource import com.tencent.devops.notify.pojo.SendNotifyMessageTemplateRequest import com.tencent.devops.process.constant.ProcessMessageCode -import com.tencent.devops.process.engine.dao.PipelineResDao +import com.tencent.devops.process.engine.dao.PipelineResourceDao import com.tencent.devops.process.engine.dao.PipelineWebhookDao import com.tencent.devops.process.engine.pojo.WebhookElementParams import com.tencent.devops.process.permission.PipelinePermissionService @@ -81,7 +81,7 @@ class PipelineWebhookService @Autowired constructor( private val scmProxyService: ScmProxyService, private val dslContext: DSLContext, private val pipelineWebhookDao: PipelineWebhookDao, - private val pipelineResDao: PipelineResDao, + private val pipelineResourceDao: PipelineResourceDao, private val objectMapper: ObjectMapper, private val client: Client, private val pipelinePermissionService: PipelinePermissionService, @@ -269,7 +269,7 @@ class PipelineWebhookService @Autowired constructor( fun getModel(projectId: String, pipelineId: String, version: Int? = null): Model? { val modelString = - pipelineResDao.getVersionModelString(dslContext, projectId, pipelineId, version) ?: return null + pipelineResourceDao.getVersionModelString(dslContext, projectId, pipelineId, version) ?: return null return try { objectMapper.readValue(modelString, Model::class.java) } catch (e: Exception) { diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomReplaceCronService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomReplaceCronService.kt index cf49fe274bd..b32a8114537 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomReplaceCronService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomReplaceCronService.kt @@ -53,7 +53,7 @@ import com.tencent.devops.process.dao.PipelineAtomReplaceBaseDao import com.tencent.devops.process.dao.PipelineAtomReplaceHistoryDao import com.tencent.devops.process.dao.PipelineAtomReplaceItemDao import com.tencent.devops.process.engine.dao.PipelineInfoDao -import com.tencent.devops.process.engine.dao.PipelineResDao +import com.tencent.devops.process.engine.dao.PipelineResourceDao import com.tencent.devops.process.engine.service.PipelineRepositoryService import com.tencent.devops.process.pojo.PipelineAtomReplaceHistory import com.tencent.devops.process.pojo.template.TemplateModel @@ -90,7 +90,7 @@ class PipelineAtomReplaceCronService @Autowired constructor( private val pipelineAtomReplaceBaseDao: PipelineAtomReplaceBaseDao, private val pipelineAtomReplaceItemDao: PipelineAtomReplaceItemDao, private val pipelineAtomReplaceHistoryDao: PipelineAtomReplaceHistoryDao, - private val pipelineResDao: PipelineResDao, + private val pipelineResourceDao: PipelineResourceDao, private val pipelineInfoDao: PipelineInfoDao, private val pipelineRepositoryService: PipelineRepositoryService, private val templateFacadeService: TemplateFacadeService, @@ -525,7 +525,7 @@ class PipelineAtomReplaceCronService @Autowired constructor( userId = userId ) // 查询需要替换插件的流水线集合 - val pipelineModelList = pipelineResDao.listLatestModelResource(dslContext, pipelineIdSet) + val pipelineModelList = pipelineResourceDao.listLatestModelResource(dslContext, pipelineIdSet) pipelineModelList?.forEach nextPipelineModel@{ pipelineModelObj -> try { if (replacePipelineModelAtom( @@ -610,6 +610,8 @@ class PipelineAtomReplaceCronService @Autowired constructor( userId = creator, channelCode = channelCode, description = null, + yamlStr = null, + baseVersion = null, create = false ).version pipelineAtomReplaceHistoryDao.createAtomReplaceHistory( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomRollBackCronService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomRollBackCronService.kt index 0823e222fa7..98e6b2b436a 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomRollBackCronService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineAtomRollBackCronService.kt @@ -254,7 +254,9 @@ class PipelineAtomRollBackCronService @Autowired constructor( signPipelineId = pipelineId, userId = pipelineInfo.lastModifyUser, channelCode = pipelineInfo.channelCode, + yamlStr = null, description = null, + baseVersion = null, create = false ) pipelineAtomReplaceHistoryDao.updateAtomReplaceHistory( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index cc6e8124b19..0ab6e429128 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -240,11 +240,13 @@ class PipelineInfoFacadeService @Autowired constructor( return Pair(pipelineInfo?.pipelineName ?: "", pipelineInfo?.version ?: 0) } + // TODO #8161 旧接口传参改造 fun createPipeline( userId: String, projectId: String, model: Model, channelCode: ChannelCode, + yaml: String? = null, checkPermission: Boolean = true, fixPipelineId: String? = null, instanceType: String? = PipelineInstanceTypeEnum.FREEDOM.type, @@ -374,7 +376,9 @@ class PipelineInfoFacadeService @Autowired constructor( useSubscriptionSettings = useSubscriptionSettings, useConcurrencyGroup = useConcurrencyGroup, templateId = templateId, - description = null + description = null, + yamlStr = yaml, + baseVersion = null ) pipelineId = result.pipelineId watcher.stop() @@ -663,6 +667,7 @@ class PipelineInfoFacadeService @Autowired constructor( } } + // TODO #8161 旧接口传参改造 fun editPipeline( userId: String, projectId: String, @@ -675,7 +680,8 @@ class PipelineInfoFacadeService @Autowired constructor( updateLastModifyUser: Boolean? = true, savedSetting: PipelineSetting? = null, saveDraft: Boolean? = false, - description: String? = null + description: String? = null, + baseVersion: Int? = null ): DeployPipelineResult { if (checkTemplate && templateService.isTemplatePipeline(projectId, pipelineId)) { throw ErrorCodeException( @@ -757,7 +763,9 @@ class PipelineInfoFacadeService @Autowired constructor( updateLastModifyUser = updateLastModifyUser, savedSetting = savedSetting, saveDraft = saveDraft, - description = description + description = description, + yamlStr = yaml, + baseVersion = baseVersion ) if (checkPermission) { pipelinePermissionService.modifyResource(projectId, pipelineId, model.name) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt index 6252184adbb..c1b0dd5705b 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt @@ -73,7 +73,7 @@ import com.tencent.devops.process.engine.common.VMUtils import com.tencent.devops.process.engine.compatibility.BuildPropertyCompatibilityTools import com.tencent.devops.process.engine.dao.PipelineBuildSummaryDao import com.tencent.devops.process.engine.dao.PipelineInfoDao -import com.tencent.devops.process.engine.dao.PipelineResDao +import com.tencent.devops.process.engine.dao.PipelineResourceDao import com.tencent.devops.process.engine.dao.template.TemplateDao import com.tencent.devops.process.engine.dao.template.TemplateInstanceBaseDao import com.tencent.devops.process.engine.dao.template.TemplateInstanceItemDao @@ -155,7 +155,7 @@ class TemplateFacadeService @Autowired constructor( private val stageTagService: StageTagService, private val client: Client, private val objectMapper: ObjectMapper, - private val pipelineResDao: PipelineResDao, + private val pipelineResourceDao: PipelineResourceDao, private val pipelineBuildSummaryDao: PipelineBuildSummaryDao, private val templateInstanceBaseDao: TemplateInstanceBaseDao, private val templateInstanceItemDao: TemplateInstanceItemDao, @@ -291,7 +291,7 @@ class TemplateFacadeService @Autowired constructor( checkPermission(projectId, userId) - val template = pipelineResDao.getLatestVersionModelString(dslContext, projectId, saveAsTemplateReq.pipelineId) + val template = pipelineResourceDao.getLatestVersionModelString(dslContext, projectId, saveAsTemplateReq.pipelineId) ?: throw ErrorCodeException( statusCode = Response.Status.NOT_FOUND.statusCode, errorCode = ProcessMessageCode.ERROR_PIPELINE_MODEL_NOT_EXISTS @@ -1070,7 +1070,7 @@ class TemplateFacadeService @Autowired constructor( ) val v1Model: Model = instanceCompareModel( objectMapper.readValue( - content = pipelineResDao.getVersionModelString(dslContext, projectId, pipelineId, null) + content = pipelineResourceDao.getVersionModelString(dslContext, projectId, pipelineId, null) ?: throw ErrorCodeException( statusCode = Response.Status.NOT_FOUND.statusCode, errorCode = ProcessMessageCode.ERROR_PIPELINE_MODEL_NOT_EXISTS @@ -2064,7 +2064,7 @@ class TemplateFacadeService @Autowired constructor( } fun listLatestModel(projectId: String, pipelineIds: Set): Map { - val modelResources = pipelineResDao.listLatestModelResource(dslContext, pipelineIds, projectId) + val modelResources = pipelineResourceDao.listLatestModelResource(dslContext, pipelineIds, projectId) return modelResources?.map { modelResource -> modelResource.value1() to modelResource.value3() }?.toMap() ?: mapOf() From a9f580b7ffb311f3bfaefa95a2b375bce9deceae Mon Sep 17 00:00:00 2001 From: yongyiduan Date: Mon, 28 Aug 2023 20:52:58 +0800 Subject: [PATCH 087/852] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=BB=BA/?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=BB=A5=20Code=20=E6=96=B9=E5=BC=8F=E7=BC=96=E6=8E=92?= =?UTF-8?q?=E6=B5=81=E6=B0=B4=E7=BA=BF=20#8125=20core?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yaml/modelTransfer/ContainerTransfer.kt | 3 +- .../yaml/modelTransfer/DispatchTransfer.kt | 72 ++--- .../yaml/modelTransfer/ElementTransfer.kt | 127 +++++++-- .../yaml/modelTransfer/ModelTransfer.kt | 90 ++++-- .../yaml/modelTransfer/StageTransfer.kt | 12 +- .../modelTransfer/TransferCacheService.kt | 25 ++ .../yaml/modelTransfer/TriggerTransfer.kt | 266 +++++++++++++----- .../yaml/modelTransfer/VariableDefault.kt | 8 +- .../pojo/WebHookTriggerElementChanger.kt | 62 +++- .../devops/process/yaml/v2/models/Notices.kt | 6 +- .../v2/models/PreTemplateScriptBuildYaml.kt | 9 +- .../devops/process/yaml/v2/models/Variable.kt | 2 + .../process/yaml/v2/models/image/PoolType.kt | 3 +- .../process/yaml/v2/models/on/IssueRule.kt | 1 + .../process/yaml/v2/models/on/ManualRule.kt | 52 ++++ .../process/yaml/v2/models/on/MrRule.kt | 7 +- .../process/yaml/v2/models/on/NoteRule.kt | 1 + .../process/yaml/v2/models/on/PushRule.kt | 9 +- .../process/yaml/v2/models/on/ReviewRule.kt | 1 + .../yaml/v2/models/on/SchedulesRule.kt | 10 +- .../process/yaml/v2/models/on/TagRule.kt | 1 + .../process/yaml/v2/models/on/TriggerOn.kt | 47 ++-- .../process/yaml/v2/utils/ScriptYmlUtils.kt | 59 ++-- .../v3/models/PreTemplateScriptBuildYamlV3.kt | 19 +- .../process/yaml/v3/models/TriggerType.kt | 57 ++++ .../yaml/v3/models/on/PreTriggerOnV3.kt | 10 +- .../common/pipeline/pojo/BuildFormProperty.kt | 6 +- .../transfer/PipelineTransferYamlService.kt | 2 +- .../devops/stream/trigger/StreamYamlBuild.kt | 7 +- .../actions/github/GithubPushActionGit.kt | 4 +- .../trigger/actions/tgit/TGitPushActionGit.kt | 4 +- 31 files changed, 769 insertions(+), 213 deletions(-) create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ManualRule.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/TriggerType.kt diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ContainerTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ContainerTransfer.kt index 60ab994707b..863fab17e63 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ContainerTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ContainerTransfer.kt @@ -139,7 +139,8 @@ class ContainerTransfer @Autowired(required = false) constructor( name = job.name, runsOn = RunsOn( selfHosted = null, - poolName = JobRunsOnType.AGENT_LESS.type + poolName = JobRunsOnType.AGENT_LESS.type, + poolType = null ), mutex = getMutexYaml(job.mutexGroup), container = null, diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/DispatchTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/DispatchTransfer.kt index cb04b6d7ba4..108158947b8 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/DispatchTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/DispatchTransfer.kt @@ -42,6 +42,8 @@ import com.tencent.devops.common.pipeline.type.docker.ImageType import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.constant.ProcessMessageCode import com.tencent.devops.process.pojo.BuildTemplateAcrossInfo +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_JOB_PREPARE_TIMEOUT +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault import com.tencent.devops.process.yaml.modelTransfer.inner.TransferCreator import com.tencent.devops.process.yaml.utils.StreamDispatchUtils import com.tencent.devops.process.yaml.v2.models.image.Pool @@ -82,17 +84,17 @@ class DispatchTransfer @Autowired(required = false) constructor( job: Job, buildTemplateAcrossInfo: BuildTemplateAcrossInfo? ): DispatchType { + // linux构建机 + dispatcherLinux(job, buildTemplateAcrossInfo)?.let { return it } // 第三方构建机 dispatcherThirdPartyAgent(job, buildTemplateAcrossInfo)?.let { return it } // windows构建机 dispatcherWindows(job)?.let { return it } // macos构建机 dispatcherMacos(job)?.let { return it } - // linux构建机 - dispatcherLinux(job, buildTemplateAcrossInfo)?.let { return it } // 转换失败 throw CustomException( - Response.Status.NOT_FOUND, + Response.Status.BAD_REQUEST, MessageUtil.getMessageByLocale( messageCode = CommonMessageCode.PUBLIC_BUILD_RESOURCE_POOL_NOT_EXIST, language = I18nUtil.getLanguage(I18nUtil.getRequestUserId()) @@ -100,6 +102,38 @@ class DispatchTransfer @Autowired(required = false) constructor( ) } + fun makeRunsOn( + job: VMBuildContainer + ): RunsOn? { + val dispatchType = job.dispatchType + if (dispatchType == null) { + logger.warn("job.dispatchType can not be null") + return null + } + val runsOn = dispatch2RunsOn(dispatchType) ?: RunsOn( + selfHosted = null, + poolName = I18nUtil.getCodeLanMessage( + messageCode = ProcessMessageCode.BK_AUTOMATIC_EXPORT_NOT_SUPPORTED + ), + container = null, + agentSelector = null + ) + if (dispatchType is ThirdPartyAgentEnvDispatchType) { + runsOn.agentSelector = when (job.baseOS) { + VMBaseOS.WINDOWS -> listOf("windows") + VMBaseOS.LINUX -> listOf("linux") + VMBaseOS.MACOS -> listOf("macos") + else -> null + } + } + runsOn.needs = job.buildEnv?.ifEmpty { null } + runsOn.queueTimeoutMinutes = job.jobControlOption?.prepareTimeout?.nullIfDefault(DEFAULT_JOB_PREPARE_TIMEOUT) + if (JSONObject(runsOn).similar(defaultRunsOn)) { + return null + } + return runsOn + } + fun dispatcherLinux( job: Job, buildTemplateAcrossInfo: BuildTemplateAcrossInfo? @@ -185,38 +219,6 @@ class DispatchTransfer @Autowired(required = false) constructor( } else null } - fun makeRunsOn( - job: VMBuildContainer - ): RunsOn? { - val dispatchType = job.dispatchType - if (dispatchType == null) { - logger.warn("job.dispatchType can not be null") - return null - } - val runsOn = dispatch2RunsOn(dispatchType) ?: RunsOn( - selfHosted = null, - poolName = I18nUtil.getCodeLanMessage( - messageCode = ProcessMessageCode.BK_AUTOMATIC_EXPORT_NOT_SUPPORTED - ), - container = null, - agentSelector = null - ) - if (dispatchType is ThirdPartyAgentEnvDispatchType) { - runsOn.agentSelector = when (job.baseOS) { - VMBaseOS.WINDOWS -> listOf("windows") - VMBaseOS.LINUX -> listOf("linux") - VMBaseOS.MACOS -> listOf("macos") - else -> null - } - } - runsOn.needs = job.buildEnv - runsOn.queueTimeoutMinutes = job.jobControlOption?.prepareTimeout - if (JSONObject(runsOn).similar(defaultRunsOn)) { - return null - } - return runsOn - } - fun dispatch2RunsOn(dispatcher: DispatchType) = PoolType.SelfHosted.toRunsOn(dispatcher) ?: PoolType.DockerOnVm.toRunsOn(dispatcher) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt index b9a9749ce08..b27dad96358 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt @@ -27,6 +27,7 @@ package com.tencent.devops.process.yaml.modelTransfer +import com.tencent.devops.common.api.enums.RepositoryType import com.tencent.devops.common.api.enums.ScmType import com.tencent.devops.common.client.Client import com.tencent.devops.common.pipeline.NameAndValue @@ -41,7 +42,13 @@ import com.tencent.devops.common.pipeline.pojo.element.market.MarketBuildAtomEle import com.tencent.devops.common.pipeline.pojo.element.market.MarketBuildLessAtomElement import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGitWebHookTriggerElement import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGithubWebHookTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGitlabWebHookTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeP4WebHookTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeSVNWebHookTriggerElement import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeTGitWebHookTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.ManualTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.RemoteTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.TimerTriggerElement import com.tencent.devops.process.yaml.modelCreate.ModelCommon import com.tencent.devops.process.yaml.modelCreate.ModelCreateException import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault @@ -53,9 +60,13 @@ import com.tencent.devops.process.yaml.modelTransfer.pojo.YamlTransferInput import com.tencent.devops.process.yaml.utils.ModelCreateUtil import com.tencent.devops.process.yaml.v2.models.IfType import com.tencent.devops.process.yaml.v2.models.job.Job +import com.tencent.devops.process.yaml.v2.models.on.EnableType +import com.tencent.devops.process.yaml.v2.models.on.ManualRule +import com.tencent.devops.process.yaml.v2.models.on.SchedulesRule import com.tencent.devops.process.yaml.v2.models.on.TriggerOn import com.tencent.devops.process.yaml.v2.models.step.PreStep import com.tencent.devops.process.yaml.v2.models.step.Step +import com.tencent.devops.process.yaml.v3.models.TriggerType import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component @@ -72,17 +83,57 @@ class ElementTransfer @Autowired(required = false) constructor( private val logger = LoggerFactory.getLogger(ElementTransfer::class.java) } - fun yaml2Triggers(triggerOns: Map, elements: MutableList) { - triggerOns.forEach { - when (it.key) { - ScmType.CODE_GIT -> triggerTransfer.yaml2TriggerGit(it.value, elements) - ScmType.CODE_TGIT -> triggerTransfer.yaml2TriggerTGit(it.value, elements) - ScmType.GITHUB -> triggerTransfer.yaml2TriggerGithub(it.value, elements) + fun yaml2Triggers(yamlInput: YamlTransferInput, elements: MutableList) { + yamlInput.yaml.formatTriggerOn(yamlInput.defaultScmType).forEach { + when (it.first) { + TriggerType.BASE -> triggerTransfer.yaml2TriggerBase(it.second, elements) + TriggerType.CODE_GIT -> triggerTransfer.yaml2TriggerGit(it.second, elements) + TriggerType.CODE_TGIT -> triggerTransfer.yaml2TriggerTGit(it.second, elements) + TriggerType.GITHUB -> triggerTransfer.yaml2TriggerGithub(it.second, elements) + TriggerType.CODE_SVN -> triggerTransfer.yaml2TriggerSvn(it.second, elements) + TriggerType.CODE_P4 -> triggerTransfer.yaml2TriggerP4(it.second, elements) } } } - fun triggers2Yaml(elements: List): Map { + fun baseTriggers2yaml(elements: List): TriggerOn? { + val triggerOn = lazy { TriggerOn() } + val schedules = mutableListOf() + elements.forEach { element -> + if (element is ManualTriggerElement) { + triggerOn.value.manual = ManualRule( + canElementSkip = element.canElementSkip.nullIfDefault(true), + useLatestParameters = element.useLatestParameters.nullIfDefault(false) + ) + return@forEach + } + if (element is TimerTriggerElement) { + schedules.add( + SchedulesRule( + cron = element.newExpression?.firstOrNull(), + advanceCron = element.advanceExpression?.ifEmpty { null }, + always = (element.noScm != true).nullIfDefault(false), + enable = element.isElementEnable().nullIfDefault(true) + ) + ) + return@forEach + } + if (element is RemoteTriggerElement) { + triggerOn.value.remote = if (element.isElementEnable()) { + EnableType.TRUE.value + } else { + EnableType.FALSE.value + } + } + } + if (schedules.isNotEmpty()) { + triggerOn.value.schedules = schedules + } + if (triggerOn.isInitialized()) return triggerOn.value + return null + } + + fun scmTriggers2Yaml(elements: List, projectId: String): Map { val res = mutableMapOf() val fix = elements.groupBy { it.getClassType() } @@ -90,7 +141,7 @@ class ElementTransfer @Autowired(required = false) constructor( WebHookTriggerElementChanger(it as CodeGitWebHookTriggerElement) } if (!gitElement.isNullOrEmpty()) { - val gitTrigger = triggerTransfer.git2YamlTriggerOn(gitElement) + val gitTrigger = triggerTransfer.git2YamlTriggerOn(gitElement, projectId) res.putAll(gitTrigger.associateBy { ScmType.CODE_GIT }) } @@ -98,7 +149,7 @@ class ElementTransfer @Autowired(required = false) constructor( WebHookTriggerElementChanger(it as CodeTGitWebHookTriggerElement) } if (!tGitElement.isNullOrEmpty()) { - val gitTrigger = triggerTransfer.git2YamlTriggerOn(tGitElement) + val gitTrigger = triggerTransfer.git2YamlTriggerOn(tGitElement, projectId) res.putAll(gitTrigger.associateBy { ScmType.CODE_TGIT }) } @@ -106,9 +157,33 @@ class ElementTransfer @Autowired(required = false) constructor( WebHookTriggerElementChanger(it as CodeGithubWebHookTriggerElement) } if (!githubElement.isNullOrEmpty()) { - val gitTrigger = triggerTransfer.git2YamlTriggerOn(githubElement) + val gitTrigger = triggerTransfer.git2YamlTriggerOn(githubElement, projectId) res.putAll(gitTrigger.associateBy { ScmType.GITHUB }) } + + val svnElement = fix[CodeSVNWebHookTriggerElement.classType]?.map { + WebHookTriggerElementChanger(it as CodeSVNWebHookTriggerElement) + } + if (!svnElement.isNullOrEmpty()) { + val gitTrigger = triggerTransfer.git2YamlTriggerOn(svnElement, projectId) + res.putAll(gitTrigger.associateBy { ScmType.CODE_SVN }) + } + + val p4Element = fix[CodeP4WebHookTriggerElement.classType]?.map { + WebHookTriggerElementChanger(it as CodeP4WebHookTriggerElement) + } + if (!p4Element.isNullOrEmpty()) { + val gitTrigger = triggerTransfer.git2YamlTriggerOn(p4Element, projectId) + res.putAll(gitTrigger.associateBy { ScmType.CODE_P4 }) + } + + val gitlabElement = fix[CodeGitlabWebHookTriggerElement.classType]?.map { + WebHookTriggerElementChanger(it as CodeGitlabWebHookTriggerElement) + } + if (!gitlabElement.isNullOrEmpty()) { + val gitTrigger = triggerTransfer.git2YamlTriggerOn(gitlabElement, projectId) + res.putAll(gitTrigger.associateBy { ScmType.CODE_P4 }) + } return res } @@ -230,11 +305,12 @@ class ElementTransfer @Autowired(required = false) constructor( } fun model2YamlSteps( - job: Container + job: Container, + projectId: String ): List { val stepList = mutableListOf() job.elements.forEach { element -> - val step = element2YamlStep(element) + val step = element2YamlStep(element, projectId) if (step != null) { stepList.add(step) } @@ -243,8 +319,10 @@ class ElementTransfer @Autowired(required = false) constructor( } @Suppress("ComplexMethod") - fun element2YamlStep(element: Element): PreStep? { - val retryTimes = element.additionalOptions?.retryCount.nullIfDefault(VariableDefault.DEFAULT_RETRY_COUNT) + fun element2YamlStep(element: Element, projectId: String): PreStep? { + val retryTimes = if (element.additionalOptions?.retryWhenFailed == true) { + element.additionalOptions?.retryCount + } else null val timeoutMinutes = element.additionalOptions?.timeout?.toInt() .nullIfDefault(VariableDefault.DEFAULT_TASK_TIME_OUT) val continueOnError = element.additionalOptions?.continueWhenFailed @@ -288,7 +366,24 @@ class ElementTransfer @Autowired(required = false) constructor( } element.getAtomCode() == "checkout" && element is MarketBuildAtomElement -> { val input = element.data["input"] as Map? ?: emptyMap() - val url = input[CheckoutAtomParam::repositoryUrl.name].toString().ifBlank { null } + val repositoryType = input[CheckoutAtomParam::repositoryType.name].toString().ifBlank { null }?.let { + CheckoutAtomParam.CheckoutRepositoryType.valueOf(it) + } + val repositoryHashId = input[CheckoutAtomParam::repositoryHashId.name].toString().ifBlank { null } + val repositoryName = input[CheckoutAtomParam::repositoryName.name].toString().ifBlank { null } + val repositoryUrl = input[CheckoutAtomParam::repositoryUrl.name].toString().ifBlank { null } + val checkout = when { + repositoryType == CheckoutAtomParam.CheckoutRepositoryType.ID && repositoryHashId != null -> { + transferCache.getGitRepository(projectId, RepositoryType.ID, repositoryHashId)?.url + } + repositoryType == CheckoutAtomParam.CheckoutRepositoryType.NAME && repositoryName != null -> { + transferCache.getGitRepository(projectId, RepositoryType.NAME, repositoryName)?.url + } + repositoryType == CheckoutAtomParam.CheckoutRepositoryType.URL && repositoryUrl != null -> { + repositoryUrl + } + else -> null + } ?: "self" // todo 等待checkout插件新增self参数 PreStep( name = element.name, @@ -302,7 +397,7 @@ class ElementTransfer @Autowired(required = false) constructor( retryTimes = retryTimes, env = env, run = null, - checkout = url, + checkout = checkout, shell = null ) } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt index 618f8ca119a..30dc784248d 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt @@ -27,7 +27,6 @@ package com.tencent.devops.process.yaml.modelTransfer -import com.tencent.devops.common.api.enums.ScmType import com.tencent.devops.common.client.Client import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.container.Stage @@ -47,9 +46,11 @@ import com.tencent.devops.process.yaml.v2.models.Notices import com.tencent.devops.process.yaml.v2.models.PacNotices import com.tencent.devops.process.yaml.v2.models.PreTemplateScriptBuildYaml import com.tencent.devops.process.yaml.v2.models.Variable -import com.tencent.devops.process.yaml.v2.models.on.TriggerOn +import com.tencent.devops.process.yaml.v2.models.on.IPreTriggerOn +import com.tencent.devops.process.yaml.v2.models.on.PreTriggerOn import com.tencent.devops.process.yaml.v2.models.stage.PreStage import com.tencent.devops.process.yaml.v3.models.PreTemplateScriptBuildYamlV3 +import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component @@ -118,7 +119,7 @@ class ModelTransfer @Autowired constructor( private fun prepareYamlGroups(projectId: String, notice: PacNotices): PacNotices { if (notice.groups.isNullOrEmpty()) return notice val info = transferCache.getProjectGroupAndUsers(projectId)?.associateBy { it.roleName } ?: return notice - val groups = notice.groups.mapNotNull { info[it]?.displayName } + val groups = notice.groups.mapNotNull { info[it]?.displayName }.ifEmpty { null } return notice.copy(groups = groups) } @@ -169,22 +170,23 @@ class ModelTransfer @Autowired constructor( val stages = mutableListOf() modelInput.model.stages.forEachIndexed { index, stage -> if (index == 0 || stage.finally) return@forEachIndexed - val ymlStage = modelStage.model2YamlStage(stage) + val ymlStage = modelStage.model2YamlStage(stage, modelInput.setting.projectId) stages.add(ymlStage) } val label = prepareYamlLabels(modelInput.setting).ifEmpty { null } - val triggerOn = getTriggerOn(modelInput.model) - val variables = getVariableFromModel(modelInput.model) + val triggerOn = makeTriggerOn(modelInput) + val variables = makeVariableFromModel(modelInput.model) val lastStage = modelInput.model.stages.last() - val finally = if (lastStage.finally) modelStage.model2YamlStage(lastStage).jobs else null - val concurrency = getConcurrency(modelInput.setting) + val finally = if (lastStage.finally) + modelStage.model2YamlStage(lastStage, modelInput.setting.projectId).jobs else null + val concurrency = makeConcurrency(modelInput.setting) return when (modelInput.version) { YamlVersion.Version.V2_0 -> PreTemplateScriptBuildYaml( version = "v2.0", name = modelInput.model.name, label = label, - triggerOn = triggerOn[modelInput.defaultScmType]?.toPreV2(), + triggerOn = triggerOn.firstOrNull() as PreTriggerOn?, variables = variables, stages = TransferMapper.anyTo(stages), extends = null, @@ -197,9 +199,7 @@ class ModelTransfer @Autowired constructor( version = "v3.0", name = modelInput.model.name, label = label, - triggerOn = triggerOn.map { on -> - on.value.toPreV3().also { it.type = on.key.alis } - }.ifEmpty { null }?.let { if (it.size == 1) it.first() else it }, + triggerOn = triggerOn.ifEmpty { null }?.let { if (it.size == 1) it.first() else it }, variables = variables, stages = TransferMapper.anyTo(stages), extends = null, @@ -243,7 +243,7 @@ class ModelTransfer @Autowired constructor( return res } - private fun getConcurrency(setting: PipelineSetting): Concurrency? { + private fun makeConcurrency(setting: PipelineSetting): Concurrency? { if (setting.runLockType == PipelineRunLockType.GROUP_LOCK) { return Concurrency( group = setting.concurrencyGroup, @@ -257,16 +257,70 @@ class ModelTransfer @Autowired constructor( return null } - private fun getTriggerOn(model: Model): Map { - val triggers = (model.stages[0].containers[0] as TriggerContainer).elements - return modelElement.triggers2Yaml(triggers) + private fun makeTriggerOn(modelInput: ModelTransferInput): List { + val triggers = (modelInput.model.stages[0].containers[0] as TriggerContainer).elements + val baseTrigger = modelElement.baseTriggers2yaml(triggers)?.toPre(modelInput.version) + val scmTrigger = modelElement.scmTriggers2Yaml(triggers, modelInput.setting.projectId) + when (modelInput.version) { + YamlVersion.Version.V2_0 -> { + // 融合默认git触发器 + 基础触发器 + if (scmTrigger[modelInput.defaultScmType] != null) { + val res = scmTrigger[modelInput.defaultScmType]!!.toPre(modelInput.version) as PreTriggerOn + return listOf( + res.copy( + manual = baseTrigger?.manual, + schedules = baseTrigger?.schedules, + remote = baseTrigger?.remote + ) + ) + } + // 只带基础触发器 + if (baseTrigger != null) { + return listOf(baseTrigger) + } + // 不带触发器 + return emptyList() + } + YamlVersion.Version.V3_0 -> { + val trigger = mutableListOf() + val triggerV3 = scmTrigger.map { on -> + on.value.toPre(modelInput.version).also { + it as PreTriggerOnV3 + it.type = on.key.alis + } + } + if (baseTrigger != null) { + when (triggerV3.size) { + // 只带基础触发器 + 0 -> return listOf(baseTrigger) + // 融合一个git触发器 + 基础触发器 + 1 -> return listOf( + (triggerV3.first() as PreTriggerOnV3).copy( + manual = baseTrigger.manual, + schedules = baseTrigger.schedules, + remote = baseTrigger.remote + ) + ) + // 队列首插入基础触发器 + else -> trigger.add(0, baseTrigger) + } + } + trigger.addAll(triggerV3) + return trigger + } + } } - private fun getVariableFromModel(model: Model): Map? { + private fun makeVariableFromModel(model: Model): Map? { val result = mutableMapOf() (model.stages[0].containers[0] as TriggerContainer).params.forEach { // todo 启动参数需要更详细的解析 - result[it.id] = Variable(it.defaultValue.toString()) + result[it.id] = Variable( + it.defaultValue.toString(), + readonly = it.readOnly.nullIfDefault(false), + allowModifyAtStartup = it.required.nullIfDefault(true), + valueNotEmpty = it.valueNotEmpty.nullIfDefault(false) + ) } return if (result.isEmpty()) { null diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt index 864db98fb7a..2f1e053de98 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt @@ -81,7 +81,7 @@ class StageTransfer @Autowired(required = false) constructor( fun yaml2TriggerStage(yamlInput: YamlTransferInput, stageIndex: Int): Stage { // 第一个stage,触发类 val triggerElementList = mutableListOf() - modelElement.yaml2Triggers(yamlInput.yaml.formatTriggerOn(yamlInput.defaultScmType), triggerElementList) + modelElement.yaml2Triggers(yamlInput, triggerElementList) val triggerContainer = TriggerContainer( id = "0", @@ -186,11 +186,12 @@ class StageTransfer @Autowired(required = false) constructor( } fun model2YamlStage( - stage: Stage + stage: Stage, + projectId: String ): PreStage { val jobs = stage.containers.associate { job -> - val steps = modelElement.model2YamlSteps(job) + val steps = modelElement.model2YamlSteps(job, projectId) (job.jobId ?: "job_${job.id}") to when (job.getClassType()) { NormalContainer.classType -> modelContainer.addYamlNormalContainer(job as NormalContainer, steps) @@ -316,7 +317,7 @@ class StageTransfer @Autowired(required = false) constructor( buildFormProperties.add( BuildFormProperty( id = key, - required = false, + required = variable.allowModifyAtStartup ?: true, type = BuildFormPropertyType.STRING, defaultValue = variable.value ?: "", options = null, @@ -327,7 +328,8 @@ class StageTransfer @Autowired(required = false) constructor( containerType = null, glob = null, properties = null, - readOnly = variable.readonly + readOnly = variable.readonly, + valueNotEmpty = variable.valueNotEmpty ) ) } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferCacheService.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferCacheService.kt index 36e9db3a00c..f034e77763e 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferCacheService.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferCacheService.kt @@ -3,11 +3,15 @@ package com.tencent.devops.process.yaml.modelTransfer import com.github.benmanes.caffeine.cache.Caffeine import com.tencent.devops.auth.api.service.ServiceProjectAuthResource import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE +import com.tencent.devops.common.api.enums.RepositoryConfig +import com.tencent.devops.common.api.enums.RepositoryType import com.tencent.devops.common.auth.api.pojo.BkAuthGroupAndUserList import com.tencent.devops.common.client.Client import com.tencent.devops.common.client.ClientTokenService import com.tencent.devops.process.api.service.ServicePipelineGroupResource import com.tencent.devops.process.pojo.classify.PipelineGroup +import com.tencent.devops.repository.api.ServiceRepositoryResource +import com.tencent.devops.repository.pojo.Repository import com.tencent.devops.store.api.atom.ServiceMarketAtomResource import com.tencent.devops.store.api.image.service.ServiceStoreImageResource import com.tencent.devops.store.pojo.atom.ElementThirdPartySearchParam @@ -76,6 +80,24 @@ class TransferCacheService @Autowired constructor( }.onFailure { logger.warn("get $projectId default value error.") }.getOrNull() } + private val gitRepository = Caffeine.newBuilder() + .maximumSize(1000) + .expireAfterWrite(10, TimeUnit.MINUTES) + .build { key -> + kotlin.runCatching { + val (projectId, type, value) = key.split("@@") + val repositoryType = RepositoryType.valueOf(type) + val config = RepositoryConfig( + if (repositoryType == RepositoryType.ID) value else null, + if (repositoryType == RepositoryType.NAME) value else null, + RepositoryType.valueOf(type) + ) + client.get(ServiceRepositoryResource::class) + .get(projectId, config.getURLEncodeRepositoryId(), config.repositoryType) + .data + }.onFailure { logger.warn("get $key value error.") }.getOrNull() + } + fun getAtomDefaultValue(key: String) = atomDefaultValueCache.get(key) ?: emptyMap() fun getStoreImageInfo(imageCode: String, imageVersion: String?) = @@ -84,4 +106,7 @@ class TransferCacheService @Autowired constructor( fun getProjectGroupAndUsers(projectId: String) = projectGroupAndUsersCache.get(projectId) fun getPipelineLabel(projectId: String) = pipelineLabel.get(projectId) + + fun getGitRepository(projectId: String, repositoryType: RepositoryType, value: String) = + gitRepository.get("$projectId@@${repositoryType.name}@@$value") } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt index 8b655017b31..da433a2dfb9 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt @@ -27,20 +27,29 @@ package com.tencent.devops.process.yaml.modelTransfer -import com.tencent.devops.common.api.constant.CommonMessageCode import com.tencent.devops.common.api.enums.RepositoryType import com.tencent.devops.common.client.Client import com.tencent.devops.common.pipeline.pojo.element.Element +import com.tencent.devops.common.pipeline.pojo.element.ElementAdditionalOptions +import com.tencent.devops.common.pipeline.pojo.element.RunCondition import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGitWebHookTriggerElement import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGithubWebHookTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeP4WebHookTriggerData +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeP4WebHookTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeP4WebHookTriggerInput +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeSVNWebHookTriggerElement import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeTGitWebHookTriggerData import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeTGitWebHookTriggerElement import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeTGitWebHookTriggerInput import com.tencent.devops.common.pipeline.pojo.element.trigger.ManualTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.RemoteTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.TimerTriggerElement import com.tencent.devops.common.pipeline.pojo.element.trigger.enums.CodeEventType -import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.common.pipeline.pojo.element.trigger.enums.PathFilterType +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault import com.tencent.devops.process.yaml.modelTransfer.inner.TransferCreator import com.tencent.devops.process.yaml.modelTransfer.pojo.WebHookTriggerElementChanger +import com.tencent.devops.process.yaml.v2.models.on.EnableType import com.tencent.devops.process.yaml.v2.models.on.IssueRule import com.tencent.devops.process.yaml.v2.models.on.MrRule import com.tencent.devops.process.yaml.v2.models.on.NoteRule @@ -65,15 +74,6 @@ class TriggerTransfer @Autowired(required = false) constructor( @Suppress("ComplexMethod") fun yaml2TriggerGit(triggerOn: TriggerOn, elementQueue: MutableList) { - if (triggerOn.manual != "disabled") { - elementQueue.add( - ManualTriggerElement( - I18nUtil.getCodeLanMessage(CommonMessageCode.BK_MANUAL_TRIGGER), - "T-1-1-1" - ) - ) - } - triggerOn.push?.let { push -> elementQueue.add( CodeGitWebHookTriggerElement( @@ -83,12 +83,14 @@ class TriggerTransfer @Autowired(required = false) constructor( excludePaths = push.pathsIgnore.nonEmptyOrNull()?.join(), includeUsers = push.users, excludeUsers = push.usersIgnore, + pathFilterType = push.pathFilterType?.let { PathFilterType.valueOf(it) }, eventType = CodeEventType.PUSH, // todo action - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name - ) + repositoryName = triggerOn.repoName + ).checkTriggerElementEnable(push.enable) ) } @@ -101,10 +103,11 @@ class TriggerTransfer @Autowired(required = false) constructor( includeUsers = tag.users, excludeUsers = tag.usersIgnore, eventType = CodeEventType.TAG_PUSH, - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name - ) + repositoryName = triggerOn.repoName + ).checkTriggerElementEnable(tag.enable) ) } @@ -122,12 +125,14 @@ class TriggerTransfer @Autowired(required = false) constructor( block = mr.block, webhookQueue = mr.webhookQueue, enableCheck = mr.enableCheck, + pathFilterType = mr.pathFilterType?.let { PathFilterType.valueOf(it) }, // todo action eventType = CodeEventType.MERGE_REQUEST, - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name - ) + repositoryName = triggerOn.repoName + ).checkTriggerElementEnable(mr.enable) ) } @@ -137,10 +142,11 @@ class TriggerTransfer @Autowired(required = false) constructor( includeCrState = review.states, includeCrTypes = review.types, eventType = CodeEventType.REVIEW, - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name - ) + repositoryName = triggerOn.repoName + ).checkTriggerElementEnable(review.enable) ) } @@ -149,10 +155,11 @@ class TriggerTransfer @Autowired(required = false) constructor( CodeGitWebHookTriggerElement( includeIssueAction = issue.action, eventType = CodeEventType.ISSUES, - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name - ) + repositoryName = triggerOn.repoName + ).checkTriggerElementEnable(issue.enable) ) } @@ -169,16 +176,17 @@ class TriggerTransfer @Autowired(required = false) constructor( }, includeNoteComment = note.comment.nonEmptyOrNull()?.join(), eventType = CodeEventType.NOTE, - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name - ) + repositoryName = triggerOn.repoName + ).checkTriggerElementEnable(note.enable) ) } } @Suppress("ComplexMethod") - fun git2YamlTriggerOn(elements: List): List { + fun git2YamlTriggerOn(elements: List, projectId: String): List { val fix = elements.groupBy { when (it.repositoryType) { RepositoryType.ID -> it.repositoryHashId ?: "" @@ -191,23 +199,29 @@ class TriggerTransfer @Autowired(required = false) constructor( group.forEach { git -> val nowExist = res.getOrPut(name) { when (name) { - git.repositoryHashId -> TriggerOn(repoHashId = name) - git.repositoryName -> TriggerOn(name = name) + git.repositoryHashId -> TriggerOn( + repoHashId = name, + repoName = transferCache.getGitRepository(projectId, RepositoryType.ID, name)?.aliasName + ) + git.repositoryName -> TriggerOn(repoName = name) else -> TriggerOn() } } when (git.eventType) { CodeEventType.PUSH -> nowExist.push = PushRule( + enable = git.enable.nullIfDefault(true), branches = git.branchName?.disjoin() ?: emptyList(), branchesIgnore = git.excludeBranchName?.disjoin(), paths = git.includePaths?.disjoin(), pathsIgnore = git.excludePaths?.disjoin(), users = git.includeUsers, usersIgnore = git.excludeUsers, + pathFilterType = git.pathFilterType?.name, // todo action action = null ) CodeEventType.TAG_PUSH -> nowExist.tag = TagRule( + enable = git.enable.nullIfDefault(true), tags = git.tagName?.disjoin(), tagsIgnore = git.excludeTagName?.disjoin(), fromBranches = git.fromBranches?.disjoin(), @@ -215,6 +229,7 @@ class TriggerTransfer @Autowired(required = false) constructor( usersIgnore = git.excludeUsers ) CodeEventType.MERGE_REQUEST -> nowExist.mr = MrRule( + enable = git.enable.nullIfDefault(true), targetBranches = git.branchName?.disjoin(), targetBranchesIgnore = git.excludeBranchName?.disjoin(), sourceBranches = git.includeSourceBranchName?.disjoin(), @@ -226,17 +241,21 @@ class TriggerTransfer @Autowired(required = false) constructor( block = git.block, webhookQueue = git.webhookQueue, enableCheck = git.enableCheck, + pathFilterType = git.pathFilterType?.name, // todo action action = null ) CodeEventType.REVIEW -> nowExist.review = ReviewRule( + enable = git.enable.nullIfDefault(true), states = git.includeCrState, types = git.includeCrTypes ) CodeEventType.ISSUES -> nowExist.issue = IssueRule( + enable = git.enable.nullIfDefault(true), action = git.includeIssueAction ) CodeEventType.NOTE -> nowExist.note = NoteRule( + enable = git.enable.nullIfDefault(true), types = git.includeNoteTypes?.map { when (it) { "Commit" -> "commit" @@ -246,6 +265,22 @@ class TriggerTransfer @Autowired(required = false) constructor( } } ) + CodeEventType.POST_COMMIT -> nowExist.push = PushRule( + enable = git.enable.nullIfDefault(true), + branches = null, + paths = git.includePaths?.disjoin(), + pathsIgnore = git.excludePaths?.disjoin(), + users = git.includeUsers, + usersIgnore = git.excludeUsers, + pathFilterType = git.pathFilterType?.name + ) + CodeEventType.CHANGE_COMMIT -> nowExist.push = PushRule( + enable = git.enable.nullIfDefault(true), + branches = null, + branchesIgnore = null, + paths = git.includePaths?.disjoin(), + pathsIgnore = git.excludePaths?.disjoin() + ) } } // res[name] = nowExist @@ -266,14 +301,16 @@ class TriggerTransfer @Autowired(required = false) constructor( excludePaths = push.pathsIgnore.nonEmptyOrNull()?.join(), includeUsers = push.users, excludeUsers = push.usersIgnore, + pathFilterType = push.pathFilterType?.let { PathFilterType.valueOf(it) }, eventType = CodeEventType.PUSH, // todo action - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name + repositoryName = triggerOn.repoName ) ) - ) + ).checkTriggerElementEnable(push.enable) ) } @@ -288,12 +325,13 @@ class TriggerTransfer @Autowired(required = false) constructor( includeUsers = tag.users, excludeUsers = tag.usersIgnore, eventType = CodeEventType.TAG_PUSH, - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name + repositoryName = triggerOn.repoName ) ) - ) + ).checkTriggerElementEnable(tag.enable) ) } @@ -313,14 +351,16 @@ class TriggerTransfer @Autowired(required = false) constructor( block = mr.block, webhookQueue = mr.webhookQueue, enableCheck = mr.enableCheck, + pathFilterType = mr.pathFilterType?.let { PathFilterType.valueOf(it) }, // todo action eventType = CodeEventType.MERGE_REQUEST, - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name + repositoryName = triggerOn.repoName ) ) - ) + ).checkTriggerElementEnable(mr.enable) ) } @@ -332,12 +372,13 @@ class TriggerTransfer @Autowired(required = false) constructor( includeCrState = review.states, includeCrTypes = review.types, eventType = CodeEventType.REVIEW, - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name + repositoryName = triggerOn.repoName ) ) - ) + ).checkTriggerElementEnable(review.enable) ) } @@ -348,12 +389,13 @@ class TriggerTransfer @Autowired(required = false) constructor( input = CodeTGitWebHookTriggerInput( includeIssueAction = issue.action, eventType = CodeEventType.ISSUES, - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name + repositoryName = triggerOn.repoName ) ) - ) + ).checkTriggerElementEnable(issue.enable) ) } @@ -372,12 +414,13 @@ class TriggerTransfer @Autowired(required = false) constructor( }, includeNoteComment = note.comment.nonEmptyOrNull()?.join(), eventType = CodeEventType.NOTE, - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name + repositoryName = triggerOn.repoName ) ) - ) + ).checkTriggerElementEnable(note.enable) ) } } @@ -393,12 +436,14 @@ class TriggerTransfer @Autowired(required = false) constructor( excludePaths = push.pathsIgnore.nonEmptyOrNull()?.join(), includeUsers = push.users, excludeUsers = push.usersIgnore.nonEmptyOrNull()?.join(), + pathFilterType = push.pathFilterType?.let { PathFilterType.valueOf(it) }, eventType = CodeEventType.PUSH, // todo action - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name - ) + repositoryName = triggerOn.repoName + ).checkTriggerElementEnable(push.enable) ) } @@ -411,10 +456,11 @@ class TriggerTransfer @Autowired(required = false) constructor( includeUsers = tag.users, excludeUsers = tag.usersIgnore.nonEmptyOrNull()?.join(), eventType = CodeEventType.TAG_PUSH, - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name - ) + repositoryName = triggerOn.repoName + ).checkTriggerElementEnable(tag.enable) ) } @@ -431,12 +477,14 @@ class TriggerTransfer @Autowired(required = false) constructor( excludeUsers = mr.usersIgnore.nonEmptyOrNull()?.join(), webhookQueue = mr.webhookQueue, enableCheck = mr.enableCheck, + pathFilterType = mr.pathFilterType?.let { PathFilterType.valueOf(it) }, // todo action eventType = CodeEventType.PULL_REQUEST, - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name - ) + repositoryName = triggerOn.repoName + ).checkTriggerElementEnable(mr.enable) ) } @@ -446,10 +494,11 @@ class TriggerTransfer @Autowired(required = false) constructor( includeCrState = review.states, includeCrTypes = review.types, eventType = CodeEventType.REVIEW, - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name - ) + repositoryName = triggerOn.repoName + ).checkTriggerElementEnable(review.enable) ) } @@ -458,10 +507,11 @@ class TriggerTransfer @Autowired(required = false) constructor( CodeGithubWebHookTriggerElement( includeIssueAction = issue.action, eventType = CodeEventType.ISSUES, - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name - ) + repositoryName = triggerOn.repoName + ).checkTriggerElementEnable(issue.enable) ) } @@ -478,12 +528,94 @@ class TriggerTransfer @Autowired(required = false) constructor( }, includeNoteComment = note.comment.nonEmptyOrNull()?.join(), eventType = CodeEventType.NOTE, - repositoryType = if (triggerOn.name.isNullOrBlank()) RepositoryType.ID else RepositoryType.NAME, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, repositoryHashId = triggerOn.repoHashId, - repositoryName = triggerOn.name + repositoryName = triggerOn.repoName + ).checkTriggerElementEnable(note.enable) + ) + } + } + + @Suppress("ComplexMethod") + fun yaml2TriggerSvn(triggerOn: TriggerOn, elementQueue: MutableList) { + triggerOn.push?.let { push -> + elementQueue.add( + CodeSVNWebHookTriggerElement( + relativePath = push.paths.nonEmptyOrNull()?.join(), + excludePaths = push.pathsIgnore.nonEmptyOrNull()?.join(), + includeUsers = push.users, + excludeUsers = push.usersIgnore.nonEmptyOrNull(), + pathFilterType = push.pathFilterType?.let { PathFilterType.valueOf(it) }, + // todo action + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.repoName + ).checkTriggerElementEnable(push.enable) + ) + } + } + + @Suppress("ComplexMethod") + fun yaml2TriggerP4(triggerOn: TriggerOn, elementQueue: MutableList) { + triggerOn.push?.let { push -> + elementQueue.add( + CodeP4WebHookTriggerElement( + data = CodeP4WebHookTriggerData( + input = CodeP4WebHookTriggerInput( + includePaths = push.paths.nonEmptyOrNull()?.join(), + excludePaths = push.pathsIgnore.nonEmptyOrNull()?.join(), + eventType = CodeEventType.CHANGE_COMMIT, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.repoName + ) + ) + ).checkTriggerElementEnable(push.enable) + ) + } + } + + @Suppress("ComplexMethod") + fun yaml2TriggerBase(triggerOn: TriggerOn, elementQueue: MutableList) { + triggerOn.manual?.let { manual -> + elementQueue.add( + ManualTriggerElement( + id = "T-1-1-1", + canElementSkip = manual.canElementSkip, + useLatestParameters = manual.useLatestParameters ) ) } + triggerOn.remote?.let { remote -> + elementQueue.add( + RemoteTriggerElement( + // todo, + ).checkTriggerElementEnable(remote == EnableType.TRUE.value) + ) + } + + triggerOn.schedules?.let { remote -> + remote.forEach { timer -> + elementQueue.add( + TimerTriggerElement( + newExpression = timer.cron?.disjoin(), + advanceExpression = timer.advanceCron, + noScm = timer.always != true, + ).checkTriggerElementEnable(timer.enable) + ) + } + } + } + + private fun Element.checkTriggerElementEnable(enabled: Boolean?): Element { + if (additionalOptions == null) { + additionalOptions = ElementAdditionalOptions(runCondition = RunCondition.PRE_TASK_SUCCESS) + } + additionalOptions!!.enable = enabled ?: true + return this } private fun List.join() = this.joinToString(separator = ",") diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/VariableDefault.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/VariableDefault.kt index c74f09bc7f4..602289f3bc7 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/VariableDefault.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/VariableDefault.kt @@ -1,17 +1,21 @@ package com.tencent.devops.process.yaml.modelTransfer +import com.tencent.devops.process.yaml.v2.models.on.ManualRule + object VariableDefault { - const val DEFAULT_TASK_TIME_OUT = 480 - const val DEFAULT_JOB_TIME_OUT = 480 + const val DEFAULT_TASK_TIME_OUT = 900 + const val DEFAULT_JOB_TIME_OUT = 900 const val DEFAULT_WAIT_QUEUE_TIME_MINUTE = 480 const val DEFAULT_RETRY_COUNT = 0 const val DEFAULT_CONTINUE_WHEN_FAILED = false const val DEFAULT_PIPELINE_SETTING_MAX_QUEUE_SIZE = 10 + const val DEFAULT_JOB_PREPARE_TIMEOUT = 10 const val DEFAULT_JOB_MAX_QUEUE_MINUTES = 60 const val DEFAULT_JOB_MAX_RUNNING_MINUTES = 60 const val DEFAULT_MUTEX_QUEUE_LENGTH = 5 const val DEFAULT_MUTEX_TIMEOUT_MINUTES = 900 const val DEFAULT_MUTEX_QUEUE_ENABLE = false + val DEFAULT_MANUAL_RULE = ManualRule(canElementSkip = true, useLatestParameters = false) fun T.nullIfDefault(value: T) = if (this == value) null else this } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/WebHookTriggerElementChanger.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/WebHookTriggerElementChanger.kt index 181182740c3..b25ec90cbf6 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/WebHookTriggerElementChanger.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/WebHookTriggerElementChanger.kt @@ -30,6 +30,9 @@ package com.tencent.devops.process.yaml.modelTransfer.pojo import com.tencent.devops.common.api.enums.RepositoryType import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGitWebHookTriggerElement import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGithubWebHookTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGitlabWebHookTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeP4WebHookTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeSVNWebHookTriggerElement import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeTGitWebHookTriggerElement import com.tencent.devops.common.pipeline.pojo.element.trigger.enums.CodeEventType import com.tencent.devops.common.pipeline.pojo.element.trigger.enums.PathFilterType @@ -95,7 +98,9 @@ data class WebHookTriggerElementChanger( @ApiModelProperty("第三方应用地址") val thirdUrl: String? = null, @ApiModelProperty("第三方应用鉴权token") - val thirdSecretToken: String? = null + val thirdSecretToken: String? = null, + @ApiModelProperty("是否启用插件") + val enable: Boolean ) { constructor(data: CodeGitWebHookTriggerElement) : this( name = data.name, @@ -127,7 +132,8 @@ data class WebHookTriggerElementChanger( includePushAction = data.includePushAction, enableThirdFilter = data.enableThirdFilter, thirdUrl = data.thirdUrl, - thirdSecretToken = data.thirdSecretToken + thirdSecretToken = data.thirdSecretToken, + enable = data.isElementEnable() ) constructor(data: CodeTGitWebHookTriggerElement) : this( @@ -158,7 +164,8 @@ data class WebHookTriggerElementChanger( includeIssueAction = data.data.input.includeIssueAction, includeMrAction = data.data.input.includeMrAction, includePushAction = data.data.input.includePushAction, - enableThirdFilter = data.data.input.enableThirdFilter + enableThirdFilter = data.data.input.enableThirdFilter, + enable = data.isElementEnable() ) constructor(data: CodeGithubWebHookTriggerElement) : this( @@ -188,6 +195,53 @@ data class WebHookTriggerElementChanger( includeIssueAction = data.includeIssueAction, includeMrAction = data.includeMrAction, includePushAction = data.includePushAction, - enableThirdFilter = data.enableThirdFilter + enableThirdFilter = data.enableThirdFilter, + enable = data.isElementEnable() + ) + + constructor(data: CodeSVNWebHookTriggerElement) : this( + name = data.name, + repositoryHashId = data.repositoryHashId, + pathFilterType = data.pathFilterType, + includePaths = data.relativePath, + excludePaths = data.excludePaths, + includeUsers = data.includeUsers, + excludeUsers = data.excludeUsers, + eventType = CodeEventType.POST_COMMIT, + repositoryType = data.repositoryType, + repositoryName = data.repositoryName, + enable = data.isElementEnable() + ) + + constructor(data: CodeP4WebHookTriggerElement) : this( + name = data.name, + repositoryHashId = data.data.input.repositoryHashId, + includePaths = data.data.input.includePaths, + excludePaths = data.data.input.excludePaths, + eventType = data.data.input.eventType, + repositoryType = data.data.input.repositoryType, + repositoryName = data.data.input.repositoryName, + enable = data.isElementEnable() + ) + + constructor(data: CodeGitlabWebHookTriggerElement) : this( + name = data.name, + repositoryHashId = data.repositoryHashId, + branchName = data.branchName, + excludeBranchName = data.excludeBranchName, + pathFilterType = data.pathFilterType, + includePaths = data.includePaths, + excludePaths = data.excludePaths, + includeUsers = data.includeUsers, + excludeUsers = data.excludeUsers, + eventType = data.eventType, + block = data.block, + repositoryType = data.repositoryType, + repositoryName = data.repositoryName, + tagName = data.tagName, + excludeTagName = data.excludeTagName, + excludeSourceBranchName = data.excludeSourceBranchName, + includeSourceBranchName = data.includeSourceBranchName, + enable = data.isElementEnable() ) } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Notices.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Notices.kt index 12a3abb0a3b..0115e75727c 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Notices.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Notices.kt @@ -68,7 +68,7 @@ data class GitNotices( ) : Notices { constructor(subscription: Subscription, ifField: String?) : this( - type = subscription.types.map { PacNotices.toNotifyType(it) }.toMutableList().also { + type = subscription.types.map { PacNotices.toNotifyType(it) }.toMutableList().apply { sort() }.also { if (subscription.wechatGroupFlag) it.add(NotifyType.RTX_GROUP.yamlText) }.first(), receivers = subscription.users.split(",").ifEmpty { null }?.toSet(), @@ -124,11 +124,11 @@ data class PacNotices( ) : Notices { constructor(subscription: Subscription, ifField: String?) : this( - type = subscription.types.map { toNotifyType(it) }.toMutableList().also { + type = subscription.types.map { toNotifyType(it) }.toMutableList().apply { sort() }.also { if (subscription.wechatGroupFlag) it.add(NotifyType.RTX_GROUP.yamlText) }, receivers = subscription.users.ifBlank { null }?.split(",")?.toSet()?.toList(), - groups = subscription.groups.ifEmpty { null }?.toList(), + groups = subscription.groups.ifEmpty { null }?.sorted(), content = subscription.content.ifEmpty { null }, ifField = ifField, chatId = subscription.wechatGroup.ifBlank { null }?.split(",")?.toSet()?.toList(), diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt index 408cf7221cd..91c48a8c463 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt @@ -41,6 +41,7 @@ import com.tencent.devops.process.yaml.v2.models.on.TriggerOn import com.tencent.devops.process.yaml.v2.models.stage.Stage import com.tencent.devops.process.yaml.v2.utils.ScriptYmlUtils import com.tencent.devops.process.yaml.v3.models.PreTemplateScriptBuildYamlV3 +import com.tencent.devops.process.yaml.v3.models.TriggerType @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, @@ -63,7 +64,7 @@ interface IPreTemplateScriptBuildYaml : YamlVersion { fun formatVariables(): Map - fun formatTriggerOn(default: ScmType): Map + fun formatTriggerOn(default: ScmType): List> fun formatStages(): List @@ -106,8 +107,8 @@ data class PreTemplateScriptBuildYaml( override val steps: List>? = null, override val extends: Extends?, override val resources: Resources?, - override val notices: List?, override var finally: Map?, + override val notices: List?, override val concurrency: Concurrency? = null ) : IPreTemplateScriptBuildYaml, ITemplateFilter { override fun yamlVersion() = YamlVersion.Version.V2_0 @@ -136,8 +137,8 @@ data class PreTemplateScriptBuildYaml( return preYaml.variables ?: emptyMap() } - override fun formatTriggerOn(default: ScmType): Map { - return mapOf(default to ScriptYmlUtils.formatTriggerOn(triggerOn)) + override fun formatTriggerOn(default: ScmType): List> { + return listOf(TriggerType.parse(default) to ScriptYmlUtils.formatTriggerOn(triggerOn)) } override fun formatStages(): List { diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Variable.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Variable.kt index ae027e85917..df18a991ad6 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Variable.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Variable.kt @@ -73,6 +73,8 @@ data class Variable( val readonly: Boolean? = false, @JsonProperty("allow-modify-at-startup") val allowModifyAtStartup: Boolean? = false, + @JsonProperty("value-not-empty") + val valueNotEmpty: Boolean? = false, val props: VariableProps? = null ) : IVariable diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/PoolType.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/PoolType.kt index 09522a54019..aa5fe852049 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/PoolType.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/PoolType.kt @@ -66,6 +66,7 @@ enum class PoolType { override fun transfer(dispatcher: DispatchType): RunsOn? { if (dispatcher is DockerDispatchType) { return RunsOn( + selfHosted = null, poolName = JobRunsOnType.DOCKER.type, container = when (dispatcher.imageType) { ImageType.BKSTORE, ImageType.THIRD -> Container2( @@ -153,7 +154,7 @@ enum class PoolType { credentials = with(dockerInfo.credential) { when { this == null -> null - credentialId != null -> dockerInfo.credential?.credentialId + credentialId != null -> dockerInfo.credential?.credentialId?.ifBlank { null } user != null && password != null -> Credentials(user!!, password!!) else -> null } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/IssueRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/IssueRule.kt index 4fc20022638..a9d0a524912 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/IssueRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/IssueRule.kt @@ -33,5 +33,6 @@ import com.fasterxml.jackson.annotation.JsonInclude @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class IssueRule( + val enable: Boolean? = true, val action: List? = null ) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ManualRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ManualRule.kt new file mode 100644 index 00000000000..f964fa95a8e --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ManualRule.kt @@ -0,0 +1,52 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v2.models.on + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import io.swagger.annotations.ApiModelProperty + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class ManualRule( + @ApiModelProperty("手动触发执行时可跳过插件 ", name = "can-element-skip", required = false) + @JsonProperty("can-element-skip") + var canElementSkip: Boolean? = true, + @ApiModelProperty("手动触发执行时使用最近一次构建参数值 ", name = "use-latest-parameters", required = false) + @JsonProperty("use-latest-parameters") + var useLatestParameters: Boolean? = false +) { + override fun equals(other: Any?): Boolean { + if (other is ManualRule) { + return (other.canElementSkip == canElementSkip || other.canElementSkip == null) && + (other.useLatestParameters == useLatestParameters || other.useLatestParameters == null) + } + return super.equals(other) + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/MrRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/MrRule.kt index dc067a64d34..a26bcb3340b 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/MrRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/MrRule.kt @@ -38,6 +38,7 @@ import io.swagger.annotations.ApiModelProperty @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class MrRule( + val enable: Boolean? = true, @ApiModelProperty(name = "source-branches") @JsonProperty("source-branches") val sourceBranches: List? = null, @@ -72,5 +73,9 @@ data class MrRule( val webhookQueue: Boolean? = null, - val enableCheck: Boolean? = null + val enableCheck: Boolean? = null, + + @ApiModelProperty(name = "path-filter-type") + @JsonProperty("path-filter-type") + val pathFilterType: String? = null ) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/NoteRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/NoteRule.kt index dd0bef4f063..861c18bf577 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/NoteRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/NoteRule.kt @@ -33,6 +33,7 @@ import com.fasterxml.jackson.annotation.JsonInclude @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) class NoteRule( + val enable: Boolean? = true, val types: List? = null, val comment: List? = null ) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/PushRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/PushRule.kt index 6214ffd5a67..93e441be6f1 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/PushRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/PushRule.kt @@ -38,7 +38,8 @@ import io.swagger.annotations.ApiModelProperty @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class PushRule( - val branches: List = listOf("*"), + val enable: Boolean? = true, + val branches: List? = listOf("*"), @ApiModelProperty(name = "branches-ignore") @JsonProperty("branches-ignore") @@ -56,5 +57,9 @@ data class PushRule( @JsonProperty("users-ignore") val usersIgnore: List? = null, - val action: List? = null + val action: List? = null, + + @ApiModelProperty(name = "path-filter-type") + @JsonProperty("path-filter-type") + val pathFilterType: String? = null ) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ReviewRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ReviewRule.kt index 4a02ca2e007..18cd25938f0 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ReviewRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ReviewRule.kt @@ -33,6 +33,7 @@ import com.fasterxml.jackson.annotation.JsonInclude @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class ReviewRule( + val enable: Boolean? = true, val types: List? = null, val states: List? = null ) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/SchedulesRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/SchedulesRule.kt index e693487d4ff..148aa59c093 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/SchedulesRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/SchedulesRule.kt @@ -29,6 +29,8 @@ package com.tencent.devops.process.yaml.v2.models.on import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import io.swagger.annotations.ApiModelProperty /** * model @@ -36,7 +38,13 @@ import com.fasterxml.jackson.annotation.JsonInclude @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class SchedulesRule( - val cron: String, + val enable: Boolean? = true, + val cron: String? = null, + + @ApiModelProperty(name = "advance-cron") + @JsonProperty("advance-cron") + val advanceCron: List? = null, + val branches: List? = null, diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TagRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TagRule.kt index f34fd78f1e3..009950765a3 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TagRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TagRule.kt @@ -38,6 +38,7 @@ import io.swagger.annotations.ApiModelProperty @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class TagRule( + val enable: Boolean? = true, val tags: List? = null, @ApiModelProperty(name = "tags-ignore") diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TriggerOn.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TriggerOn.kt index 4ba23f1c223..eca175c5726 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TriggerOn.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TriggerOn.kt @@ -30,6 +30,8 @@ package com.tencent.devops.process.yaml.v2.models.on import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_MANUAL_RULE +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault import com.tencent.devops.process.yaml.pojo.YamlVersion import com.tencent.devops.process.yaml.v2.models.RepositoryHook import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 @@ -44,7 +46,7 @@ data class TriggerOn( var push: PushRule? = null, var tag: TagRule? = null, var mr: MrRule? = null, - var schedules: SchedulesRule? = null, + var schedules: List? = null, var delete: DeleteRule? = null, var issue: IssueRule? = null, var review: ReviewRule? = null, @@ -52,46 +54,55 @@ data class TriggerOn( @ApiModelProperty(name = "repo_hook") @JsonProperty("repo_hook") val repoHook: RepositoryHook? = null, - val manual: String? = null, + var manual: ManualRule? = null, + var remote: String? = null, val openapi: String? = null, - var name: String? = null, + var repoName: String? = null, + var triggerName: String? = null, @JsonProperty("repoId") @ApiModelProperty(name = "repoId") var repoHashId: String? = null, var credentials: String? = null ) { - fun toPreV2() = PreTriggerOn( + fun toPre(version: YamlVersion.Version) = when (version) { + YamlVersion.Version.V2_0 -> toPreV2() + YamlVersion.Version.V3_0 -> toPreV3() + } + + private fun toPreV2() = PreTriggerOn( push = push, tag = tag, mr = mr, - schedules = schedules, + schedules = schedules?.firstOrNull(), delete = delete, issue = issue, review = review, note = note, // todo repoHook = null, - manual = manual, - openapi = openapi + manual = manual?.let { EnableType.TRUE.value } ?: EnableType.FALSE.value, + openapi = openapi, + remote = remote ) - fun toPreV3() = PreTriggerOnV3( - name = name, + private fun toPreV3() = PreTriggerOnV3( + repoName = repoName, repoHashId = repoHashId, type = null, credentials = credentials, push = push, tag = tag, mr = mr, - schedules = schedules, + schedules = if (schedules?.size == 1) schedules!!.first() else schedules, delete = delete, issue = issue, review = review, note = note, // todo repoHook = null, - manual = manual, - openapi = openapi + manual = (manual ?: EnableType.FALSE.value).nullIfDefault(DEFAULT_MANUAL_RULE), + openapi = openapi, + remote = remote ) } @@ -99,14 +110,15 @@ interface IPreTriggerOn : YamlVersion { val push: Any? val tag: Any? val mr: Any? - val schedules: SchedulesRule? + val schedules: Any? val delete: DeleteRule? val issue: IssueRule? val review: ReviewRule? val note: NoteRule? val repoHook: List? - val manual: String? + val manual: Any? val openapi: String? + val remote: String? } @JsonInclude(JsonInclude.Include.NON_NULL) @@ -115,7 +127,7 @@ data class PreTriggerOn( override val push: Any?, override val tag: Any?, override val mr: Any?, - override val schedules: SchedulesRule?, + override val schedules: Any?, override val delete: DeleteRule?, override val issue: IssueRule? = null, override val review: ReviewRule? = null, @@ -123,8 +135,9 @@ data class PreTriggerOn( @ApiModelProperty(name = "repo_hook") @JsonProperty("repo_hook") override val repoHook: List? = null, - override val manual: String? = null, - override val openapi: String? = null + override val manual: Any? = null, + override val openapi: String? = null, + override val remote: String? = null ) : IPreTriggerOn { override fun yamlVersion() = YamlVersion.Version.V2_0 } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/ScriptYmlUtils.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/ScriptYmlUtils.kt index f58cf291ecb..4ba51911949 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/ScriptYmlUtils.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/ScriptYmlUtils.kt @@ -73,6 +73,7 @@ import com.tencent.devops.process.yaml.v2.models.on.DeleteRule import com.tencent.devops.process.yaml.v2.models.on.EnableType import com.tencent.devops.process.yaml.v2.models.on.IPreTriggerOn import com.tencent.devops.process.yaml.v2.models.on.IssueRule +import com.tencent.devops.process.yaml.v2.models.on.ManualRule import com.tencent.devops.process.yaml.v2.models.on.MrRule import com.tencent.devops.process.yaml.v2.models.on.NoteRule import com.tencent.devops.process.yaml.v2.models.on.PreTriggerOn @@ -658,7 +659,8 @@ object ScriptYmlUtils { note = noteRule(repoPreTriggerOn), repoHook = repoHookRule(repositoryHook), manual = manualRule(repoPreTriggerOn), - openapi = openapiRule(repoPreTriggerOn) + openapi = openapiRule(repoPreTriggerOn), + remote = remoteRule(repoPreTriggerOn) ) } logger.warn("repo hook has none effective TriggerOn in ($repositoryHookList)") @@ -695,11 +697,12 @@ object ScriptYmlUtils { review = reviewRule(preTriggerOn), note = noteRule(preTriggerOn), manual = manualRule(preTriggerOn), - openapi = openapiRule(preTriggerOn) + openapi = openapiRule(preTriggerOn), + remote = remoteRule(preTriggerOn) ) if (preTriggerOn is PreTriggerOnV3) { - res.name = preTriggerOn.name + res.repoName = preTriggerOn.repoName res.credentials = preTriggerOn.credentials } @@ -745,16 +748,23 @@ object ScriptYmlUtils { private fun manualRule( preTriggerOn: IPreTriggerOn - ): String? { + ): ManualRule? { if (preTriggerOn.manual == null) { - return null + return ManualRule() } - if (preTriggerOn.manual != EnableType.TRUE.value && preTriggerOn.manual != EnableType.FALSE.value) { - throw YamlFormatException("not allow manual type ${preTriggerOn.manual}") + return when { + preTriggerOn.manual is String && preTriggerOn.manual == EnableType.TRUE.value -> { + return ManualRule() + } + preTriggerOn.manual is String && preTriggerOn.manual == EnableType.FALSE.value -> { + return null + } + preTriggerOn.manual is Map<*, *> -> kotlin.runCatching { + JsonUtil.anyTo(preTriggerOn.manual, object : TypeReference() {}) + }.getOrElse { ManualRule() } + else -> ManualRule() } - - return preTriggerOn.manual } private fun openapiRule( @@ -771,6 +781,20 @@ object ScriptYmlUtils { return preTriggerOn.openapi } + private fun remoteRule( + preTriggerOn: IPreTriggerOn + ): String? { + if (preTriggerOn.remote == null) { + return null + } + + if (preTriggerOn.remote != EnableType.TRUE.value && preTriggerOn.remote != EnableType.FALSE.value) { + throw YamlFormatException("not allow remote type ${preTriggerOn.openapi}") + } + + return preTriggerOn.remote + } + private fun noteRule( preTriggerOn: IPreTriggerOn ): NoteRule? { @@ -841,17 +865,16 @@ object ScriptYmlUtils { private fun schedulesRule( preTriggerOn: IPreTriggerOn - ): SchedulesRule? { + ): List? { if (preTriggerOn.schedules != null) { val schedules = preTriggerOn.schedules!! - return try { - YamlUtil.getObjectMapper().readValue( - JsonUtil.toJson(schedules), - SchedulesRule::class.java - ) - } catch (e: MismatchedInputException) { - null - } + return kotlin.runCatching { + when (schedules) { + is Map<*, *> -> listOf(JsonUtil.anyTo(schedules, object : TypeReference() {})) + is List<*> -> JsonUtil.anyTo(schedules, object : TypeReference>() {}) + else -> null + } + }.getOrNull() } return null } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYamlV3.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYamlV3.kt index baa4fc15a0a..e5a90e8ccd2 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYamlV3.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYamlV3.kt @@ -64,8 +64,8 @@ data class PreTemplateScriptBuildYamlV3( override val steps: List>? = null, override val extends: Extends?, override val resources: Resources?, - override val notices: List?, override var finally: Map?, + override val notices: List?, override val concurrency: Concurrency? = null ) : IPreTemplateScriptBuildYaml, ITemplateFilter { override fun yamlVersion() = YamlVersion.Version.V3_0 @@ -97,9 +97,20 @@ data class PreTemplateScriptBuildYamlV3( return preYaml.variables ?: emptyMap() } - override fun formatTriggerOn(default: ScmType): Map { - return makeRunsOn()?.associateBy({ ScmType.parse(it.type) ?: default }, { ScriptYmlUtils.formatTriggerOn(it) }) - ?: emptyMap() + override fun formatTriggerOn(default: ScmType): List> { + val runsOn = makeRunsOn() ?: return listOf( + TriggerType.parse(default) to ScriptYmlUtils.formatTriggerOn(null) + ) + + val res = mutableListOf>() + runsOn.forEach { + if (it.repoName == null && it.repoHashId == null && it.type == null) { + res.add(TriggerType.BASE to ScriptYmlUtils.formatTriggerOn(it)) + return@forEach + } + res.add((TriggerType.parse(it.type) ?: TriggerType.parse(default)) to ScriptYmlUtils.formatTriggerOn(it)) + } + return res } override fun formatStages(): List { diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/TriggerType.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/TriggerType.kt new file mode 100644 index 00000000000..e97b34a0a28 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/TriggerType.kt @@ -0,0 +1,57 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +import com.tencent.devops.common.api.enums.ScmType + +enum class TriggerType(val alis: String) { + CODE_SVN("svn"), + CODE_GIT("git"), + CODE_GITLAB("gitlab"), + GITHUB("github"), + CODE_TGIT("tgit"), + CODE_P4("p4"), + BASE("base") + ; + + companion object { + + fun parse(alis: String?): TriggerType? { + values().forEach { + if (alis == it.alis) return it + } + return null + } + fun parse(scm: ScmType): TriggerType { + values().forEach { + if (scm.name == it.name) return it + } + return BASE + } + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PreTriggerOnV3.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PreTriggerOnV3.kt index d8c0e8b4a55..71bf2052cc2 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PreTriggerOnV3.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PreTriggerOnV3.kt @@ -36,20 +36,19 @@ import com.tencent.devops.process.yaml.v2.models.on.IPreTriggerOn import com.tencent.devops.process.yaml.v2.models.on.IssueRule import com.tencent.devops.process.yaml.v2.models.on.NoteRule import com.tencent.devops.process.yaml.v2.models.on.ReviewRule -import com.tencent.devops.process.yaml.v2.models.on.SchedulesRule import io.swagger.annotations.ApiModelProperty @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class PreTriggerOnV3( - val name: String?, + val repoName: String?, var repoHashId: String?, var type: String?, val credentials: String?, override val push: Any?, override val tag: Any?, override val mr: Any?, - override val schedules: SchedulesRule?, + override val schedules: Any?, override val delete: DeleteRule?, override val issue: IssueRule? = null, override val review: ReviewRule? = null, @@ -57,8 +56,9 @@ data class PreTriggerOnV3( @ApiModelProperty(name = "repo_hook") @JsonProperty("repo_hook") override val repoHook: List? = null, - override val manual: String? = null, - override val openapi: String? = null + override val manual: Any? = null, + override val openapi: String? = null, + override val remote: String? = null ) : IPreTriggerOn { override fun yamlVersion() = YamlVersion.Version.V3_0 } diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/BuildFormProperty.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/BuildFormProperty.kt index a002e3d6bde..53cfde749f4 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/BuildFormProperty.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/BuildFormProperty.kt @@ -80,5 +80,9 @@ data class BuildFormProperty( @ApiModelProperty("替换搜索url中的搜素关键字", required = false) var replaceKey: String? = null, @ApiModelProperty("是否只读", required = false) - val readOnly: Boolean? = false + val readOnly: Boolean? = false, + @ApiModelProperty("参数值是否必填", required = false) + val valueNotEmpty: Boolean? = false, + @ApiModelProperty("页面所需内容,后台仅保存,不做处理", required = false) + val payload: Any? = null ) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt index 4e2f346898f..833a33c6a65 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt @@ -149,7 +149,7 @@ class PipelineTransferYamlService @Autowired constructor( pipelineId: String, data: Element ): String { - val yml = elementTransfer.element2YamlStep(data) ?: throw ErrorCodeException(errorCode = "") + val yml = elementTransfer.element2YamlStep(data, projectId) ?: throw ErrorCodeException(errorCode = "") return TransferMapper.toYaml(yml) } diff --git a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlBuild.kt b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlBuild.kt index 8f53f2c36af..11a29fec6fa 100644 --- a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlBuild.kt +++ b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/StreamYamlBuild.kt @@ -271,18 +271,19 @@ class StreamYamlBuild @Autowired constructor( val pipeline = action.data.context.pipeline!! // 如果是定时触发需要注册事件 if (triggerResult.timeTrigger) { + val schedules = yaml.triggerOn?.schedules?.firstOrNull() streamTimerService.saveTimer( StreamTimer( projectId = action.getProjectCode(), pipelineId = pipeline.pipelineId, userId = action.data.getUserId(), - crontabExpressions = listOf(yaml.triggerOn?.schedules?.cron.toString()), + crontabExpressions = listOf(schedules?.cron.toString()), gitProjectId = action.data.getGitProjectId().toLong(), // 未填写则在每次触发拉默认分支 - branchs = yaml.triggerOn?.schedules?.branches?.ifEmpty { + branchs = schedules?.branches?.ifEmpty { listOf(action.data.context.defaultBranch!!) } ?: listOf(action.data.context.defaultBranch!!), - always = yaml.triggerOn?.schedules?.always ?: false, + always = schedules?.always ?: false, channelCode = channelCode, eventId = action.data.context.requestEventId!!, originYaml = action.data.context.originYaml!! diff --git a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/actions/github/GithubPushActionGit.kt b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/actions/github/GithubPushActionGit.kt index 4e0eec328d6..48ad2fac0f6 100644 --- a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/actions/github/GithubPushActionGit.kt +++ b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/actions/github/GithubPushActionGit.kt @@ -368,7 +368,7 @@ class GithubPushActionGit( userId: String, pipelineId: String ): Boolean { - if (triggerOn.schedules == null) { + if (triggerOn.schedules.isNullOrEmpty()) { // 新流水线没有定时任务就没注册过定时任务 if (pipelineId.isBlank()) { return false @@ -379,7 +379,7 @@ class GithubPushActionGit( return false } } else { - if (triggerOn.schedules?.cron.isNullOrBlank()) { + if (triggerOn.schedules?.firstOrNull()?.cron.isNullOrBlank()) { logger.info("The schedules cron is invalid($eventBranch)") return false } diff --git a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/actions/tgit/TGitPushActionGit.kt b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/actions/tgit/TGitPushActionGit.kt index 9186122274f..6d7ca55bb9b 100644 --- a/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/actions/tgit/TGitPushActionGit.kt +++ b/src/backend/ci/core/stream/biz-stream/src/main/kotlin/com/tencent/devops/stream/trigger/actions/tgit/TGitPushActionGit.kt @@ -382,7 +382,7 @@ class TGitPushActionGit( userId: String, pipelineId: String ): Boolean { - if (triggerOn.schedules == null) { + if (triggerOn.schedules.isNullOrEmpty()) { // 新流水线没有定时任务就没注册过定时任务 if (pipelineId.isBlank()) { return false @@ -393,7 +393,7 @@ class TGitPushActionGit( return false } } else { - if (triggerOn.schedules?.cron.isNullOrBlank()) { + if (triggerOn.schedules?.firstOrNull()?.cron.isNullOrBlank()) { logger.info("The schedules cron is invalid($eventBranch)") return false } From 5d0521e07d404d154391cd98fc5b4019076b5da8 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 28 Aug 2023 20:55:00 +0800 Subject: [PATCH 088/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E4=BC=98=E5=8C=96=E8=8D=89=E7=A8=BF=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/pipeline/PipelineModelWithYaml.kt | 2 ++ .../engine/dao/PipelineResourceVersionDao.kt | 10 +++---- .../service/PipelineRepositoryService.kt | 26 +++++++++---------- .../api/ServicePipelineResourceImpl.kt | 3 ++- .../api/ServicePipelineVersionResourceImpl.kt | 3 ++- .../process/api/UserPipelineResourceImpl.kt | 5 ++-- .../api/UserPipelineVersionResourceImpl.kt | 8 +++--- .../service/PipelineInfoFacadeService.kt | 13 +++++----- .../pipeline/PipelineSettingFacadeService.kt | 4 +-- 9 files changed, 41 insertions(+), 33 deletions(-) diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelWithYaml.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelWithYaml.kt index 38bf51a54a9..4133df642c5 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelWithYaml.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/PipelineModelWithYaml.kt @@ -39,6 +39,8 @@ data class PipelineModelWithYaml( val modelAndSetting: PipelineModelAndSetting, @ApiModelProperty("流水线YAML编排(不为空时以YAML为准)", required = false) val yaml: String?, + @ApiModelProperty("是否处在可以调试状态", required = false) + val canDebug: Boolean?, @ApiModelProperty("版本变更说明", required = false) val description: String? ) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceVersionDao.kt index 81421338a55..8c616d0d71d 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceVersionDao.kt @@ -57,7 +57,7 @@ class PipelineResourceVersionDao { pipelineVersion: Int?, triggerVersion: Int?, settingVersion: Int?, - status: VersionStatus?, + versionStatus: VersionStatus?, description: String? ): TPipelineResourceVersionRecord? { return create( @@ -73,7 +73,7 @@ class PipelineResourceVersionDao { pipelineVersion = pipelineVersion, triggerVersion = triggerVersion, settingVersion = settingVersion, - status = status, + versionStatus = versionStatus, description = description ) } @@ -91,7 +91,7 @@ class PipelineResourceVersionDao { pipelineVersion: Int?, triggerVersion: Int?, settingVersion: Int?, - status: VersionStatus?, + versionStatus: VersionStatus?, description: String? ): TPipelineResourceVersionRecord? { with(T_PIPELINE_RESOURCE_VERSION) { @@ -107,7 +107,7 @@ class PipelineResourceVersionDao { .set(PIPELINE_VERSION, pipelineVersion) .set(TRIGGER_VERSION, triggerVersion) .set(SETTING_VERSION, settingVersion) - .set(STATUS, status?.name) + .set(STATUS, versionStatus?.name) .set(DESCRIPTION, description) .set(BASE_VERSION, baseVersion) .onDuplicateKeyUpdate() @@ -118,7 +118,7 @@ class PipelineResourceVersionDao { .set(PIPELINE_VERSION, pipelineVersion) .set(TRIGGER_VERSION, triggerVersion) .set(SETTING_VERSION, settingVersion) - .set(STATUS, status?.name) + .set(STATUS, versionStatus?.name) .set(DESCRIPTION, description) .returning() .fetchOne() diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index 88f36a81aa8..8b5bcac3e5f 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -206,7 +206,7 @@ class PipelineRepositoryService constructor( templateId: String? = null, updateLastModifyUser: Boolean? = true, savedSetting: PipelineSetting? = null, - saveDraft: Boolean? = false, + versionStatus: VersionStatus? = VersionStatus.RELEASED, description: String? = null ): DeployPipelineResult { @@ -252,7 +252,7 @@ class PipelineRepositoryService constructor( channelCode = channelCode, setting = pipelineSetting, updateLastModifyUser = updateLastModifyUser, - saveDraft = saveDraft, + versionStatus = versionStatus, description = description, baseVersion = baseVersion ) @@ -261,7 +261,7 @@ class PipelineRepositoryService constructor( projectId = projectId, pipelineId = pipelineId, version = result.version, - operationLogType = if (saveDraft == true) { + operationLogType = if (versionStatus != VersionStatus.RELEASED) { OperationLogType.UPDATE_DRAFT_VERSION } else { OperationLogType.NORMAL_SAVE_OPERATION @@ -286,7 +286,7 @@ class PipelineRepositoryService constructor( useLabelSettings = useLabelSettings, useConcurrencyGroup = useConcurrencyGroup, templateId = templateId, - saveDraft = saveDraft, + versionStatus = versionStatus, description = description, baseVersion = baseVersion ) @@ -295,7 +295,7 @@ class PipelineRepositoryService constructor( projectId = projectId, pipelineId = pipelineId, version = result.version, - operationLogType = if (saveDraft == true) { + operationLogType = if (versionStatus != VersionStatus.RELEASED) { OperationLogType.CREATE_PIPELINE_AND_DRAFT } else { OperationLogType.NORMAL_SAVE_OPERATION @@ -589,7 +589,7 @@ class PipelineRepositoryService constructor( useLabelSettings: Boolean? = false, useConcurrencyGroup: Boolean? = false, templateId: String? = null, - saveDraft: Boolean? = false, + versionStatus: VersionStatus? = VersionStatus.RELEASED, description: String? ): DeployPipelineResult { val modelVersion = 1 @@ -711,7 +711,7 @@ class PipelineRepositoryService constructor( versionName = PipelineVersionUtils.getVersionName( pipelineVersion, triggerVersion, settingVersion ) - if (saveDraft != true) pipelineResourceDao.create( + if (versionStatus == VersionStatus.RELEASED) pipelineResourceDao.create( dslContext = transactionContext, projectId = projectId, pipelineId = pipelineId, @@ -737,7 +737,7 @@ class PipelineRepositoryService constructor( pipelineVersion = modelVersion, triggerVersion = triggerVersion, settingVersion = settingVersion, - status = if (saveDraft == true) VersionStatus.COMMITTING else VersionStatus.RELEASED, + versionStatus = versionStatus, description = description ) // 初始化流水线构建统计表 @@ -781,14 +781,14 @@ class PipelineRepositoryService constructor( channelCode: ChannelCode, setting: PipelineSetting? = null, updateLastModifyUser: Boolean? = true, - saveDraft: Boolean? = false, + versionStatus: VersionStatus? = VersionStatus.RELEASED, baseVersion: Int?, description: String? ): DeployPipelineResult { val taskCount: Int = model.taskCount() var version = 0 val lock = PipelineModelLock(redisOperation, pipelineId) - val watcher = Watcher(id = "updatePipeline#$pipelineId#$saveDraft") + val watcher = Watcher(id = "updatePipeline#$pipelineId#$versionStatus") var versionName: String? = null try { lock.lock() @@ -856,7 +856,7 @@ class PipelineRepositoryService constructor( pipelineVersion, triggerVersion, settingVersion ) watcher.start("updatePipelineResource") - if (saveDraft != true) pipelineResourceDao.create( + if (versionStatus == VersionStatus.RELEASED) pipelineResourceDao.create( dslContext = transactionContext, projectId = projectId, pipelineId = pipelineId, @@ -881,7 +881,7 @@ class PipelineRepositoryService constructor( pipelineVersion = pipelineVersion, triggerVersion = triggerVersion, settingVersion = settingVersion, - status = if (saveDraft == true) VersionStatus.COMMITTING else VersionStatus.RELEASED, + versionStatus = versionStatus, description = description, baseVersion = baseVersion ?: (version - 1) ) @@ -914,7 +914,7 @@ class PipelineRepositoryService constructor( pipelineVersion = null, triggerVersion = null, settingVersion = null, - status = VersionStatus.RELEASED, + versionStatus = VersionStatus.RELEASED, description = description, baseVersion = (version - 1).coerceAtLeast(0) ) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt index f954fd8a765..4f3a96f578c 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt @@ -39,6 +39,7 @@ import com.tencent.devops.common.event.pojo.measure.PipelineLabelRelateInfo import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.ModelUpdate import com.tencent.devops.common.pipeline.enums.ChannelCode +import com.tencent.devops.common.pipeline.enums.VersionStatus import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting import com.tencent.devops.common.web.RestResource import com.tencent.devops.common.web.utils.I18nUtil @@ -231,7 +232,7 @@ class ServicePipelineResourceImpl @Autowired constructor( pipelineId = pipelineId, model = modelAndSetting.model, setting = modelAndSetting.setting, - saveDraft = saveDraft, + versionStatus = VersionStatus.RELEASED, channelCode = ChannelCode.BS ) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt index 77e00b3b506..5ce59fbad3e 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineVersionResourceImpl.kt @@ -36,6 +36,7 @@ import com.tencent.devops.common.auth.api.AuthPermission import com.tencent.devops.common.auth.api.AuthResourceType import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.enums.ChannelCode +import com.tencent.devops.common.pipeline.enums.VersionStatus import com.tencent.devops.common.web.RestResource import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.api.service.ServicePipelineVersionResource @@ -79,7 +80,7 @@ class ServicePipelineVersionResourceImpl @Autowired constructor( channelCode = ChannelCode.BS, checkPermission = true, checkTemplate = true, - saveDraft = true, + versionStatus = VersionStatus.COMMITTING, description = description ) auditService.createAudit( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index 2d5e0095811..ece73953186 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -39,6 +39,7 @@ import com.tencent.devops.common.auth.api.AuthResourceType import com.tencent.devops.common.client.Client import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.enums.ChannelCode +import com.tencent.devops.common.pipeline.enums.VersionStatus import com.tencent.devops.common.pipeline.pojo.MatrixPipelineInfo import com.tencent.devops.common.pipeline.utils.MatrixYamlCheckUtils import com.tencent.devops.common.web.RestResource @@ -243,7 +244,7 @@ class UserPipelineResourceImpl @Autowired constructor( pipelineId = pipelineId, model = pipeline, yaml = null, - saveDraft = saveDraft, + versionStatus = VersionStatus.RELEASED, channelCode = ChannelCode.BS ) auditService.createAudit( @@ -279,7 +280,7 @@ class UserPipelineResourceImpl @Autowired constructor( pipelineId = pipelineId, model = modelAndSetting.model, setting = modelAndSetting.setting, - saveDraft = saveDraft, + versionStatus = VersionStatus.RELEASED, channelCode = ChannelCode.BS ) auditService.createAudit( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index 82a654b4c08..597571d7c8f 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -38,6 +38,7 @@ import com.tencent.devops.common.auth.api.AuthResourceType import com.tencent.devops.common.pipeline.PipelineModelWithYaml import com.tencent.devops.common.pipeline.PipelineModelWithYamlRequest import com.tencent.devops.common.pipeline.enums.ChannelCode +import com.tencent.devops.common.pipeline.enums.VersionStatus import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting import com.tencent.devops.common.pipeline.pojo.TemplateInstanceCreateRequest import com.tencent.devops.common.web.RestResource @@ -214,6 +215,7 @@ class UserPipelineVersionResourceImpl @Autowired constructor( modelAndSetting = modelAndSetting, yaml = yaml, description = resource.description, + canDebug = resource.status == VersionStatus.COMMITTING, version = resource.version, versionName = resource.versionName ) @@ -288,14 +290,14 @@ class UserPipelineVersionResourceImpl @Autowired constructor( oldYaml = baseVersion?.yaml ?: "" ) ) + // TODO #8161 模板的草稿如何处理 val savedSetting = pipelineSettingFacadeService.saveSetting( userId = userId, projectId = projectId, pipelineId = pipelineId, setting = transferResult.modelAndSetting?.setting ?: modelAndYaml.modelAndSetting.setting, checkPermission = false, - dispatchPipelineUpdateEvent = false, - saveDraft = true + dispatchPipelineUpdateEvent = false ) val pipelineResult = pipelineInfoFacadeService.editPipeline( userId = userId, @@ -305,7 +307,7 @@ class UserPipelineVersionResourceImpl @Autowired constructor( channelCode = ChannelCode.BS, checkPermission = false, checkTemplate = false, - saveDraft = true, + versionStatus = VersionStatus.COMMITTING, description = modelAndYaml.description, yaml = transferResult.newYaml, savedSetting = savedSetting diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index 0ab6e429128..a753be18fb5 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -46,6 +46,7 @@ import com.tencent.devops.common.pipeline.ModelUpdate import com.tencent.devops.common.pipeline.container.TriggerContainer import com.tencent.devops.common.pipeline.enums.ChannelCode import com.tencent.devops.common.pipeline.enums.PipelineInstanceTypeEnum +import com.tencent.devops.common.pipeline.enums.VersionStatus import com.tencent.devops.common.pipeline.extend.ModelCheckPlugin import com.tencent.devops.common.pipeline.pojo.BuildFormProperty import com.tencent.devops.common.pipeline.pojo.BuildNo @@ -679,7 +680,7 @@ class PipelineInfoFacadeService @Autowired constructor( checkTemplate: Boolean = true, updateLastModifyUser: Boolean? = true, savedSetting: PipelineSetting? = null, - saveDraft: Boolean? = false, + versionStatus: VersionStatus? = VersionStatus.RELEASED, description: String? = null, baseVersion: Int? = null ): DeployPipelineResult { @@ -762,7 +763,7 @@ class PipelineInfoFacadeService @Autowired constructor( create = false, updateLastModifyUser = updateLastModifyUser, savedSetting = savedSetting, - saveDraft = saveDraft, + versionStatus = versionStatus, description = description, yamlStr = yaml, baseVersion = baseVersion @@ -827,16 +828,16 @@ class PipelineInfoFacadeService @Autowired constructor( channelCode: ChannelCode, checkPermission: Boolean = true, checkTemplate: Boolean = true, - saveDraft: Boolean? = false + versionStatus: VersionStatus? = VersionStatus.RELEASED ): DeployPipelineResult { + // TODO #8161 模板的草稿如何处理 val savedSetting = pipelineSettingFacadeService.saveSetting( userId = userId, projectId = projectId, pipelineId = pipelineId, setting = setting, checkPermission = false, - dispatchPipelineUpdateEvent = false, - saveDraft = saveDraft + dispatchPipelineUpdateEvent = false ) val pipelineResult = editPipeline( userId = userId, @@ -848,7 +849,7 @@ class PipelineInfoFacadeService @Autowired constructor( checkPermission = checkPermission, checkTemplate = checkTemplate, savedSetting = savedSetting, - saveDraft = saveDraft + versionStatus = versionStatus ) if (setting.projectId.isBlank()) { setting.projectId = projectId diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt index e14fd10eef8..7b62f45b3ec 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt @@ -37,6 +37,7 @@ import com.tencent.devops.common.auth.api.AuthResourceType import com.tencent.devops.common.client.Client import com.tencent.devops.common.event.dispatcher.pipeline.PipelineEventDispatcher import com.tencent.devops.common.pipeline.enums.ChannelCode +import com.tencent.devops.common.pipeline.enums.VersionStatus import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.api.service.ServicePipelineResource import com.tencent.devops.process.audit.service.AuditService @@ -97,8 +98,7 @@ class PipelineSettingFacadeService @Autowired constructor( checkPermission: Boolean = true, updateLastModifyUser: Boolean? = true, dispatchPipelineUpdateEvent: Boolean = true, - updateLabels: Boolean = true, - saveDraft: Boolean? = false + updateLabels: Boolean = true ): PipelineSetting { if (checkPermission) { val language = I18nUtil.getLanguage(userId) From c2a9bce7b0825a3e4d5a9f057bdaad4cc3e340ad Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Tue, 29 Aug 2023 16:42:27 +0800 Subject: [PATCH 089/852] =?UTF-8?q?=E3=80=90PAC=E3=80=91feat=EF=BC=9A?= =?UTF-8?q?=E5=BC=80=E5=90=AFPAC=E6=A8=A1=E5=BC=8F=E7=9A=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=BA=93=E6=94=AF=E6=8C=81=E8=87=AA=E5=8A=A8=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E4=BB=A3=E7=A0=81=E5=BA=93YAML=E5=8F=98=E6=9B=B4?= =?UTF-8?q?=E5=88=B0=E8=93=9D=E7=9B=BE=20#8130?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/api/service/ServicePacResource.kt | 69 +++++ .../pojo/pipeline/PipelineYamlRefer.kt | 44 +++ .../pojo/pipeline/PipelineYamlVersion.kt | 50 ++++ .../engine/dao/PipelineYamlReferDao.kt | 98 +++++++ .../engine/dao/PipelineYamlVersionDao.kt | 112 +++++++ .../api/service/ServicePacResourceImpl.kt | 48 +++ .../service/PipelineInfoFacadeService.kt | 21 ++ .../process/trigger/PacYamlResourceService.kt | 150 ++++++++++ .../process/trigger/PacYamlTriggerService.kt | 70 +++++ .../process/trigger/actions/BaseAction.kt | 64 ++++ .../trigger/actions/EventActionFactory.kt | 124 ++++++++ .../trigger/actions/GitActionCommon.kt | 124 ++++++++ .../process/trigger/actions/GitBaseAction.kt | 38 +++ .../trigger/actions/data/ActionData.kt | 51 ++++ .../trigger/actions/data/EventCommonData.kt | 50 ++++ .../trigger/actions/data/PacRepoSetting.kt | 67 +++++ .../actions/data/context/PacTriggerContext.kt | 46 +++ .../actions/pacActions/PacEnableAction.kt | 111 +++++++ .../actions/pacActions/data/PacEnableEvent.kt | 42 +++ .../trigger/actions/tgit/TGitActionGit.kt | 38 +++ .../actions/tgit/TGitIssueActionGit.kt | 102 +++++++ .../trigger/actions/tgit/TGitNoteActionGit.kt | 127 ++++++++ .../trigger/actions/tgit/TGitPushActionGit.kt | 123 ++++++++ .../actions/tgit/TGitReviewActionGit.kt | 127 ++++++++ .../actions/tgit/TGitTagPushActionGit.kt | 95 ++++++ .../process/trigger/common/Constansts.kt | 8 + .../trigger/common/exception/ErrorCodeEnum.kt | 145 ++++++++++ .../trigger/git/pojo/ApiRequestRetryInfo.kt | 40 +++ .../trigger/git/pojo/PacGitChangeFileInfo.kt | 46 +++ .../process/trigger/git/pojo/PacGitCred.kt | 33 +++ .../trigger/git/pojo/PacGitFileInfo.kt | 12 + .../trigger/git/pojo/PacGitMrChangeInfo.kt | 9 + .../process/trigger/git/pojo/PacGitMrInfo.kt | 9 + .../trigger/git/pojo/PacGitProjectInfo.kt | 72 +++++ .../trigger/git/pojo/PacGitTreeFileInfo.kt | 17 ++ .../git/pojo/tgit/TGitChangeFileInfo.kt | 54 ++++ .../process/trigger/git/pojo/tgit/TGitCred.kt | 42 +++ .../trigger/git/pojo/tgit/TGitFileInfo.kt | 36 +++ .../trigger/git/pojo/tgit/TGitMrChangeInfo.kt | 34 +++ .../trigger/git/pojo/tgit/TGitMrInfo.kt | 45 +++ .../trigger/git/pojo/tgit/TGitProjectInfo.kt | 63 ++++ .../trigger/git/pojo/tgit/TGitTreeFileInfo.kt | 43 +++ .../process/trigger/git/service/PacApiUtil.kt | 77 +++++ .../trigger/git/service/PacGitApiService.kt | 124 ++++++++ .../trigger/git/service/TGitApiService.kt | 273 ++++++++++++++++++ .../process/trigger/pojo/PacTriggerLock.kt | 43 +++ .../process/trigger/pojo/YamlContent.kt | 39 +++ .../process/trigger/pojo/YamlPathListEntry.kt | 46 +++ 48 files changed, 3301 insertions(+) create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePacResource.kt create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineYamlRefer.kt create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineYamlVersion.kt create mode 100644 src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineYamlReferDao.kt create mode 100644 src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineYamlVersionDao.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePacResourceImpl.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/PacYamlResourceService.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/PacYamlTriggerService.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/BaseAction.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/EventActionFactory.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/GitActionCommon.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/GitBaseAction.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/ActionData.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/EventCommonData.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/PacRepoSetting.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/context/PacTriggerContext.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/pacActions/PacEnableAction.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/pacActions/data/PacEnableEvent.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitActionGit.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitIssueActionGit.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitNoteActionGit.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitPushActionGit.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitReviewActionGit.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitTagPushActionGit.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/common/Constansts.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/common/exception/ErrorCodeEnum.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/ApiRequestRetryInfo.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitChangeFileInfo.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitCred.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitFileInfo.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitMrChangeInfo.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitMrInfo.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitProjectInfo.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitTreeFileInfo.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitChangeFileInfo.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitCred.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitFileInfo.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitMrChangeInfo.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitMrInfo.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitProjectInfo.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitTreeFileInfo.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/service/PacApiUtil.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/service/PacGitApiService.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/service/TGitApiService.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/pojo/PacTriggerLock.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/pojo/YamlContent.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/pojo/YamlPathListEntry.kt diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePacResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePacResource.kt new file mode 100644 index 00000000000..178021fcf11 --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePacResource.kt @@ -0,0 +1,69 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package com.tencent.devops.process.api.service + +import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID +import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE +import com.tencent.devops.common.api.enums.ScmType +import io.swagger.annotations.Api +import io.swagger.annotations.ApiOperation +import io.swagger.annotations.ApiParam +import javax.ws.rs.Consumes +import javax.ws.rs.HeaderParam +import javax.ws.rs.POST +import javax.ws.rs.Path +import javax.ws.rs.PathParam +import javax.ws.rs.Produces +import javax.ws.rs.QueryParam +import javax.ws.rs.core.MediaType + +@Api(tags = ["SERVICE_PAC"], description = "服务-pac资源") +@Path("/service/pac/") +@Produces(MediaType.APPLICATION_JSON) +@Consumes(MediaType.APPLICATION_JSON) +interface ServicePacResource { + + @ApiOperation("开启PAC") + @POST + @Path("/{projectId}/{repoHashId}/enable") + fun enable( + @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) + @HeaderParam(AUTH_HEADER_USER_ID) + userId: String, + @ApiParam("项目ID", required = true) + @PathParam("projectId") + projectId: String, + @ApiParam("代码库hashId", required = true) + @PathParam("repoHashId") + repoHashId: String, + @ApiParam("代码库类型", required = true) + @QueryParam("scmType") + scmType: ScmType + ) +} diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineYamlRefer.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineYamlRefer.kt new file mode 100644 index 00000000000..b4a34899db0 --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineYamlRefer.kt @@ -0,0 +1,44 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package com.tencent.devops.process.pojo.pipeline + +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty + +@ApiModel("流水线yml关联") +data class PipelineYamlRefer( + @ApiModelProperty("项目ID") + val projectId: String, + @ApiModelProperty("代码库ID") + val repoHashId: String, + @ApiModelProperty("ci文件路径") + val filePath: String, + @ApiModelProperty("流水线ID") + val pipelineId: String +) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineYamlVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineYamlVersion.kt new file mode 100644 index 00000000000..7a5e4f2319b --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/pipeline/PipelineYamlVersion.kt @@ -0,0 +1,50 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package com.tencent.devops.process.pojo.pipeline + +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty + +@ApiModel("流水线yml版本") +data class PipelineYamlVersion( + @ApiModelProperty("项目ID") + val projectId: String, + @ApiModelProperty("代码库ID") + val repoHashId: String, + @ApiModelProperty("ci文件路径") + val filePath: String, + @ApiModelProperty("ci文件blob_id") + val blobId: String, + @ApiModelProperty("流水线ID") + val pipelineId: String, + @ApiModelProperty("流水线版本") + val version: Int, + @ApiModelProperty("流水线版本名称") + val versionName: String +) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineYamlReferDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineYamlReferDao.kt new file mode 100644 index 00000000000..4858452e42b --- /dev/null +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineYamlReferDao.kt @@ -0,0 +1,98 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package com.tencent.devops.process.engine.dao + +import com.tencent.devops.model.process.tables.TPipelineYamlRefer +import com.tencent.devops.model.process.tables.records.TPipelineYamlReferRecord +import com.tencent.devops.process.pojo.pipeline.PipelineYamlRefer +import org.jooq.DSLContext +import org.springframework.stereotype.Repository +import java.time.LocalDateTime + +/** + * 流水线与代码库yml文件关联表 + */ +@Repository +class PipelineYamlReferDao { + + fun save( + dslContext: DSLContext, + projectId: String, + repoHashId: String, + filePath: String, + pipelineId: String + ) { + val now = LocalDateTime.now() + with(TPipelineYamlRefer.T_PIPELINE_YAML_REFER) { + dslContext.insertInto( + this, + PROJECT_ID, + REPO_HASH_ID, + FILE_PATH, + PIPELINE_ID, + CREATE_TIME, + UPDATE_TIME + ).values( + projectId, + repoHashId, + filePath, + pipelineId, + now, + now + ) + } + } + + fun get( + dslContext: DSLContext, + projectId: String, + repoHashId: String, + filePath: String + ): PipelineYamlRefer? { + with(TPipelineYamlRefer.T_PIPELINE_YAML_REFER) { + val record = dslContext.selectFrom(this) + .where(PROJECT_ID.eq(projectId)) + .and(REPO_HASH_ID.eq(repoHashId)) + .and(FILE_PATH.eq(filePath)) + .fetchOne() + return record?.let { convert(it) } + } + } + + fun convert(record: TPipelineYamlReferRecord): PipelineYamlRefer { + return with(record) { + PipelineYamlRefer( + projectId = projectId, + repoHashId = repoHashId, + filePath = filePath, + pipelineId = pipelineId + ) + } + } +} diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineYamlVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineYamlVersionDao.kt new file mode 100644 index 00000000000..cf4c1aaf99d --- /dev/null +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineYamlVersionDao.kt @@ -0,0 +1,112 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package com.tencent.devops.process.engine.dao + +import com.tencent.devops.model.process.tables.TPipelineYamlVersion +import com.tencent.devops.model.process.tables.records.TPipelineYamlVersionRecord +import com.tencent.devops.process.pojo.pipeline.PipelineYamlVersion +import org.jooq.DSLContext +import org.springframework.stereotype.Repository +import java.time.LocalDateTime + +/** + * 流水线与代码库yml文件关联表 + */ +@Repository +class PipelineYamlVersionDao { + + fun save( + dslContext: DSLContext, + projectId: String, + repoHashId: String, + filePath: String, + blobId: String, + pipelineId: String, + version: Int, + versionName: String + ) { + val now = LocalDateTime.now() + with(TPipelineYamlVersion.T_PIPELINE_YAML_VERSION) { + dslContext.insertInto( + this, + PROJECT_ID, + REPO_HASH_ID, + FILE_PATH, + BLOB_ID, + PIPELINE_ID, + VERSION, + VERSION_NAME, + CREATE_TIME, + UPDATE_TIME + ).values( + projectId, + repoHashId, + filePath, + blobId, + pipelineId, + version, + versionName, + now, + now + ) + } + } + + fun get( + dslContext: DSLContext, + projectId: String, + repoHashId: String, + filePath: String, + blobId: String + ): PipelineYamlVersion? { + with(TPipelineYamlVersion.T_PIPELINE_YAML_VERSION) { + val record = dslContext.selectFrom(this) + .where(PROJECT_ID.eq(projectId)) + .and(REPO_HASH_ID.eq(repoHashId)) + .and(FILE_PATH.eq(filePath)) + .and(BLOB_ID.eq(blobId)) + .fetchOne() + return record?.let { convert(it) } + } + } + + fun convert(record: TPipelineYamlVersionRecord): PipelineYamlVersion { + return with(record) { + PipelineYamlVersion( + projectId = projectId, + repoHashId = repoHashId, + filePath = filePath, + blobId = blobId, + pipelineId = pipelineId, + version = version, + versionName = versionName + ) + } + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePacResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePacResourceImpl.kt new file mode 100644 index 00000000000..ef1f7173119 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePacResourceImpl.kt @@ -0,0 +1,48 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package com.tencent.devops.process.api.service + +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.common.web.RestResource +import com.tencent.devops.process.trigger.PacYamlTriggerService +import org.springframework.beans.factory.annotation.Autowired + +@RestResource +class ServicePacResourceImpl @Autowired constructor( + private val pacYamlTriggerService: PacYamlTriggerService +) : ServicePacResource { + override fun enable(userId: String, projectId: String, repoHashId: String, scmType: ScmType) { + pacYamlTriggerService.enablePac( + userId = userId, + projectId = projectId, + repoHashId = repoHashId, + scmType = scmType + ) + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index 1d11678a6e9..5d8c81c9281 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -472,6 +472,27 @@ class PipelineInfoFacadeService @Autowired constructor( } } + fun createYamlPipeline( + userId: String, + projectId: String, + yml: String, + defaultBranch: Boolean + ): DeployPipelineResult { + // TODO 待补充 + return DeployPipelineResult(pipelineId = "p-001", pipelineName = "yml-001-pipeline", version = 1) + } + + fun updateYamlPipeline( + userId: String, + projectId: String, + pipelineId: String, + yml: String, + defaultBranch: Boolean + ): DeployPipelineResult { + // TODO 待补充 + return DeployPipelineResult(pipelineId = "p-001", pipelineName = "yml-001-pipeline", version = 1) + } + /** * 还原已经删除的流水线 */ diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/PacYamlResourceService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/PacYamlResourceService.kt new file mode 100644 index 00000000000..2cc019cba30 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/PacYamlResourceService.kt @@ -0,0 +1,150 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package com.tencent.devops.process.trigger + +import com.tencent.devops.common.redis.RedisOperation +import com.tencent.devops.process.engine.dao.PipelineYamlReferDao +import com.tencent.devops.process.engine.dao.PipelineYamlVersionDao +import com.tencent.devops.process.service.PipelineInfoFacadeService +import com.tencent.devops.process.trigger.actions.BaseAction +import com.tencent.devops.process.trigger.pojo.CheckType +import com.tencent.devops.process.trigger.pojo.PacTriggerLock +import com.tencent.devops.process.trigger.pojo.YamlPathListEntry +import org.jooq.DSLContext +import org.jooq.impl.DSL +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Service + +@Service +class PacYamlResourceService @Autowired constructor( + private val dslContext: DSLContext, + private val redisOperation: RedisOperation, + private val pipelineYamlReferDao: PipelineYamlReferDao, + private val pipelineYamlVersionDao: PipelineYamlVersionDao, + private val pipelineInfoFacadeService: PipelineInfoFacadeService +) { + + fun syncYamlPipeline( + projectId: String, + action: BaseAction + ) { + action.getYamlPathList().filter { it.checkType == CheckType.NEED_CHECK }.forEach { entry -> + PacTriggerLock( + redisOperation = redisOperation, + projectId = projectId, + repoHashId = action.data.setting.repoHashId, + filePath = entry.yamlPath + ).use { + it.lock() + val pipelineYamlRefer = pipelineYamlReferDao.get( + dslContext = dslContext, + projectId = projectId, + repoHashId = action.data.setting.repoHashId, + filePath = entry.yamlPath, + ) + if (pipelineYamlRefer == null) { + createYamlPipeline( + projectId = projectId, + action = action, + entry = entry + ) + } else { + updateYamlPipeline( + projectId = projectId, + pipelineId = pipelineYamlRefer.pipelineId, + action = action, + entry = entry + ) + } + } + } + } + + fun createYamlPipeline( + projectId: String, + action: BaseAction, + entry: YamlPathListEntry + ) { + val yamlContent = action.getYamlContent(entry.yamlPath) + val deployPipelineResult = pipelineInfoFacadeService.createYamlPipeline( + userId = action.data.setting.enableUser, + projectId = projectId, + yml = yamlContent.content, + defaultBranch = true + ) + dslContext.transaction { configuration -> + val transactionContext = DSL.using(configuration) + pipelineYamlReferDao.save( + dslContext = transactionContext, + projectId = projectId, + repoHashId = action.data.setting.repoHashId, + filePath = entry.yamlPath, + pipelineId = deployPipelineResult.pipelineId + ) + pipelineYamlVersionDao.save( + dslContext = transactionContext, + projectId = projectId, + repoHashId = action.data.setting.repoHashId, + filePath = entry.yamlPath, + blobId = entry.blobId!!, + pipelineId = deployPipelineResult.pipelineId, + version = deployPipelineResult.version, + // TODO 需要改成具体的版本名称 + versionName = "p.1.1" + ) + } + } + + fun updateYamlPipeline( + projectId: String, + pipelineId: String, + action: BaseAction, + entry: YamlPathListEntry + ) { + val yamlContent = action.getYamlContent(entry.yamlPath) + val deployPipelineResult = pipelineInfoFacadeService.updateYamlPipeline( + userId = action.data.setting.enableUser, + projectId = projectId, + pipelineId = pipelineId, + yml = yamlContent.content, + defaultBranch = true + ) + pipelineYamlVersionDao.save( + dslContext = dslContext, + projectId = projectId, + repoHashId = action.data.setting.repoHashId, + filePath = entry.yamlPath, + blobId = entry.blobId!!, + pipelineId = deployPipelineResult.pipelineId, + version = deployPipelineResult.version, + // TODO 需要改成具体的版本名称 + versionName = "p.1.1" + ) + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/PacYamlTriggerService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/PacYamlTriggerService.kt new file mode 100644 index 00000000000..0c46aba84b6 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/PacYamlTriggerService.kt @@ -0,0 +1,70 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package com.tencent.devops.process.trigger + +import com.tencent.devops.common.api.enums.RepositoryType +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.common.client.Client +import com.tencent.devops.process.trigger.actions.EventActionFactory +import com.tencent.devops.process.trigger.actions.data.PacRepoSetting +import com.tencent.devops.process.trigger.actions.pacActions.data.PacEnableEvent +import com.tencent.devops.repository.api.ServiceRepositoryResource +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Service + +@Service +class PacYamlTriggerService @Autowired constructor( + private val client: Client, + private val eventActionFactory: EventActionFactory, + private val pacYamlResourceService: PacYamlResourceService +) { + + companion object { + private val logger = LoggerFactory.getLogger(PacYamlTriggerService::class.java) + } + + fun enablePac(userId: String, projectId: String, repoHashId: String, scmType: ScmType) { + logger.info("enable pac|$userId|$projectId|$repoHashId|$scmType") + val repository = client.get(ServiceRepositoryResource::class).get( + projectId = projectId, + repositoryId = repoHashId, + repositoryType = RepositoryType.ID + ).data ?: return + val setting = PacRepoSetting(repository = repository) + val event = PacEnableEvent( + userId = userId, + projectId = projectId, + repoHashId = repoHashId, + scmType = scmType + ) + val action = eventActionFactory.loadEnableEvent(setting = setting, event = event) + pacYamlResourceService.syncYamlPipeline(projectId = projectId, action = action) + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/BaseAction.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/BaseAction.kt new file mode 100644 index 00000000000..13fdaa5f8f2 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/BaseAction.kt @@ -0,0 +1,64 @@ +package com.tencent.devops.process.trigger.actions + +import com.tencent.devops.process.trigger.actions.data.ActionData +import com.tencent.devops.process.trigger.git.pojo.PacGitCred +import com.tencent.devops.process.trigger.git.service.PacGitApiService +import com.tencent.devops.process.trigger.pojo.YamlContent +import com.tencent.devops.process.trigger.pojo.YamlPathListEntry + + +/** + * 所有action的父类,只提供抽象方法 + */ +interface BaseAction { + // 当前事件源相关的数据 + var data: ActionData + + // 当前事件源绑定的git api + val api: PacGitApiService + + // 方便日志打印 + fun format() = "${this::class.qualifiedName}|${data.format()}|${api::class.qualifiedName}" + + /** + * 填充一些初始化数据 + * 因为可能存在需要上下文参数的情况,所以和load分开 + */ + fun init(): BaseAction? + + /** + * 初始化一些用于缓存的数据,主要是为了减少接口调用 + */ + fun initCacheData() = Unit + + /** + * 由于API接口所需参数不同,所以区分 + * TGIT -> 接口需要 git project id + * Github -> 接口需要 git project name + */ + fun getGitProjectIdOrName(gitProjectId: String? = null): String + + /** + * 获取调用当前git平台信息的cred,可能会请求Git api,所以放到action + * @param personToken yaml语法中会直接填写的accessToken或tickId转换的token + */ + fun getGitCred( + personToken: String? = null + ): PacGitCred + + /** + * 获取流水线yaml文件列表 + */ + fun getYamlPathList(): List + + /** + * 获取yaml文件具体内容 + * @param fileName 文件名称 + */ + fun getYamlContent(fileName: String): YamlContent + + /** + * 获取本次触发变更的文件列表 + */ + fun getChangeSet(): Set? +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/EventActionFactory.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/EventActionFactory.kt new file mode 100644 index 00000000000..82435498ca7 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/EventActionFactory.kt @@ -0,0 +1,124 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.actions + +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.common.webhook.pojo.code.CodeWebhookEvent +import com.tencent.devops.common.webhook.pojo.code.git.GitIssueEvent +import com.tencent.devops.common.webhook.pojo.code.git.GitNoteEvent +import com.tencent.devops.common.webhook.pojo.code.git.GitPushEvent +import com.tencent.devops.common.webhook.pojo.code.git.GitReviewEvent +import com.tencent.devops.common.webhook.pojo.code.git.GitTagPushEvent +import com.tencent.devops.process.trigger.actions.data.ActionData +import com.tencent.devops.process.trigger.actions.data.PacRepoSetting +import com.tencent.devops.process.trigger.actions.data.context.PacTriggerContext +import com.tencent.devops.process.trigger.actions.pacActions.PacEnableAction +import com.tencent.devops.process.trigger.actions.pacActions.data.PacEnableEvent +import com.tencent.devops.process.trigger.actions.tgit.TGitIssueActionGit +import com.tencent.devops.process.trigger.actions.tgit.TGitNoteActionGit +import com.tencent.devops.process.trigger.actions.tgit.TGitPushActionGit +import com.tencent.devops.process.trigger.actions.tgit.TGitReviewActionGit +import com.tencent.devops.process.trigger.actions.tgit.TGitTagPushActionGit +import com.tencent.devops.process.trigger.git.service.TGitApiService +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Service + +@Service +class EventActionFactory @Autowired constructor( + private val tGitApiService: TGitApiService +) { + + companion object { + private val logger = LoggerFactory.getLogger(EventActionFactory::class.java) + } + + fun load(event: CodeWebhookEvent): BaseAction? { + val action = loadEvent(event) ?: return null + + return action.init() + } + + @Suppress("ComplexMethod") + private fun loadEvent(event: CodeWebhookEvent): BaseAction? { + // 先根据git事件分为得到初始化的git action + val gitAction = when (event) { + is GitPushEvent -> { + val tGitPushAction = TGitPushActionGit( + apiService = tGitApiService + ) + tGitPushAction + } + is GitTagPushEvent -> { + val tGitTagPushAction = TGitTagPushActionGit( + apiService = tGitApiService, + ) + tGitTagPushAction + } + is GitIssueEvent -> { + val tGitIssueAction = TGitIssueActionGit( + apiService = tGitApiService + ) + tGitIssueAction + } + is GitReviewEvent -> { + val tGitReviewAction = TGitReviewActionGit( + apiService = tGitApiService + ) + tGitReviewAction + } + is GitNoteEvent -> { + val tGitNoteAction = TGitNoteActionGit( + apiService = tGitApiService + ) + tGitNoteAction + } + else -> { + return null + } + } + gitAction.data = ActionData(event, PacTriggerContext()) + + return gitAction + } + + fun loadEnableEvent( + setting: PacRepoSetting, + event: PacEnableEvent + ): PacEnableAction { + val pacEnableAction = PacEnableAction() + pacEnableAction.data = ActionData(event, PacTriggerContext()) + pacEnableAction.api = when (event.scmType) { + ScmType.CODE_GIT -> tGitApiService + else -> TODO("对接其他代码库平台时需要补充") + } + pacEnableAction.data.setting = setting + pacEnableAction.init() + return pacEnableAction + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/GitActionCommon.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/GitActionCommon.kt new file mode 100644 index 00000000000..7a1c11f55d1 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/GitActionCommon.kt @@ -0,0 +1,124 @@ +package com.tencent.devops.process.trigger.actions + +import com.tencent.devops.process.trigger.common.Constansts +import com.tencent.devops.process.trigger.git.pojo.ApiRequestRetryInfo +import com.tencent.devops.process.trigger.git.pojo.PacGitCred +import com.tencent.devops.process.trigger.git.pojo.PacGitTreeFileInfo +import com.tencent.devops.process.trigger.git.pojo.StreamGitTreeFileInfoType +import org.joda.time.DateTime +import org.slf4j.LoggerFactory +import java.io.File +import java.text.SimpleDateFormat +import java.util.Date + +object GitActionCommon { + + private val logger = LoggerFactory.getLogger(GitActionCommon::class.java) + + /** + * 拿到所有的ci文件的文件列表 + * @return file,blobId + */ + fun getYamlPathList( + action: BaseAction, + gitProjectId: String, + ref: String?, + cred: PacGitCred? = null + ): MutableList> { + // 获取指定目录下所有yml文件 + val yamlPathList = getCIYamlList(action, gitProjectId, ref, cred).toMutableList() + + // 兼容旧的根目录yml文件 + val (isCIYamlExist, blobId) = isCIYamlExist(action, gitProjectId, ref, cred) + + if (isCIYamlExist) { + yamlPathList.add(Pair(Constansts.ciFileName, blobId)) + } + return yamlPathList + } + + /** + * @return name,blobId + */ + private fun getCIYamlList( + action: BaseAction, + gitProjectId: String, + ref: String?, + cred: PacGitCred? + ): List> { + val ciFileList = action.api.getFileTree( + gitProjectId = gitProjectId, + cred = cred ?: action.getGitCred(), + path = Constansts.ciFileDirectoryName, + ref = ref?.let { getTriggerBranch(it) }, + recursive = true, + retry = ApiRequestRetryInfo(true) + ).filter { (it.type == "blob") && checkStreamPipelineFile(it.name) && !checkStreamTemplateFile(it.name) } + return ciFileList.map { + Pair(Constansts.ciFileDirectoryName + File.separator + it.name, getBlobId(it)) + }.toList() + } + + private fun checkStreamPipelineFile(fileName: String): Boolean = + ( + fileName.endsWith(Constansts.ciFileExtensionYml) || + fileName.endsWith(Constansts.ciFileExtensionYaml) + ) && + // 加以限制:最多仅限一级子目录 + (fileName.count { it == '/' } <= 1) + + private fun checkStreamTemplateFile(fileName: String): Boolean = fileName.startsWith("templates/") + + fun checkStreamPipelineAndTemplateFile(fullPath: String): Boolean = + if (fullPath.startsWith(Constansts.ciFileDirectoryName)) { + val removePrefix = fullPath.removePrefix(Constansts.ciFileDirectoryName + "/") + checkStreamPipelineFile(removePrefix) || checkStreamTemplateFile(removePrefix) + } else false + + private fun getBlobId(f: PacGitTreeFileInfo?): String? { + return if (f != null && f.type == StreamGitTreeFileInfoType.BLOB.value && !f.id.isNullOrBlank()) { + f.id + } else { + null + } + } + + /** + * @return isExist,blobId + */ + private fun isCIYamlExist( + action: BaseAction, + gitProjectId: String, + ref: String?, + cred: PacGitCred? + ): Pair { + val ciFileList = action.api.getFileTree( + gitProjectId = gitProjectId, + cred = cred ?: action.getGitCred(), + path = "", + ref = ref?.let { getTriggerBranch(it) }, + recursive = false, + retry = ApiRequestRetryInfo(true) + ).filter { it.name == Constansts.ciFileName } + return Pair(ciFileList.isNotEmpty(), getBlobId(ciFileList.ifEmpty { null }?.first())) + } + + fun getTriggerBranch(branch: String): String { + return when { + branch.startsWith("refs/heads/") -> branch.removePrefix("refs/heads/") + branch.startsWith("refs/tags/") -> branch.removePrefix("refs/tags/") + else -> branch + } + } + + fun getCommitTimeStamp(commitTimeStamp: String?): String { + return if (commitTimeStamp.isNullOrBlank()) { + val formatter = SimpleDateFormat("yyyy-MM-dd HH:mm:ss") + formatter.format(Date()) + } else { + val time = DateTime.parse(commitTimeStamp) + val sdf = SimpleDateFormat("yyyy-MM-dd HH:mm:ss") + sdf.format(time.toDate()) + } + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/GitBaseAction.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/GitBaseAction.kt new file mode 100644 index 00000000000..9504c7ecbea --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/GitBaseAction.kt @@ -0,0 +1,38 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.actions + +import com.tencent.devops.common.webhook.pojo.code.CodeWebhookEvent + +/** + * 和Git的一些操作的相关抽象类,方便不同源操作 + */ +interface GitBaseAction : BaseAction { + + fun event(): CodeWebhookEvent +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/ActionData.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/ActionData.kt new file mode 100644 index 00000000000..f56a7edb542 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/ActionData.kt @@ -0,0 +1,51 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.actions.data + +import com.tencent.devops.common.webhook.pojo.code.CodeWebhookEvent +import com.tencent.devops.process.trigger.actions.data.context.PacTriggerContext + +/** + * 保存action需要用到的元数据 + * @param event 各源的事件原文 + */ +@Suppress("MaxLineLength") +data class ActionData( + val event: CodeWebhookEvent, + var context: PacTriggerContext +) { + // 需要根据各事件源的event去拿的通用数据,随event改变可能会不同 + lateinit var eventCommon: EventCommonData + + // pac触发时需要的配置信息 + lateinit var setting: PacRepoSetting + val isSettingInitialized get() = this::setting.isInitialized + + // 方便日志打印 + fun format() = "${event::class.qualifiedName}|$eventCommon|$setting" +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/EventCommonData.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/EventCommonData.kt new file mode 100644 index 00000000000..60685e70a30 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/EventCommonData.kt @@ -0,0 +1,50 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.actions.data + +import com.tencent.devops.common.api.enums.ScmType + +/** + * 需要根据各事件源的event去拿的通用数据,随event改变可能会不同 + * @param gitProjectId Git平台项目唯一标识 + * @param scmType 当前事件 git平台唯一标识 + * @param branch 当前event的触发branch + * @param userId 当前event的触发人 + * @param projectName Git平台项目全称: namespace/name + * @param eventType 当前事件类型 仅在github需要 + * @param sourceGitProjectId mr触发时的源Git库 + */ +data class EventCommonData( + val gitProjectId: String, + val scmType: ScmType?, + val branch: String, + val userId: String, + val projectName: String?, + val eventType: String? = null, + val sourceGitProjectId: String? = null +) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/PacRepoSetting.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/PacRepoSetting.kt new file mode 100644 index 00000000000..67d011e7254 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/PacRepoSetting.kt @@ -0,0 +1,67 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.actions.data + +import com.tencent.devops.repository.pojo.CodeGitRepository +import com.tencent.devops.repository.pojo.CodeGitlabRepository +import com.tencent.devops.repository.pojo.CodeTGitRepository +import com.tencent.devops.repository.pojo.GithubRepository +import com.tencent.devops.repository.pojo.Repository + +/** + * pac绑定的代码库配置信息 + * @param projectId 项目ID + * @param repoHashId 代码库hashId + * @param enableUser 开启pac的用户ID + * @param gitProjectId git项目ID,只有tgit/gitlab/github才有值 + * @param projectName 代码平台项目名: namespace/name + * @param credentialId 代码库绑定的凭证ID + */ +data class PacRepoSetting( + val projectId: String, + val repoHashId: String, + val enableUser: String, + val gitProjectId: Long?, + val projectName: String, + val credentialId: String? +) { + constructor(repository: Repository): this( + projectId = repository.projectId!!, + repoHashId = repository.repoHashId!!, + enableUser = repository.userName, + gitProjectId = when (repository) { + is CodeGitRepository -> repository.gitProjectId + is CodeTGitRepository -> repository.gitProjectId + is GithubRepository -> repository.gitProjectId + is CodeGitlabRepository -> repository.gitProjectId + else -> null + }, + projectName = repository.projectName, + credentialId = repository.credentialId + ) +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/context/PacTriggerContext.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/context/PacTriggerContext.kt new file mode 100644 index 00000000000..c7476a5bd8a --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/context/PacTriggerContext.kt @@ -0,0 +1,46 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.actions.data.context + +import com.tencent.devops.scm.pojo.GitMrInfo +import com.tencent.devops.scm.pojo.GitMrReviewInfo + +/** + * pac触发过程中需要用到的上下文数据 + * 注:上下文对象涉及消息传递时,需要确保不是确定对象 + * + * @param hookRequestId webhook触发的requestId,对应代码库T_REPOSITORY_WEBHOOK_REQUEST的requestId + * @param eventId 触发事件ID,对应T_PIPELINE_TRIGGER_EVENT的eventId + */ +data class PacTriggerContext( + var hookRequestId: Long? = null, + var eventId: Long? = null, + // 缓存 + var gitMrReviewInfo: GitMrReviewInfo? = null, + var gitMrInfo: GitMrInfo? = null +) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/pacActions/PacEnableAction.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/pacActions/PacEnableAction.kt new file mode 100644 index 00000000000..08e5062edb2 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/pacActions/PacEnableAction.kt @@ -0,0 +1,111 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package com.tencent.devops.process.trigger.actions.pacActions + +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.process.trigger.actions.BaseAction +import com.tencent.devops.process.trigger.actions.GitActionCommon +import com.tencent.devops.process.trigger.actions.data.ActionData +import com.tencent.devops.process.trigger.actions.data.EventCommonData +import com.tencent.devops.process.trigger.actions.pacActions.data.PacEnableEvent +import com.tencent.devops.process.trigger.git.pojo.ApiRequestRetryInfo +import com.tencent.devops.process.trigger.git.pojo.PacGitCred +import com.tencent.devops.process.trigger.git.pojo.tgit.TGitCred +import com.tencent.devops.process.trigger.git.service.PacGitApiService +import com.tencent.devops.process.trigger.pojo.CheckType +import com.tencent.devops.process.trigger.pojo.YamlContent +import com.tencent.devops.process.trigger.pojo.YamlPathListEntry + +class PacEnableAction : BaseAction { + override lateinit var data: ActionData + fun event() = data.event as PacEnableEvent + + override lateinit var api: PacGitApiService + + override fun init(): BaseAction? { + return initCommonData() + } + + private fun initCommonData(): PacEnableAction { + val event = event() + val gitProjectId = getGitProjectIdOrName() + val defaultBranch = api.getGitProjectInfo( + cred = this.getGitCred(), + gitProjectId = gitProjectId, + retry = ApiRequestRetryInfo(true) + )!!.defaultBranch!! + this.data.eventCommon = EventCommonData( + gitProjectId = gitProjectId, + userId = event.userId, + branch = defaultBranch, + projectName = data.setting.projectName, + scmType = event.scmType + ) + return this + } + + override fun getGitProjectIdOrName(gitProjectId: String?) = gitProjectId ?: data.setting.projectName + + override fun getGitCred(personToken: String?): PacGitCred { + val event = event() + return when (event.scmType) { + ScmType.CODE_GIT, ScmType.CODE_TGIT -> TGitCred( + userId = event().userId, + accessToken = personToken, + useAccessToken = personToken == null + ) + else -> TODO("对接其他代码库平台时需要补充") + } + } + + override fun getYamlPathList(): List { + return GitActionCommon.getYamlPathList( + action = this, + gitProjectId = this.getGitProjectIdOrName(), + ref = this.data.eventCommon.branch + ).map { (name, blobId) -> + YamlPathListEntry(name, CheckType.NEED_CHECK, this.data.eventCommon.branch, blobId) + } + } + + override fun getYamlContent(fileName: String): YamlContent { + return YamlContent( + ref = data.eventCommon.branch, + content = api.getFileContent( + cred = this.getGitCred(), + gitProjectId = getGitProjectIdOrName(), + fileName = fileName, + ref = data.eventCommon.branch, + retry = ApiRequestRetryInfo(true) + ) + ) + } + + override fun getChangeSet(): Set? = null +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/pacActions/data/PacEnableEvent.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/pacActions/data/PacEnableEvent.kt new file mode 100644 index 00000000000..1b5e6b2e360 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/pacActions/data/PacEnableEvent.kt @@ -0,0 +1,42 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package com.tencent.devops.process.trigger.actions.pacActions.data + +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.common.webhook.pojo.code.CodeWebhookEvent + +/** + * pac开启事件 + */ +data class PacEnableEvent( + val userId: String, + val projectId: String, + val repoHashId: String, + val scmType: ScmType +) : CodeWebhookEvent diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitActionGit.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitActionGit.kt new file mode 100644 index 00000000000..2126b60cd07 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitActionGit.kt @@ -0,0 +1,38 @@ +package com.tencent.devops.process.trigger.actions.tgit + +import com.tencent.devops.process.trigger.actions.GitBaseAction +import com.tencent.devops.process.trigger.actions.data.ActionData +import com.tencent.devops.process.trigger.git.pojo.tgit.TGitCred +import com.tencent.devops.process.trigger.git.service.TGitApiService + +/** + * 对于stream 平台级功能的具体实现,不需要下放到具体的event + * 对于只有一两个事件实现的,也可在平台级实现一个通用的,一两个再自己重写 + */ +abstract class TGitActionGit( + override val api: TGitApiService +) : GitBaseAction { + override lateinit var data: ActionData + + /** + * 提供拿取gitProjectId的公共方法 + * 因为会存在跨库触发导致的event的gitProjectId和触发的不一致的问题 + * 所以会优先拿取pipeline的gitProjectId + */ + override fun getGitProjectIdOrName(gitProjectId: String?) = + gitProjectId ?: data.eventCommon.gitProjectId + + override fun getGitCred(personToken: String?): TGitCred { + if (personToken != null) { + return TGitCred( + userId = null, + accessToken = personToken, + useAccessToken = false + ) + } + return TGitCred(data.setting.enableUser) + } + + override fun getChangeSet(): Set? = null + +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitIssueActionGit.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitIssueActionGit.kt new file mode 100644 index 00000000000..c6d6d77fc55 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitIssueActionGit.kt @@ -0,0 +1,102 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.actions.tgit + +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.common.webhook.pojo.code.git.GitIssueEvent +import com.tencent.devops.process.trigger.actions.BaseAction +import com.tencent.devops.process.trigger.actions.GitActionCommon +import com.tencent.devops.process.trigger.actions.GitBaseAction +import com.tencent.devops.process.trigger.actions.data.EventCommonData +import com.tencent.devops.process.trigger.git.pojo.ApiRequestRetryInfo +import com.tencent.devops.process.trigger.git.service.TGitApiService +import com.tencent.devops.process.trigger.pojo.CheckType +import com.tencent.devops.process.trigger.pojo.YamlContent +import com.tencent.devops.process.trigger.pojo.YamlPathListEntry +import com.tencent.devops.scm.utils.code.git.GitUtils +import org.slf4j.LoggerFactory + +class TGitIssueActionGit( + private val apiService: TGitApiService, +) : TGitActionGit(apiService), GitBaseAction { + + companion object { + private val logger = LoggerFactory.getLogger(TGitIssueActionGit::class.java) + } + + override fun event() = data.event as GitIssueEvent + + override val api: TGitApiService + get() = apiService + + override fun init(): BaseAction? { + return initCommonData() + } + + private fun initCommonData(): GitBaseAction { + val event = event() + val gitProjectId = event.objectAttributes.projectId + + val defaultBranch = apiService.getGitProjectInfo( + cred = this.getGitCred(), + gitProjectId = gitProjectId.toString(), + retry = ApiRequestRetryInfo(true) + )!!.defaultBranch!! + this.data.eventCommon = EventCommonData( + gitProjectId = event.objectAttributes.projectId.toString(), + scmType = ScmType.CODE_GIT, + branch = defaultBranch, + userId = event.user.username, + projectName = GitUtils.getProjectName(event.repository.homepage) + ) + return this + } + + override fun getYamlPathList(): List { + return GitActionCommon.getYamlPathList( + action = this, + gitProjectId = this.getGitProjectIdOrName(), + ref = this.data.eventCommon.branch + ).map { (name, blobId) -> + YamlPathListEntry(name, CheckType.NO_NEED_CHECK, this.data.eventCommon.branch, blobId) + } + } + + override fun getYamlContent(fileName: String): YamlContent { + return YamlContent( + ref = data.eventCommon.branch, + content = api.getFileContent( + cred = this.getGitCred(), + gitProjectId = getGitProjectIdOrName(), + fileName = fileName, + ref = data.eventCommon.branch, + retry = ApiRequestRetryInfo(true) + ) + ) + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitNoteActionGit.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitNoteActionGit.kt new file mode 100644 index 00000000000..9334800cf46 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitNoteActionGit.kt @@ -0,0 +1,127 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.actions.tgit + +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.common.webhook.pojo.code.git.GitNoteEvent +import com.tencent.devops.process.trigger.actions.BaseAction +import com.tencent.devops.process.trigger.actions.GitActionCommon +import com.tencent.devops.process.trigger.actions.GitBaseAction +import com.tencent.devops.process.trigger.actions.data.EventCommonData +import com.tencent.devops.process.trigger.git.pojo.ApiRequestRetryInfo +import com.tencent.devops.process.trigger.git.service.TGitApiService +import com.tencent.devops.process.trigger.pojo.CheckType +import com.tencent.devops.process.trigger.pojo.YamlContent +import com.tencent.devops.process.trigger.pojo.YamlPathListEntry +import com.tencent.devops.scm.utils.code.git.GitUtils +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Service + +@Service +class TGitNoteActionGit @Autowired constructor( + private val apiService: TGitApiService, +) : TGitActionGit(apiService), GitBaseAction { + + companion object { + private val logger = LoggerFactory.getLogger(TGitNoteActionGit::class.java) + } + + override fun event() = data.event as GitNoteEvent + + override val api: TGitApiService + get() = apiService + + override fun init(): BaseAction? { + return initCommonData() + } + + private fun initCommonData(): GitBaseAction { + val event = event() + val gitProjectId = event.projectId + + val defaultBranch = apiService.getGitProjectInfo( + cred = this.getGitCred(), + gitProjectId = gitProjectId.toString(), + retry = ApiRequestRetryInfo(true) + )!!.defaultBranch!! + this.data.eventCommon = EventCommonData( + gitProjectId = event.objectAttributes.projectId.toString(), + scmType = ScmType.CODE_GIT, + branch = defaultBranch, + userId = event.user.username, + projectName = GitUtils.getProjectName(event.repository.homepage) + ) + return this + } + + override fun initCacheData() { + val event = event() + if (data.isSettingInitialized && event.mergeRequest != null) { + try { + data.context.gitMrInfo = apiService.getMrInfo( + cred = getGitCred(), + gitProjectId = data.eventCommon.gitProjectId, + mrId = event.mergeRequest!!.id.toString(), + retry = ApiRequestRetryInfo(true) + )?.baseInfo + data.context.gitMrReviewInfo = apiService.getMrReview( + cred = getGitCred(), + gitProjectId = event.mergeRequest!!.target_project_id.toString(), + mrId = event.mergeRequest!!.id.toString(), + retry = ApiRequestRetryInfo(true) + ) + } catch (ignore: Throwable) { + logger.warn("TGit note action cache mrInfo/mrReviewInfo error", ignore) + } + } + } + + override fun getYamlPathList(): List { + return GitActionCommon.getYamlPathList( + action = this, + gitProjectId = this.getGitProjectIdOrName(), + ref = this.data.eventCommon.branch + ).map { (name, blobId) -> + YamlPathListEntry(name, CheckType.NO_NEED_CHECK, this.data.eventCommon.branch, blobId) + } + } + + override fun getYamlContent(fileName: String): YamlContent { + return YamlContent( + ref = data.eventCommon.branch, + content = api.getFileContent( + cred = this.getGitCred(), + gitProjectId = getGitProjectIdOrName(), + fileName = fileName, + ref = data.eventCommon.branch, + retry = ApiRequestRetryInfo(true) + ) + ) + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitPushActionGit.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitPushActionGit.kt new file mode 100644 index 00000000000..8889063e5e5 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitPushActionGit.kt @@ -0,0 +1,123 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.actions.tgit +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.common.webhook.pojo.code.git.GitPushEvent +import com.tencent.devops.process.trigger.actions.BaseAction +import com.tencent.devops.process.trigger.actions.GitActionCommon +import com.tencent.devops.process.trigger.actions.GitBaseAction +import com.tencent.devops.process.trigger.actions.data.EventCommonData +import com.tencent.devops.process.trigger.git.pojo.ApiRequestRetryInfo +import com.tencent.devops.process.trigger.git.service.TGitApiService +import com.tencent.devops.process.trigger.pojo.CheckType +import com.tencent.devops.process.trigger.pojo.YamlContent +import com.tencent.devops.process.trigger.pojo.YamlPathListEntry +import com.tencent.devops.scm.utils.code.git.GitUtils +import org.slf4j.LoggerFactory + +@Suppress("ALL") +class TGitPushActionGit( + private val apiService: TGitApiService, +) : TGitActionGit(apiService), GitBaseAction { + + companion object { + val logger = LoggerFactory.getLogger(TGitPushActionGit::class.java) + } + + override fun event() = data.event as GitPushEvent + + override val api: TGitApiService + get() = apiService + + override fun init(): BaseAction? { + return initCommonData() + } + + private fun initCommonData(): GitBaseAction { + val event = event() + this.data.eventCommon = EventCommonData( + gitProjectId = event.project_id.toString(), + scmType = ScmType.CODE_GIT, + branch = event.ref.removePrefix("refs/heads/"), + userId = event.user_name, + projectName = GitUtils.getProjectName(event.repository.homepage) + ) + return this + } + + + override fun getYamlPathList(): List { + val changeSet = getChangeSet() + return GitActionCommon.getYamlPathList( + action = this, + gitProjectId = this.getGitProjectIdOrName(), + ref = this.data.eventCommon.branch + ).map { (name, blobId) -> + YamlPathListEntry( + yamlPath = name, + checkType = if (changeSet?.contains(name) == true) { + CheckType.NEED_CHECK + } else { + CheckType.NO_NEED_CHECK + }, + ref = this.data.eventCommon.branch, blobId = blobId + ) + } + } + + override fun getYamlContent(fileName: String): YamlContent { + return YamlContent( + ref = data.eventCommon.branch, + content = api.getFileContent( + cred = this.getGitCred(), + gitProjectId = getGitProjectIdOrName(), + fileName = fileName, + ref = data.eventCommon.branch, + retry = ApiRequestRetryInfo(true) + ) + ) + } + + override fun getChangeSet(): Set? { + val changeFileList = mutableSetOf() + event().diffFiles?.forEach { + when { + // 删除文件 + it.deletedFile -> changeFileList.add(it.oldPath) + // 重命名文件 + it.renamedFile -> { + changeFileList.add(it.newPath) + changeFileList.add(it.oldPath) + } + // 修改或添加文件 + else -> changeFileList.add(it.newPath) + } + } + return changeFileList + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitReviewActionGit.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitReviewActionGit.kt new file mode 100644 index 00000000000..b7daa7f0af3 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitReviewActionGit.kt @@ -0,0 +1,127 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.actions.tgit + +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.common.webhook.pojo.code.git.GitReviewEvent +import com.tencent.devops.process.trigger.actions.BaseAction +import com.tencent.devops.process.trigger.actions.GitActionCommon +import com.tencent.devops.process.trigger.actions.GitBaseAction +import com.tencent.devops.process.trigger.actions.data.EventCommonData +import com.tencent.devops.process.trigger.git.pojo.ApiRequestRetryInfo +import com.tencent.devops.process.trigger.git.service.TGitApiService +import com.tencent.devops.process.trigger.pojo.CheckType +import com.tencent.devops.process.trigger.pojo.YamlContent +import com.tencent.devops.process.trigger.pojo.YamlPathListEntry +import com.tencent.devops.scm.utils.code.git.GitUtils +import org.slf4j.LoggerFactory + +class TGitReviewActionGit( + private val apiService: TGitApiService, +) : TGitActionGit(apiService), GitBaseAction { + + companion object { + private val logger = LoggerFactory.getLogger(TGitReviewActionGit::class.java) + } + + override fun event() = data.event as GitReviewEvent + + override val api: TGitApiService + get() = apiService + + override fun init(): BaseAction? { + return initCommonData() + } + + private fun initCommonData(): GitBaseAction { + val event = event() + val gitProjectId = event.projectId + val defaultBranch = apiService.getGitProjectInfo( + cred = this.getGitCred(), + gitProjectId = gitProjectId.toString(), + retry = ApiRequestRetryInfo(true) + )!!.defaultBranch!! + this.data.eventCommon = EventCommonData( + gitProjectId = event.projectId.toString(), + scmType = ScmType.CODE_GIT, + branch = defaultBranch, + userId = if (event.reviewer == null) { + event.author.username + } else { + event.reviewer!!.reviewer.username + }, + projectName = GitUtils.getProjectName(event.repository.homepage) + ) + return this + } + + override fun initCacheData() { + val event = event() + if (data.isSettingInitialized && event.reviewableId != null && event.reviewableType == "merge_request") { + try { + data.context.gitMrInfo = apiService.getMrInfo( + cred = getGitCred(), + gitProjectId = data.eventCommon.gitProjectId, + mrId = event.reviewableId.toString(), + retry = ApiRequestRetryInfo(true) + )?.baseInfo + data.context.gitMrReviewInfo = apiService.getMrReview( + cred = getGitCred(), + gitProjectId = data.eventCommon.gitProjectId, + mrId = event.reviewableId.toString(), + retry = ApiRequestRetryInfo(true) + ) + } catch (ignore: Throwable) { + logger.warn("TGit review action cache mrInfo/mrReviewInfo error", ignore) + } + } + } + + override fun getYamlPathList(): List { + return GitActionCommon.getYamlPathList( + action = this, + gitProjectId = this.getGitProjectIdOrName(), + ref = this.data.eventCommon.branch + ).map { (name, blobId) -> + YamlPathListEntry(name, CheckType.NO_NEED_CHECK, this.data.eventCommon.branch, blobId) + } + } + + override fun getYamlContent(fileName: String): YamlContent { + return YamlContent( + ref = data.eventCommon.branch, + content = api.getFileContent( + cred = this.getGitCred(), + gitProjectId = getGitProjectIdOrName(), + fileName = fileName, + ref = data.eventCommon.branch, + retry = ApiRequestRetryInfo(true) + ) + ) + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitTagPushActionGit.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitTagPushActionGit.kt new file mode 100644 index 00000000000..75c4dd10474 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/tgit/TGitTagPushActionGit.kt @@ -0,0 +1,95 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.actions.tgit + +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.common.webhook.pojo.code.git.GitTagPushEvent +import com.tencent.devops.process.trigger.actions.BaseAction +import com.tencent.devops.process.trigger.actions.GitActionCommon +import com.tencent.devops.process.trigger.actions.GitBaseAction +import com.tencent.devops.process.trigger.actions.data.EventCommonData +import com.tencent.devops.process.trigger.git.pojo.ApiRequestRetryInfo +import com.tencent.devops.process.trigger.git.service.TGitApiService +import com.tencent.devops.process.trigger.pojo.CheckType +import com.tencent.devops.process.trigger.pojo.YamlContent +import com.tencent.devops.process.trigger.pojo.YamlPathListEntry +import com.tencent.devops.scm.utils.code.git.GitUtils +import org.slf4j.LoggerFactory + +class TGitTagPushActionGit( + private val apiService: TGitApiService +) : TGitActionGit(apiService), GitBaseAction { + + companion object { + val logger = LoggerFactory.getLogger(TGitTagPushActionGit::class.java)!! + } + + override fun event() = data.event as GitTagPushEvent + + override val api: TGitApiService + get() = apiService + + override fun init(): BaseAction { + return initCommonData() + } + + private fun initCommonData(): GitBaseAction { + val event = event() + this.data.eventCommon = EventCommonData( + gitProjectId = event.project_id.toString(), + scmType = ScmType.CODE_GIT, + branch = event.ref.removePrefix("refs/tags/"), + userId = event.user_name, + projectName = GitUtils.getProjectName(event.repository.homepage) + ) + return this + } + + override fun getYamlPathList(): List { + return GitActionCommon.getYamlPathList( + action = this, + gitProjectId = this.getGitProjectIdOrName(), + ref = this.data.eventCommon.branch + ).map { (name, blobId) -> + YamlPathListEntry(name, CheckType.NO_NEED_CHECK, this.data.eventCommon.branch, blobId) + } + } + + override fun getYamlContent(fileName: String): YamlContent { + return YamlContent( + ref = data.eventCommon.branch, + content = api.getFileContent( + cred = this.getGitCred(), + gitProjectId = getGitProjectIdOrName(), + fileName = fileName, + ref = data.eventCommon.branch, + retry = ApiRequestRetryInfo(true) + ) + ) + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/common/Constansts.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/common/Constansts.kt new file mode 100644 index 00000000000..2b337d109ec --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/common/Constansts.kt @@ -0,0 +1,8 @@ +package com.tencent.devops.process.trigger.common + +object Constansts { + const val ciFileExtensionYml = ".yml" + const val ciFileExtensionYaml = ".yaml" + const val ciFileName = ".ci.yml" + const val ciFileDirectoryName = ".ci" +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/common/exception/ErrorCodeEnum.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/common/exception/ErrorCodeEnum.kt new file mode 100644 index 00000000000..e0fde77b461 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/common/exception/ErrorCodeEnum.kt @@ -0,0 +1,145 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.common.exception + +import com.tencent.devops.common.api.annotation.BkFieldI18n +import com.tencent.devops.common.api.pojo.ErrorType +import com.tencent.devops.common.web.utils.I18nUtil + +enum class ErrorCodeEnum( + @BkFieldI18n + val errorType: ErrorType, + val errorCode: Int, + val formatErrorMessage: String +) { + STREAM_NOT_ENABLE_ERROR(ErrorType.USER, 2129001, "[repository: {0}]CI is not enabled"), + // + + // SYSTEM_ERROR(ErrorType.SYSTEM, 2129001, "stream系统错误"), + NO_REPORT_AUTH(ErrorType.SYSTEM, 2129002, "无权限查看报告"), + + // stream 接口请求错误 + DEVNET_TIMEOUT_ERROR(ErrorType.THIRD_PARTY, 2129003, "request DEVNET gateway timeout"), + GET_TOKEN_ERROR(ErrorType.THIRD_PARTY, 2129004, "get token from git error {0}"), + REFRESH_TOKEN_ERROR(ErrorType.THIRD_PARTY, 2129005, "refresh token from git error {0}"), + + GET_YAML_CONTENT_ERROR(ErrorType.THIRD_PARTY, 2129006, "获取stream 仓库文件内容失败"), + PROJECT_NOT_FOUND( + ErrorType.USER, + 2129007, + "Project [{0}] not found. Please check your project name again." + ), + GET_PROJECT_INFO_ERROR( + ErrorType.THIRD_PARTY, + 2129008, + "Load project [{0}] failed. Git api error: {1}" + ), + GET_PROJECT_INFO_FORBIDDEN( + ErrorType.USER, 2129009, + "No access to project [{0}]." + ), + + // GET_PROJECT_COMMITS_ERROR(ErrorType.THIRD_PARTY, 2129008, "获取仓库提交记录失败"), + CREATE_NEW_FILE_ERROR( + ErrorType.THIRD_PARTY, + 2129010, + "Create new pipeline failed. Git api error: {0}" + ), + CREATE_NEW_FILE_GIT_API_ERROR( + ErrorType.THIRD_PARTY, + 2129011, + "Failed to add {0} on branch {1}. Git api error, code: {2}, message: {3}." + ), + // GET_PROJECT_BRANCHES_ERROR(ErrorType.THIRD_PARTY, 2129011, "获取仓库分支列表失败"), + GET_GIT_MERGE_CHANGE_INFO(ErrorType.THIRD_PARTY, 2129012, "获取MERGE变更文件列表失败"), + GET_GIT_FILE_INFO_ERROR(ErrorType.THIRD_PARTY, 2129013, "获取仓库文件信息失败"), + GET_GIT_MERGE_INFO(ErrorType.THIRD_PARTY, 2129014, "获取MERGE提交信息失败"), + GET_GIT_FILE_TREE_ERROR(ErrorType.THIRD_PARTY, 2129015, "获取仓库CI文件列表失败"), + + // 手动触发需要转为错误码给用户,区分构建中的系统和用户异常 + MANUAL_TRIGGER_USER_ERROR(ErrorType.USER, 2129016, "manual trigger user error: [{0}]"), + MANUAL_TRIGGER_SYSTEM_ERROR( + ErrorType.SYSTEM, + 2129017, + "manual trigger system error: [{0}]" + ), + MANUAL_TRIGGER_THIRD_PARTY_ERROR( + ErrorType.THIRD_PARTY, + 2129018, + "manual trigger third party error: [{0}]" + ), + CLEAR_TOKEN_ERROR( + ErrorType.THIRD_PARTY, + 2129019, + "clear token from git error {0}" + ), + GET_GIT_PROJECT_MEMBERS_ERROR(ErrorType.THIRD_PARTY, 2129020, "获取仓库成员失败"), + GET_GIT_LATEST_REVISION_ERROR(ErrorType.THIRD_PARTY, 2129021, "获取分支最新commit信息失败"), + GET_COMMIT_CHANGE_FILE_LIST_ERROR( + ErrorType.THIRD_PARTY, + 2129022, + "获取提交差异文件列表失败" + ), + JOB_ID_CONFLICT_ERROR(ErrorType.USER, 2129023, "job id 流水线内不能重复"), + // STEP_ID_CONFLICT_ERROR(ErrorType.USER, 2129024, "step id 同一job内不能重复"), + COMMON_USER_NOT_EXISTS( + ErrorType.USER, + 2129024, + "公共账号[{0}]未注册,请先联系 DevOps-helper 注册" + ), + MANUAL_TRIGGER_YAML_NULL( + ErrorType.USER, + 2129025, + "分支上没有此流水线,或者流水线未允许手动触发" + ), + MANUAL_TRIGGER_YAML_INVALID( + ErrorType.USER, + 2129026, + "手动触发YAML SCHEMA校验错误" + ), + GET_COMMIT_INFO_ERROR(ErrorType.THIRD_PARTY, 2129027, "获取提交信息失败"), + GET_USER_INFO_ERROR( + ErrorType.THIRD_PARTY, + 2129028, + "Load user info failed. Git api error: {0}" + ); + + fun getErrorMessage(params: Array? = null): String { + return I18nUtil.getCodeLanMessage(messageCode = "${this.errorCode}", params = params) + } + companion object { + + fun get(errorCode: Int): ErrorCodeEnum? { + return try { + values().first { it.errorCode == errorCode } + } catch (e: NoSuchElementException) { + null + } + } + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/ApiRequestRetryInfo.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/ApiRequestRetryInfo.kt new file mode 100644 index 00000000000..c30dd75e677 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/ApiRequestRetryInfo.kt @@ -0,0 +1,40 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.git.pojo + +/** + * 请求git api重试信息 + * @param retry 是否重试 + * @param retryTimes 重试次数 + * @param retryPeriodMills 每次重试间隔秒数 + */ +data class ApiRequestRetryInfo( + val retry: Boolean = false, + val retryTimes: Int = 5, + val retryPeriodMills: Long = 500 +) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitChangeFileInfo.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitChangeFileInfo.kt new file mode 100644 index 00000000000..4b52124ce13 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitChangeFileInfo.kt @@ -0,0 +1,46 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + */ + +package com.tencent.devops.process.trigger.git.pojo + +/** + * PAC需要的变更文件的信息 + */ +interface PacGitChangeFileInfo { + // 变更前路径 + val oldPath: String + + // 变更后路径 + val newPath: String + + // 是否是改名文件 + val renameFile: Boolean + + // 是否是删除文件 + val deletedFile: Boolean +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitCred.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitCred.kt new file mode 100644 index 00000000000..ae5c95e7716 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitCred.kt @@ -0,0 +1,33 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.git.pojo + +/** + * PAC传递的调用各个git平台的凭据信息,各平台实现不同 + */ +interface PacGitCred diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitFileInfo.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitFileInfo.kt new file mode 100644 index 00000000000..9f555e24801 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitFileInfo.kt @@ -0,0 +1,12 @@ +package com.tencent.devops.process.trigger.git.pojo + +/** + * PAC需要用到的文件内容 + */ +interface PacGitFileInfo { + // 文件内容 + val content: String + + // git文件的唯一标识 + val blobId: String +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitMrChangeInfo.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitMrChangeInfo.kt new file mode 100644 index 00000000000..0e26810faec --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitMrChangeInfo.kt @@ -0,0 +1,9 @@ +package com.tencent.devops.process.trigger.git.pojo + +/** + * Stream需要的合并请求信息,带变更文件 + */ +interface PacGitMrChangeInfo { + // 这次合并请求涉及的变更文件 + val files: List +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitMrInfo.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitMrInfo.kt new file mode 100644 index 00000000000..2397298c2d7 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitMrInfo.kt @@ -0,0 +1,9 @@ +package com.tencent.devops.process.trigger.git.pojo + +/** + * PAC需要的合并请求信息 + */ +interface PacGitMrInfo { + // 当前合并请求的状态,可用来判断是否冲突 + val mergeStatus: String +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitProjectInfo.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitProjectInfo.kt new file mode 100644 index 00000000000..f634d1ec6aa --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitProjectInfo.kt @@ -0,0 +1,72 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.git.pojo + +/** + * PAC需要的各git平台的项目信息 + */ +interface PacGitProjectInfo { + // 项目唯一标识 + val gitProjectId: String + + // 默认分支 + val defaultBranch: String? + + // 项目的http/https的git链接,例 https://github.com/Tencent/bk-ci.git + val gitHttpUrl: String + + // 项目名称,例 bk-ci + val name: String + + // git ssh链接 + val gitSshUrl: String? + + // git主页链接 + val homepage: String? + + // git https链接 + val gitHttpsUrl: String? + + // git 仓库描述 + val description: String? + + // git 仓库图片地址 + val avatarUrl: String? + + // 地址全称 xxx/xx + val pathWithNamespace: String? + + // 名称全称 + val nameWithNamespace: String + + // 触发仓库创建时间字符串 如:2017-08-13T07:37:14+0000 + val repoCreatedTime: String + + // 触发仓库创建人id, 工蜂侧是数字 id 需要使用时转换为 name + val repoCreatorId: String +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitTreeFileInfo.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitTreeFileInfo.kt new file mode 100644 index 00000000000..cb6d9d5a946 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/PacGitTreeFileInfo.kt @@ -0,0 +1,17 @@ +package com.tencent.devops.process.trigger.git.pojo + +/** + * PAC需要的Git文件列表中的文件信息 + */ +interface PacGitTreeFileInfo { + // 文件ID + val id: String? + // 文件名称 + val name: String + // 文件类型 文件夹/文件 + val type: String +} + +enum class StreamGitTreeFileInfoType(val value: String) { + BLOB("blob") +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitChangeFileInfo.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitChangeFileInfo.kt new file mode 100644 index 00000000000..c19d3b863f5 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitChangeFileInfo.kt @@ -0,0 +1,54 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.git.pojo.tgit + +import com.tencent.devops.repository.pojo.git.GitMrChangeInfo +import com.tencent.devops.scm.pojo.ChangeFileInfo +import com.tencent.devops.process.trigger.git.pojo.PacGitChangeFileInfo + +data class TGitChangeFileInfo( + override val oldPath: String, + override val newPath: String, + override val renameFile: Boolean, + override val deletedFile: Boolean +) : PacGitChangeFileInfo { + + constructor(c: ChangeFileInfo) : this( + oldPath = c.oldPath, + newPath = c.newPath, + renameFile = c.renameFile, + deletedFile = c.deletedFile + ) + + constructor(c: GitMrChangeInfo.GitMrFile) : this( + oldPath = c.oldPath, + newPath = c.newPath, + renameFile = c.renameFile, + deletedFile = c.deletedFile + ) +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitCred.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitCred.kt new file mode 100644 index 00000000000..416a366ce07 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitCred.kt @@ -0,0 +1,42 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.git.pojo.tgit + +import com.tencent.devops.process.trigger.git.pojo.PacGitCred + +data class TGitCred( + // 获取stream OAUTH时用户的唯一凭证 + val userId: String?, + // 具体的accessToken有时优先使用 + val accessToken: String? = null, + /** + * stream 分为oauth和private key的token,private的请求方式不同 + * true 为oauth, false 为private + */ + val useAccessToken: Boolean = true +) : PacGitCred diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitFileInfo.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitFileInfo.kt new file mode 100644 index 00000000000..bf97ef388c0 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitFileInfo.kt @@ -0,0 +1,36 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.git.pojo.tgit + +import com.tencent.devops.process.trigger.git.pojo.PacGitFileInfo + +data class TGitFileInfo( + // stream 的内容经过base64加码,需要解码 + override val content: String, + override val blobId: String +) : PacGitFileInfo diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitMrChangeInfo.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitMrChangeInfo.kt new file mode 100644 index 00000000000..61f0d369dae --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitMrChangeInfo.kt @@ -0,0 +1,34 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.git.pojo.tgit + +import com.tencent.devops.process.trigger.git.pojo.PacGitMrChangeInfo + +data class TGitMrChangeInfo( + override val files: List +) : PacGitMrChangeInfo diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitMrInfo.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitMrInfo.kt new file mode 100644 index 00000000000..6771602ea3d --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitMrInfo.kt @@ -0,0 +1,45 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.git.pojo.tgit + +import com.tencent.devops.scm.pojo.GitMrInfo +import com.tencent.devops.process.trigger.git.pojo.PacGitMrInfo + +data class TGitMrInfo( + override val mergeStatus: String, + val baseCommit: String?, + val baseInfo: GitMrInfo? = null +) : PacGitMrInfo + +enum class TGitMrStatus(val value: String) { + MERGE_STATUS_UNCHECKED("unchecked"), + MERGE_STATUS_CAN_BE_MERGED("can_be_merged"), + MERGE_STATUS_CAN_NOT_BE_MERGED("cannot_be_merged") + // 项目有配置 mr hook,当创建mr后,发送mr hook前,这个状态是hook_intercept,与stream无关 + // MERGE_STATUS_HOOK_INTERCEPT("hook_intercept") +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitProjectInfo.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitProjectInfo.kt new file mode 100644 index 00000000000..88e728460bf --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitProjectInfo.kt @@ -0,0 +1,63 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.git.pojo.tgit + +import com.tencent.devops.scm.pojo.GitProjectInfo +import com.tencent.devops.process.trigger.git.pojo.PacGitProjectInfo + +data class TGitProjectInfo( + override val gitProjectId: String, + override val defaultBranch: String?, + override val gitHttpUrl: String, + override val name: String, + override val gitSshUrl: String?, + override val homepage: String?, + override val gitHttpsUrl: String?, + override val description: String?, + override val avatarUrl: String?, + override val pathWithNamespace: String?, + override val nameWithNamespace: String, + override val repoCreatorId: String, + override val repoCreatedTime: String +) : PacGitProjectInfo { + constructor(g: GitProjectInfo) : this( + gitProjectId = g.id.toString(), + defaultBranch = g.defaultBranch, + gitHttpUrl = g.repositoryUrl, + name = g.name, + gitSshUrl = g.gitSshUrl, + homepage = g.homepage, + gitHttpsUrl = g.gitHttpsUrl, + description = g.description, + avatarUrl = g.avatarUrl, + pathWithNamespace = g.pathWithNamespace, + nameWithNamespace = g.namespaceName, + repoCreatorId = g.creatorId ?: "", + repoCreatedTime = g.createdAt ?: "" + ) +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitTreeFileInfo.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitTreeFileInfo.kt new file mode 100644 index 00000000000..1e78bd035e1 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/pojo/tgit/TGitTreeFileInfo.kt @@ -0,0 +1,43 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.git.pojo.tgit + +import com.tencent.devops.scm.pojo.GitFileInfo +import com.tencent.devops.process.trigger.git.pojo.PacGitTreeFileInfo + +data class TGitTreeFileInfo( + override val id: String, + override val name: String, + override val type: String +) : PacGitTreeFileInfo { + constructor(f: GitFileInfo) : this( + id = f.id, + name = f.name, + type = f.type + ) +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/service/PacApiUtil.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/service/PacApiUtil.kt new file mode 100644 index 00000000000..5dc8e33d73a --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/service/PacApiUtil.kt @@ -0,0 +1,77 @@ +package com.tencent.devops.process.trigger.git.service + +import com.tencent.devops.common.api.exception.ClientException +import com.tencent.devops.common.api.exception.CustomException +import com.tencent.devops.common.api.exception.ErrorCodeException +import com.tencent.devops.common.api.exception.RemoteServiceException +import com.tencent.devops.common.service.utils.RetryUtils +import com.tencent.devops.process.trigger.common.exception.ErrorCodeEnum +import com.tencent.devops.process.trigger.git.pojo.ApiRequestRetryInfo +import org.slf4j.Logger + +object PacApiUtil { + fun doRetryFun( + logger: Logger, + retry: ApiRequestRetryInfo, + log: String, + apiErrorCode: ErrorCodeEnum, + action: () -> T + ): T { + return if (retry.retry) { + retryFun( + retry = retry, + logger = logger, + log = log, + apiErrorCode = apiErrorCode + ) { + action() + } + } else { + action() + } + } + + private fun retryFun( + retry: ApiRequestRetryInfo, + logger: Logger, + log: String, + apiErrorCode: ErrorCodeEnum, + action: () -> T + ): T { + try { + return RetryUtils.clientRetry( + retry.retryTimes, + retry.retryPeriodMills + ) { + action() + } + } catch (e: ClientException) { + logger.warn("TGitApiService|retryFun|retry 5 times $log", e) + throw ErrorCodeException(errorCode = ErrorCodeEnum.DEVNET_TIMEOUT_ERROR.errorCode.toString()) + } catch (e: RemoteServiceException) { + logger.warn("TGitApiService|retryFun|GIT_API_ERROR $log", e) + throw ErrorCodeException( + statusCode = e.httpStatus, + errorCode = apiErrorCode.errorCode.toString(), + defaultMessage = "$log: ${e.errorMessage}" + ) + } catch (e: CustomException) { + logger.warn("TGitApiService|retryFun|GIT_SCM_ERROR $log", e) + throw ErrorCodeException( + statusCode = e.status.statusCode, + errorCode = apiErrorCode.errorCode.toString(), + defaultMessage = "$log: ${e.message}" + ) + } catch (e: Throwable) { + logger.error("TGitApiService|retryFun|retryFun error $log", e) + throw ErrorCodeException( + errorCode = apiErrorCode.errorCode.toString(), + defaultMessage = if (e.message.isNullOrBlank()) { + "$log: ${apiErrorCode.getErrorMessage()}" + } else { + "$log: ${e.message}" + } + ) + } + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/service/PacGitApiService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/service/PacGitApiService.kt new file mode 100644 index 00000000000..f6ebf0d1fad --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/service/PacGitApiService.kt @@ -0,0 +1,124 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.git.service + +import com.tencent.devops.process.trigger.git.pojo.ApiRequestRetryInfo +import com.tencent.devops.process.trigger.git.pojo.PacGitCred +import com.tencent.devops.process.trigger.git.pojo.PacGitFileInfo +import com.tencent.devops.process.trigger.git.pojo.PacGitMrChangeInfo +import com.tencent.devops.process.trigger.git.pojo.PacGitMrInfo +import com.tencent.devops.process.trigger.git.pojo.PacGitProjectInfo +import com.tencent.devops.process.trigger.git.pojo.PacGitTreeFileInfo + +/** + * PAC 需要用到的各平台的标准接口 + * 注:在代码主流程中直接使用api的方法需要放到这里,只在各个action中的可以在其具体的GitApiService中去实现 + * 注2:只应该在trigger相关逻辑中使用此接口,其他地方使用scm相关 + */ +interface PacGitApiService { + + /** + * 通过传递的凭据信息直接获取实体token,方便直接调用接口,类似commit check之类的 + * @param cred 调用api相关凭证 + */ + fun getToken(cred: PacGitCred): String + + /** + * 获取stream需要的git项目信息 + * 当前api加入缓存,需要调用优先从缓存获取 + * @see com.tencent.devops.stream.trigger.parsers.StreamTriggerCache.getAndSaveRequestGitProjectInfo + * @param gitProjectId git项目唯一标识 + * @param retry 当前请求重试的相关信息 + */ + fun getGitProjectInfo( + cred: PacGitCred, + gitProjectId: String, + retry: ApiRequestRetryInfo + ): PacGitProjectInfo? + + /** + * 获取合并请求信息 + * @param mrId 合并请求的唯一凭证 + * @param gitProjectId 使用关联event事件的 git project id + */ + fun getMrInfo( + cred: PacGitCred, + gitProjectId: String, + mrId: String, + retry: ApiRequestRetryInfo + ): PacGitMrInfo? + + /** + * 获取合并请求信息包括变更文件 + * @param gitProjectId 使用关联event事件的 git project id + */ + fun getMrChangeInfo( + cred: PacGitCred, + gitProjectId: String, + mrId: String, + retry: ApiRequestRetryInfo + ): PacGitMrChangeInfo? + + /** + * 获取Git仓库文件列表 + * @param path 获取文件路径下的文件列表 + * @param ref commit hash值、分支 或 tag + * @param recursive 是否支持递归目录结构 + */ + fun getFileTree( + cred: PacGitCred, + gitProjectId: String, + path: String?, + ref: String?, + recursive: Boolean, + retry: ApiRequestRetryInfo + ): List + + /** + * 获取yaml文件的具体内容 + * @param fileName 文件名称 + */ + fun getFileContent( + cred: PacGitCred, + gitProjectId: String, + fileName: String, + ref: String, + retry: ApiRequestRetryInfo + ): String + + /** + * 获取yaml文件内容以及文件信息 + */ + fun getFileInfo( + cred: PacGitCred, + gitProjectId: String, + fileName: String, + ref: String?, + retry: ApiRequestRetryInfo + ): PacGitFileInfo? +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/service/TGitApiService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/service/TGitApiService.kt new file mode 100644 index 00000000000..af419fd3b0d --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/git/service/TGitApiService.kt @@ -0,0 +1,273 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.git.service + +import com.tencent.devops.common.api.exception.CustomException +import com.tencent.devops.common.client.Client +import com.tencent.devops.process.trigger.common.exception.ErrorCodeEnum +import com.tencent.devops.process.trigger.git.pojo.ApiRequestRetryInfo +import com.tencent.devops.process.trigger.git.pojo.PacGitCred +import com.tencent.devops.process.trigger.git.pojo.tgit.TGitCred +import com.tencent.devops.process.trigger.git.service.PacApiUtil.doRetryFun +import com.tencent.devops.repository.api.ServiceOauthResource +import com.tencent.devops.repository.api.scm.ServiceGitResource +import com.tencent.devops.repository.pojo.enums.RepoAuthType +import com.tencent.devops.repository.pojo.enums.TokenTypeEnum +import com.tencent.devops.scm.pojo.GitMrReviewInfo +import com.tencent.devops.process.trigger.git.pojo.tgit.TGitChangeFileInfo +import com.tencent.devops.process.trigger.git.pojo.tgit.TGitFileInfo +import com.tencent.devops.process.trigger.git.pojo.tgit.TGitMrChangeInfo +import com.tencent.devops.process.trigger.git.pojo.tgit.TGitMrInfo +import com.tencent.devops.process.trigger.git.pojo.tgit.TGitProjectInfo +import com.tencent.devops.process.trigger.git.pojo.tgit.TGitTreeFileInfo +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Service +import javax.ws.rs.core.Response + +@Service +class TGitApiService @Autowired constructor( + private val client: Client +) : PacGitApiService { + + companion object { + private val logger = LoggerFactory.getLogger(TGitApiService::class.java) + } + + /** + * 通过凭据获取可以直接使用的token + */ + override fun getToken( + cred: PacGitCred + ): String { + return cred.toToken() + } + + override fun getGitProjectInfo( + cred: PacGitCred, + gitProjectId: String, + retry: ApiRequestRetryInfo + ): TGitProjectInfo? { + return doRetryFun( + logger = logger, + retry = retry, + log = "$gitProjectId get project $gitProjectId fail", + apiErrorCode = ErrorCodeEnum.GET_PROJECT_INFO_ERROR + ) { + client.get(ServiceGitResource::class).getProjectInfo( + token = cred.toToken(), + tokenType = cred.toTokenType(), + gitProjectId = gitProjectId + ).data + }?.let { + TGitProjectInfo(it) + } + } + + + override fun getMrInfo( + cred: PacGitCred, + gitProjectId: String, + mrId: String, + retry: ApiRequestRetryInfo + ): TGitMrInfo? { + return doRetryFun( + logger = logger, + retry = retry, + log = "$gitProjectId get mr $mrId info error", + apiErrorCode = ErrorCodeEnum.GET_GIT_MERGE_INFO + ) { + client.get(ServiceGitResource::class).getMergeRequestInfo( + token = cred.toToken(), + tokenType = cred.toTokenType(), + repoName = gitProjectId, + mrId = mrId.toLong() + ).data + }?.let { + TGitMrInfo( + mergeStatus = it.mergeStatus ?: "", + baseCommit = it.baseCommit, + baseInfo = it + ) + } + } + + fun getMrReview( + cred: PacGitCred, + gitProjectId: String, + mrId: String, + retry: ApiRequestRetryInfo + ): GitMrReviewInfo? { + return doRetryFun( + logger = logger, + retry = retry, + log = "$gitProjectId get mr $mrId info error", + apiErrorCode = ErrorCodeEnum.GET_GIT_MERGE_INFO + ) { + client.get(ServiceGitResource::class).getMergeRequestReviewersInfo( + token = cred.toToken(), + tokenType = cred.toTokenType(), + repoName = gitProjectId, + mrId = mrId.toLong() + ).data + } + } + + override fun getMrChangeInfo( + cred: PacGitCred, + gitProjectId: String, + mrId: String, + retry: ApiRequestRetryInfo + ): TGitMrChangeInfo? { + return doRetryFun( + logger = logger, + retry = retry, + log = "$gitProjectId get mr $mrId changeInfo error", + apiErrorCode = ErrorCodeEnum.GET_GIT_MERGE_CHANGE_INFO + ) { + client.get(ServiceGitResource::class).getMergeRequestChangeInfo( + token = cred.toToken(), + tokenType = cred.toTokenType(), + repoName = gitProjectId, + mrId = mrId.toLong() + ).data + }?.let { + TGitMrChangeInfo( + files = it.files.map { f -> + TGitChangeFileInfo(f) + } + ) + } + } + + override fun getFileTree( + cred: PacGitCred, + gitProjectId: String, + path: String?, + ref: String?, + recursive: Boolean, + retry: ApiRequestRetryInfo + ): List { + return doRetryFun( + logger = logger, + retry = retry, + log = "$gitProjectId get $path file tree error", + apiErrorCode = ErrorCodeEnum.GET_GIT_FILE_TREE_ERROR + ) { + client.get(ServiceGitResource::class).getGitFileTree( + gitProjectId = gitProjectId, + path = path ?: "", + token = cred.toToken(), + ref = ref, + recursive = recursive, + tokenType = cred.toTokenType() + ).data ?: emptyList() + }.map { TGitTreeFileInfo(it) } + } + + override fun getFileContent( + cred: PacGitCred, + gitProjectId: String, + fileName: String, + ref: String, + retry: ApiRequestRetryInfo + ): String { + cred as TGitCred + return doRetryFun( + logger = logger, + retry = retry, + log = "$gitProjectId get yaml $fileName from $ref fail", + apiErrorCode = ErrorCodeEnum.GET_YAML_CONTENT_ERROR + ) { + client.get(ServiceGitResource::class).getGitFileContent( + token = cred.toToken(), + authType = if (cred.useAccessToken) { + RepoAuthType.OAUTH + } else { + RepoAuthType.SSH + }, + repoName = gitProjectId, + ref = getTriggerBranch(ref), + filePath = fileName + ).data!! + } + } + + private fun getTriggerBranch(branch: String): String { + return when { + branch.startsWith("refs/heads/") -> branch.removePrefix("refs/heads/") + branch.startsWith("refs/tags/") -> branch.removePrefix("refs/tags/") + else -> branch + } + } + + override fun getFileInfo( + cred: PacGitCred, + gitProjectId: String, + fileName: String, + ref: String?, + retry: ApiRequestRetryInfo + ): TGitFileInfo? { + return doRetryFun( + logger = logger, + retry = retry, + log = "getFileInfo: [$gitProjectId|$fileName][$ref] error", + apiErrorCode = ErrorCodeEnum.GET_GIT_FILE_INFO_ERROR + ) { + client.get(ServiceGitResource::class).getGitFileInfo( + gitProjectId = gitProjectId, + filePath = fileName, + token = cred.toToken(), + ref = ref, + tokenType = cred.toTokenType() + ).data + }?.let { TGitFileInfo(content = it.content, blobId = it.blobId) } + } + + + protected fun PacGitCred.toToken(): String { + this as TGitCred + if (this.accessToken != null) { + return this.accessToken + } + return client.get(ServiceOauthResource::class).gitGet(this.userId!!).data?.accessToken + ?: throw CustomException( + Response.Status.FORBIDDEN, + "STEAM PROJECT ENABLE USER NO OAUTH PERMISSION" + ) + } + + protected fun PacGitCred.toTokenType(): TokenTypeEnum { + this as TGitCred + return if (this.useAccessToken) { + TokenTypeEnum.OAUTH + } else { + TokenTypeEnum.PRIVATE_KEY + } + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/pojo/PacTriggerLock.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/pojo/PacTriggerLock.kt new file mode 100644 index 00000000000..599ea69f787 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/pojo/PacTriggerLock.kt @@ -0,0 +1,43 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.pojo + +import com.tencent.devops.common.redis.RedisLock +import com.tencent.devops.common.redis.RedisOperation + +class PacTriggerLock( + redisOperation: RedisOperation, + projectId: String, + repoHashId: String, + filePath: String +) : + RedisLock( + redisOperation = redisOperation, + lockKey = "lock:projectId:$projectId:repoHashId:$repoHashId:filePath:$filePath", + expiredTimeInSeconds = 60 + ) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/pojo/YamlContent.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/pojo/YamlContent.kt new file mode 100644 index 00000000000..6d852f95cd0 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/pojo/YamlContent.kt @@ -0,0 +1,39 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.pojo + +open class YamlContent( + open val ref: String, + open val content: String +) + +data class MrYamlInfo( + override val ref: String, + override val content: String, + val blobId: String? +) : YamlContent(ref, content) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/pojo/YamlPathListEntry.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/pojo/YamlPathListEntry.kt new file mode 100644 index 00000000000..2a719dc4269 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/pojo/YamlPathListEntry.kt @@ -0,0 +1,46 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.trigger.pojo + +data class YamlPathListEntry( + val yamlPath: String, + val checkType: CheckType, + val ref: String?, + val blobId: String? +) + +enum class CheckType { + // 需要校验 + NEED_CHECK, + + // 无需校验 + NO_NEED_CHECK, + + // 校验有问题,改流水线不触发 + NO_TRIGGER +} From 9df1ac2413b7b6bcf79280a5a36042e8ecd5272e Mon Sep 17 00:00:00 2001 From: royalhuang Date: Wed, 30 Aug 2023 15:39:13 +0800 Subject: [PATCH 090/852] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=BB=BA/?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=97=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=B0=83=E8=AF=95=E6=B5=81=E6=B0=B4=E7=BA=BF=20#8164?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=E8=B0=83=E8=AF=95=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tencent/devops/common/pipeline/pojo/BuildFormProperty.kt | 3 +++ .../devops/process/api/user/UserPipelineDebugResource.kt | 1 + 2 files changed, 4 insertions(+) diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/BuildFormProperty.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/BuildFormProperty.kt index a002e3d6bde..04ca346861d 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/BuildFormProperty.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/BuildFormProperty.kt @@ -42,6 +42,9 @@ data class BuildFormProperty( val type: BuildFormPropertyType, @ApiModelProperty("默认值", required = true) var defaultValue: Any, + // TODO #8164 增加上一次的变量记录,前端只需调一次接口 + @ApiModelProperty("上次构建的取值", required = true) + var value: Any, @ApiModelProperty("下拉框列表", required = false) var options: List?, @ApiModelProperty("描述", required = false) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineDebugResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineDebugResource.kt index 0eb50f636c7..7f19c4d3633 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineDebugResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineDebugResource.kt @@ -57,6 +57,7 @@ import javax.ws.rs.core.MediaType @Suppress("ALL") interface UserPipelineDebugResource { + // TODO #8164 是否使用最近一次构建参数值:取上一次调试或取默认值(前端可以主动取默认值,尽量不要点一次改一次) @ApiOperation("调试-获取流水线手动启动参数") @GET @Path("/projects/{projectId}/pipelines/{pipelineId}/debugStartupInfo") From f3da9e463e0356e1a2525ed96d49df81476e7a4d Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 31 Aug 2023 12:58:26 +0800 Subject: [PATCH 091/852] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=BB=BA/?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=97=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=B0=83=E8=AF=95=E6=B5=81=E6=B0=B4=E7=BA=BF=20#8164?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=E8=B0=83=E8=AF=95=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../yaml/modelTransfer/TriggerTransfer.kt | 2 +- .../yaml/v2/models/on/SchedulesRule.kt | 1 - .../common/pipeline/pojo/BuildFormProperty.kt | 3 +- .../process/api/user/UserBuildResource.kt | 11 +- .../api/user/UserPipelineDebugResource.kt | 194 ------------------ .../engine/dao/PipelineResourceVersionDao.kt | 13 ++ .../service/PipelineRepositoryService.kt | 51 ++++- .../process/api/UserBuildResourceImpl.kt | 15 +- .../api/UserPipelineVersionResourceImpl.kt | 21 +- .../builds/PipelineBuildFacadeService.kt | 46 ++--- .../pipeline/PipelineSettingFacadeService.kt | 1 - 11 files changed, 128 insertions(+), 230 deletions(-) delete mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineDebugResource.kt diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt index da433a2dfb9..90d75a95c17 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt @@ -603,7 +603,7 @@ class TriggerTransfer @Autowired(required = false) constructor( TimerTriggerElement( newExpression = timer.cron?.disjoin(), advanceExpression = timer.advanceCron, - noScm = timer.always != true, + noScm = timer.always != true ).checkTriggerElementEnable(timer.enable) ) } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/SchedulesRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/SchedulesRule.kt index 148aa59c093..1430b3bed65 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/SchedulesRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/SchedulesRule.kt @@ -45,7 +45,6 @@ data class SchedulesRule( @JsonProperty("advance-cron") val advanceCron: List? = null, - val branches: List? = null, val always: Boolean? = false diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/BuildFormProperty.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/BuildFormProperty.kt index 7bc578ede39..ac626c636fc 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/BuildFormProperty.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/BuildFormProperty.kt @@ -42,9 +42,8 @@ data class BuildFormProperty( val type: BuildFormPropertyType, @ApiModelProperty("默认值", required = true) var defaultValue: Any, - // TODO #8164 增加上一次的变量记录,前端只需调一次接口 @ApiModelProperty("上次构建的取值", required = true) - var value: Any, + var value: Any? = null, @ApiModelProperty("下拉框列表", required = false) var options: List?, @ApiModelProperty("描述", required = false) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserBuildResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserBuildResource.kt index 4fdfd8ada15..1087f549f1e 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserBuildResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserBuildResource.kt @@ -68,6 +68,7 @@ import javax.ws.rs.core.Response @Suppress("ALL") interface UserBuildResource { + // TODO #8164 增加调试,是否使用最近一次构建参数值:取上一次调试或取默认值(前端可以主动取默认值,尽量不要点一次改一次) @ApiOperation("获取流水线手动启动参数") @GET // @Path("/projects/{projectId}/pipelines/{pipelineId}/manualStartupInfo") @@ -81,7 +82,10 @@ interface UserBuildResource { projectId: String, @ApiParam("流水线ID", required = true) @PathParam("pipelineId") - pipelineId: String + pipelineId: String, + @ApiParam("指定草稿版本", required = false) + @QueryParam("version") + version: Int? ): Result @ApiOperation("获取流水线构建参数") @@ -124,7 +128,10 @@ interface UserBuildResource { buildNo: Int? = null, @ApiParam("触发审核人列表", required = false) @QueryParam("triggerReviewers") - triggerReviewers: List? = null + triggerReviewers: List? = null, + @ApiParam("指定草稿版本", required = false) + @QueryParam("version") + version: Int? = null ): Result @ApiOperation("重试流水线-重试或者跳过失败插件") diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineDebugResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineDebugResource.kt deleted file mode 100644 index 7f19c4d3633..00000000000 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineDebugResource.kt +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. - * - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. - * - * A copy of the MIT License is included in this file. - * - * - * Terms of the MIT License: - * --------------------------------------------------- - * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated - * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all copies or substantial portions of - * the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT - * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN - * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -package com.tencent.devops.process.api.user - -import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID -import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE -import com.tencent.devops.common.api.pojo.BuildHistoryPage -import com.tencent.devops.common.api.pojo.Result -import com.tencent.devops.common.pipeline.enums.BuildStatus -import com.tencent.devops.common.pipeline.enums.StartType -import com.tencent.devops.common.pipeline.pojo.BuildParameters -import com.tencent.devops.process.pojo.BuildHistory -import com.tencent.devops.process.pojo.BuildId -import com.tencent.devops.process.pojo.BuildManualStartupInfo -import io.swagger.annotations.Api -import io.swagger.annotations.ApiOperation -import io.swagger.annotations.ApiParam -import javax.ws.rs.Consumes -import javax.ws.rs.GET -import javax.ws.rs.HeaderParam -import javax.ws.rs.POST -import javax.ws.rs.Path -import javax.ws.rs.PathParam -import javax.ws.rs.Produces -import javax.ws.rs.QueryParam -import javax.ws.rs.core.MediaType - -@Api(tags = ["USER_PIPELINE_DEBUG"], description = "用户-流水线调试构建") -@Path("/user/debug") -@Produces(MediaType.APPLICATION_JSON) -@Consumes(MediaType.APPLICATION_JSON) -@Suppress("ALL") -interface UserPipelineDebugResource { - - // TODO #8164 是否使用最近一次构建参数值:取上一次调试或取默认值(前端可以主动取默认值,尽量不要点一次改一次) - @ApiOperation("调试-获取流水线手动启动参数") - @GET - @Path("/projects/{projectId}/pipelines/{pipelineId}/debugStartupInfo") - fun debugStartupInfo( - @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) - @HeaderParam(AUTH_HEADER_USER_ID) - userId: String, - @ApiParam("项目ID", required = true) - @PathParam("projectId") - projectId: String, - @ApiParam("流水线ID", required = true) - @PathParam("pipelineId") - pipelineId: String - ): Result - - @ApiOperation("调试-获取流水线构建参数") - @GET - @Path("/projects/{projectId}/pipelines/{pipelineId}/builds/{buildId}/parameters") - fun getDebugBuildParameters( - @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) - @HeaderParam(AUTH_HEADER_USER_ID) - userId: String, - @ApiParam("项目ID", required = true) - @PathParam("projectId") - projectId: String, - @ApiParam("流水线ID", required = true) - @PathParam("pipelineId") - pipelineId: String, - @ApiParam("构建ID", required = true) - @PathParam("buildId") - buildId: String - ): Result> - - @ApiOperation("启动流水线调试") - @POST - @Path("/projects/{projectId}/pipelines/{pipelineId}/start") - fun debugStartup( - @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) - @HeaderParam(AUTH_HEADER_USER_ID) - userId: String, - @ApiParam("项目ID", required = true) - @PathParam("projectId") - projectId: String, - @ApiParam("流水线ID", required = true) - @PathParam("pipelineId") - pipelineId: String, - @ApiParam("启动参数", required = true) - values: Map, - @ApiParam("手动指定构建版本参数", required = false) - @QueryParam("buildNo") - buildNo: Int? = null, - @ApiParam("触发审核人列表", required = false) - @QueryParam("triggerReviewers") - triggerReviewers: List? = null - ): Result - - @ApiOperation("获取流水线调试构建历史") - @GET - @Path("/projects/{projectId}/pipelines/{pipelineId}/history") - fun getDebugHistoryBuild( - @ApiParam(value = "用户ID", required = true, defaultValue = AUTH_HEADER_USER_ID_DEFAULT_VALUE) - @HeaderParam(AUTH_HEADER_USER_ID) - userId: String, - @ApiParam("项目ID", required = true) - @PathParam("projectId") - projectId: String, - @ApiParam("流水线ID", required = true) - @PathParam("pipelineId") - pipelineId: String, - @ApiParam("第几页", required = false, defaultValue = "1") - @QueryParam("page") - page: Int?, - @ApiParam("每页多少条", required = false, defaultValue = "20") - @QueryParam("pageSize") - pageSize: Int?, - @ApiParam("代码库别名", required = false) - @QueryParam("materialAlias") - materialAlias: List?, - @ApiParam("代码库URL", required = false) - @QueryParam("materialUrl") - materialUrl: String?, - @ApiParam("分支", required = false) - @QueryParam("materialBranch") - materialBranch: List?, - @ApiParam("commitId", required = false) - @QueryParam("materialCommitId") - materialCommitId: String?, - @ApiParam("commitMessage", required = false) - @QueryParam("materialCommitMessage") - materialCommitMessage: String?, - @ApiParam("状态", required = false) - @QueryParam("status") - status: List?, - @ApiParam("触发方式", required = false) - @QueryParam("trigger") - trigger: List?, - @ApiParam("排队于-开始时间(时间戳形式)", required = false) - @QueryParam("queueTimeStartTime") - queueTimeStartTime: Long?, - @ApiParam("排队于-结束时间(时间戳形式)", required = false) - @QueryParam("queueTimeEndTime") - queueTimeEndTime: Long?, - @ApiParam("开始于-开始时间(时间戳形式)", required = false) - @QueryParam("startTimeStartTime") - startTimeStartTime: Long?, - @ApiParam("开始于-结束时间(时间戳形式)", required = false) - @QueryParam("startTimeEndTime") - startTimeEndTime: Long?, - @ApiParam("结束于-开始时间(时间戳形式)", required = false) - @QueryParam("endTimeStartTime") - endTimeStartTime: Long?, - @ApiParam("结束于-结束时间(时间戳形式)", required = false) - @QueryParam("endTimeEndTime") - endTimeEndTime: Long?, - @ApiParam("耗时最小值", required = false) - @QueryParam("totalTimeMin") - totalTimeMin: Long?, - @ApiParam("耗时最大值", required = false) - @QueryParam("totalTimeMax") - totalTimeMax: Long?, - @ApiParam("备注", required = false) - @QueryParam("remark") - remark: String?, - @ApiParam("构件号起始", required = false) - @QueryParam("buildNoStart") - buildNoStart: Int?, - @ApiParam("构件号结束", required = false) - @QueryParam("buildNoEnd") - buildNoEnd: Int?, - @ApiParam("构建信息", required = false) - @QueryParam("buildMsg") - buildMsg: String? - ): Result> -} diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceVersionDao.kt index 8c616d0d71d..4ed5d0709d0 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceVersionDao.kt @@ -194,6 +194,19 @@ class PipelineResourceVersionDao { } } + fun clearDraftVersion( + dslContext: DSLContext, + projectId: String, + pipelineId: String + ): Int? { + return with(T_PIPELINE_RESOURCE_VERSION) { + dslContext.deleteFrom(this) + .where(PIPELINE_ID.eq(pipelineId).and(PROJECT_ID.eq(projectId))) + .and(STATUS.eq(VersionStatus.COMMITTING.name)) + .execute() + } + } + fun deleteEarlyVersion( dslContext: DSLContext, projectId: String, diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index 8b5bcac3e5f..1587cb1d5a4 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -893,7 +893,7 @@ class PipelineRepositoryService constructor( pipelineId = pipelineId, version = version - 1 ) - if (version > 1 && lastVersionRecord == null) { + if (version > 1 && lastVersionRecord == null) { // 当ResVersion表中缺失上一个有效版本时需从Res表迁移数据(版本间流水线模型对比有用) // TODO 将保存时才转移到ResVersion的逻辑改成双写同步写入 val lastVersionModelStr = pipelineResourceDao.getVersionModelString( @@ -1064,6 +1064,55 @@ class PipelineRepositoryService constructor( } } + fun rollbackDraftFromVersion( + userId: String, + projectId: String, + pipelineId: String, + version: Int + ): PipelineResourceVersion? { + var resultVersion: PipelineResourceVersion? = null + dslContext.transaction { configuration -> + val context = DSL.using(configuration) + val latestVersion = pipelineResourceDao.getLatestVersionResource( + dslContext = context, + projectId = projectId, + pipelineId = pipelineId + ) + // TODO #8161 增加报错逻辑 + val targetVersion = pipelineResourceVersionDao.getVersionResource( + dslContext = context, + projectId = projectId, + pipelineId = pipelineId, + version = version + ) + if (latestVersion != null && targetVersion != null) { + resultVersion = targetVersion.copy(version = latestVersion.version + 1, versionName = "init") + pipelineResourceVersionDao.clearDraftVersion( + dslContext = context, + projectId = projectId, + pipelineId = pipelineId + ) + pipelineResourceVersionDao.create( + dslContext = context, + projectId = projectId, + pipelineId = pipelineId, + creator = userId, + version = resultVersion!!.version, + versionName = resultVersion!!.versionName ?: "init", + model = resultVersion!!.model, + baseVersion = targetVersion.version, + yaml = resultVersion!!.yaml, + pipelineVersion = resultVersion!!.pipelineVersion, + triggerVersion = resultVersion!!.triggerVersion, + settingVersion = resultVersion!!.settingVersion, + versionStatus = VersionStatus.COMMITTING, + description = null + ) + } + } + return resultVersion + } + private fun str2model( modelString: String, pipelineId: String diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserBuildResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserBuildResourceImpl.kt index b1f41a9973b..8fa60ca524c 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserBuildResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserBuildResourceImpl.kt @@ -66,10 +66,18 @@ class UserBuildResourceImpl @Autowired constructor( override fun manualStartupInfo( userId: String, projectId: String, - pipelineId: String + pipelineId: String, + version: Int? ): Result { checkParam(userId, projectId, pipelineId) - return Result(pipelineBuildFacadeService.buildManualStartupInfo(userId, projectId, pipelineId, ChannelCode.BS)) + return Result( + pipelineBuildFacadeService.buildManualStartupInfo( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + channelCode = ChannelCode.BS + ) + ) } override fun getBuildParameters( @@ -91,7 +99,8 @@ class UserBuildResourceImpl @Autowired constructor( pipelineId: String, values: Map, buildNo: Int?, - triggerReviewers: List? + triggerReviewers: List?, + version: Int? ): Result { checkParam(userId, projectId, pipelineId) val manualStartup = pipelineBuildFacadeService.buildManualStartup( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index 597571d7c8f..e7d0013c94b 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -475,7 +475,26 @@ class UserPipelineVersionResourceImpl @Autowired constructor( pipelineId: String, version: Int ): Result { - TODO("Not yet implemented") + checkParam(userId, projectId) + val permission = AuthPermission.EDIT + pipelinePermissionService.validPipelinePermission( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + permission = permission, + message = MessageUtil.getMessageByLocale( + CommonMessageCode.USER_NOT_PERMISSIONS_OPERATE_PIPELINE, + I18nUtil.getLanguage(userId), + arrayOf( + userId, + projectId, + permission.getI18n(I18nUtil.getLanguage(userId)), + pipelineId + ) + ) + ) + pipelineRepositoryService.rollbackDraftFromVersion(userId, projectId, pipelineId, version) + return Result(true) } private fun checkParam(userId: String, projectId: String) { diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/builds/PipelineBuildFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/builds/PipelineBuildFacadeService.kt index c46edd6bfb2..6c96ffa3461 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/builds/PipelineBuildFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/builds/PipelineBuildFacadeService.kt @@ -187,7 +187,8 @@ class PipelineBuildFacadeService( projectId: String, pipelineId: String, channelCode: ChannelCode, - checkPermission: Boolean = true + checkPermission: Boolean = true, + version: Int? = null ): BuildManualStartupInfo { if (checkPermission) { // 不用校验查看权限,只校验执行权限 @@ -213,41 +214,36 @@ class PipelineBuildFacadeService( errorCode = ProcessMessageCode.ERROR_PIPELINE_NOT_EXISTS, params = arrayOf(pipelineId) ) - - val model = getModel(projectId, pipelineId) + // TODO #8164 检查传入版本是否为草稿 + val model = getModel(projectId, pipelineId, version) val triggerContainer = model.stages[0].containers[0] as TriggerContainer var canManualStartup = false var canElementSkip = false - var useLatestParameters = false run lit@{ triggerContainer.elements.forEach { if (it is ManualTriggerElement && it.isElementEnable()) { canManualStartup = true canElementSkip = it.canElementSkip ?: false - useLatestParameters = it.useLatestParameters ?: false return@lit } } } - // 当使用最近一次参数进行构建的时候,获取并替换container.params中的defaultValue值 - if (useLatestParameters) { - // 获取最后一次的构建id - val lastTimeBuildInfo = pipelineRuntimeService.getLastTimeBuild(projectId, pipelineId) - if (lastTimeBuildInfo?.buildParameters?.isNotEmpty() == true) { - val latestParamsMap = lastTimeBuildInfo.buildParameters!!.associate { it.key to it.value } - triggerContainer.params.forEach { param -> - val realValue = latestParamsMap[param.id] - if (realValue != null) { - // 有上一次的构建参数的时候才设置成默认值,否者依然使用默认值。 - // 当值是boolean类型的时候,需要转为boolean类型 - if (param.defaultValue is Boolean) { - param.defaultValue = realValue.toString().toBoolean() - } else { - param.defaultValue = realValue - } + // 获取最后一次的构建id + val lastTimDebugInfo = pipelineRuntimeService.getLastTimeBuild(projectId, pipelineId) + if (lastTimDebugInfo?.buildParameters?.isNotEmpty() == true) { + val latestParamsMap = lastTimDebugInfo.buildParameters!!.associate { it.key to it.value } + triggerContainer.params.forEach { param -> + val realValue = latestParamsMap[param.id] + if (realValue != null) { + // 有上一次的构建参数的时候才设置成默认值,否者依然使用默认值。 + // 当值是boolean类型的时候,需要转为boolean类型 + if (param.defaultValue is Boolean) { + param.value = realValue.toString().toBoolean() + } else { + param.value = realValue } } } @@ -260,6 +256,7 @@ class PipelineBuildFacadeService( required = true, type = BuildFormPropertyType.STRING, defaultValue = "", + value = "", options = null, desc = I18nUtil.getCodeLanMessage( messageCode = ProcessMessageCode.BUILD_MSG_DESC, @@ -564,7 +561,8 @@ class PipelineBuildFacadeService( startByMessage: String? = null, buildNo: Int? = null, frequencyLimit: Boolean = true, - triggerReviewers: List? = null + triggerReviewers: List? = null, + version: Int? = null ): BuildId { logger.info("[$pipelineId] Manual build start with buildNo[$buildNo] and vars: $values") if (checkPermission) { @@ -596,8 +594,8 @@ class PipelineBuildFacadeService( val startEpoch = System.currentTimeMillis() try { - - val model = getModel(projectId, pipelineId) + // TODO #8164 检查传入版本是否为草稿 + val model = getModel(projectId, pipelineId, version) /** * 验证流水线参数构建启动参数 diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt index 7b62f45b3ec..727d1210f8d 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/pipeline/PipelineSettingFacadeService.kt @@ -37,7 +37,6 @@ import com.tencent.devops.common.auth.api.AuthResourceType import com.tencent.devops.common.client.Client import com.tencent.devops.common.event.dispatcher.pipeline.PipelineEventDispatcher import com.tencent.devops.common.pipeline.enums.ChannelCode -import com.tencent.devops.common.pipeline.enums.VersionStatus import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.api.service.ServicePipelineResource import com.tencent.devops.process.audit.service.AuditService From feea55233466c2b267dfc5014fcf1cffef6dd5eb Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Thu, 31 Aug 2023 20:04:24 +0800 Subject: [PATCH 092/852] =?UTF-8?q?=E3=80=90PAC=E3=80=91feat=EF=BC=9A?= =?UTF-8?q?=E5=BC=80=E5=90=AFPAC=E6=A8=A1=E5=BC=8F=E7=9A=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=BA=93=E6=94=AF=E6=8C=81=E8=87=AA=E5=8A=A8=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E4=BB=A3=E7=A0=81=E5=BA=93YAML=E5=8F=98=E6=9B=B4?= =?UTF-8?q?=E5=88=B0=E8=93=9D=E7=9B=BE=20#8130?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tencent/devops/process/engine/dao/PipelineYamlReferDao.kt | 2 +- .../tencent/devops/process/engine/dao/PipelineYamlVersionDao.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineYamlReferDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineYamlReferDao.kt index 4858452e42b..0c21329bdcd 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineYamlReferDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineYamlReferDao.kt @@ -65,7 +65,7 @@ class PipelineYamlReferDao { pipelineId, now, now - ) + ).execute() } } diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineYamlVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineYamlVersionDao.kt index cf4c1aaf99d..a4da126f4c3 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineYamlVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineYamlVersionDao.kt @@ -74,7 +74,7 @@ class PipelineYamlVersionDao { versionName, now, now - ) + ).execute() } } From bdebe9bda714eebc4f22a69f8cd378a236256967 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Thu, 31 Aug 2023 21:47:03 +0800 Subject: [PATCH 093/852] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=BB=BA/?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=97=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=B0=83=E8=AF=95=E6=B5=81=E6=B0=B4=E7=BA=BF=20#8164?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0=E8=B0=83=E8=AF=95=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/api/user/UserBuildResource.kt | 1 - .../process/api/UserPipelineResourceImpl.kt | 1 + .../service/PipelineInfoFacadeService.kt | 32 ++++++++++++++++++- .../builds/PipelineBuildFacadeService.kt | 25 ++++++++++++--- 4 files changed, 52 insertions(+), 7 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserBuildResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserBuildResource.kt index 1087f549f1e..742d32712d5 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserBuildResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserBuildResource.kt @@ -68,7 +68,6 @@ import javax.ws.rs.core.Response @Suppress("ALL") interface UserBuildResource { - // TODO #8164 增加调试,是否使用最近一次构建参数值:取上一次调试或取默认值(前端可以主动取默认值,尽量不要点一次改一次) @ApiOperation("获取流水线手动启动参数") @GET // @Path("/projects/{projectId}/pipelines/{pipelineId}/manualStartupInfo") diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index ece73953186..29ce3a0858c 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -86,6 +86,7 @@ import org.springframework.beans.factory.annotation.Autowired import javax.ws.rs.core.Response @RestResource +@Suppress("LongParameterList") class UserPipelineResourceImpl @Autowired constructor( private val pipelineListFacadeService: PipelineListFacadeService, private val pipelineSettingFacadeService: PipelineSettingFacadeService, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index a753be18fb5..2b3b85183e5 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -487,6 +487,37 @@ class PipelineInfoFacadeService @Autowired constructor( } } + fun createYamlPipeline( + userId: String, + projectId: String, + yml: String, + defaultBranch: Boolean + ): DeployPipelineResult { + // TODO 待补充 + return DeployPipelineResult( + pipelineId = "p-001", + pipelineName = "yml-001-pipeline", + version = 1, + versionName = "1.0" + ) + } + + fun updateYamlPipeline( + userId: String, + projectId: String, + pipelineId: String, + yml: String, + defaultBranch: Boolean + ): DeployPipelineResult { + // TODO 待补充 + return DeployPipelineResult( + pipelineId = "p-001", + pipelineName = "yml-001-pipeline", + version = 1, + versionName = "1.0" + ) + } + /** * 还原已经删除的流水线 */ @@ -668,7 +699,6 @@ class PipelineInfoFacadeService @Autowired constructor( } } - // TODO #8161 旧接口传参改造 fun editPipeline( userId: String, projectId: String, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/builds/PipelineBuildFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/builds/PipelineBuildFacadeService.kt index 6c96ffa3461..8c7eb6a7dc4 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/builds/PipelineBuildFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/builds/PipelineBuildFacadeService.kt @@ -50,6 +50,7 @@ import com.tencent.devops.common.pipeline.enums.BuildStatus import com.tencent.devops.common.pipeline.enums.ChannelCode import com.tencent.devops.common.pipeline.enums.ManualReviewAction import com.tencent.devops.common.pipeline.enums.StartType +import com.tencent.devops.common.pipeline.enums.VersionStatus import com.tencent.devops.common.pipeline.pojo.BuildFormProperty import com.tencent.devops.common.pipeline.pojo.BuildFormValue import com.tencent.devops.common.pipeline.pojo.BuildParameters @@ -214,8 +215,22 @@ class PipelineBuildFacadeService( errorCode = ProcessMessageCode.ERROR_PIPELINE_NOT_EXISTS, params = arrayOf(pipelineId) ) - // TODO #8164 检查传入版本是否为草稿 - val model = getModel(projectId, pipelineId, version) + val model = if (version != null) { + val resource = pipelineRepositoryService.getPipelineResourceVersion( + projectId = projectId, + pipelineId = pipelineId, + version = version, + includeDraft = true + ) + if (resource == null || resource.status == VersionStatus.COMMITTING) { + throw ErrorCodeException( + + ) + } + resource.model + } else { + getModel(projectId, pipelineId) + } val triggerContainer = model.stages[0].containers[0] as TriggerContainer @@ -232,9 +247,9 @@ class PipelineBuildFacadeService( } // 获取最后一次的构建id - val lastTimDebugInfo = pipelineRuntimeService.getLastTimeBuild(projectId, pipelineId) - if (lastTimDebugInfo?.buildParameters?.isNotEmpty() == true) { - val latestParamsMap = lastTimDebugInfo.buildParameters!!.associate { it.key to it.value } + val lastTimeInfo = pipelineRuntimeService.getLastTimeBuild(projectId, pipelineId) + if (lastTimeInfo?.buildParameters?.isNotEmpty() == true) { + val latestParamsMap = lastTimeInfo.buildParameters!!.associate { it.key to it.value } triggerContainer.params.forEach { param -> val realValue = latestParamsMap[param.id] if (realValue != null) { From eb53d0724d41aa791abab4896dc6e5f17b41058a Mon Sep 17 00:00:00 2001 From: royalhuang Date: Sun, 3 Sep 2023 17:06:30 +0800 Subject: [PATCH 094/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E7=BB=86=E5=8C=96=E6=8E=A5=E5=8F=A3=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/service/ServicePipelineResource.kt | 10 +--- .../process/api/user/UserPipelineResource.kt | 10 +--- .../process/constant/ProcessMessageCode.kt | 3 +- .../engine/dao/PipelineResourceVersionDao.kt | 2 +- .../service/PipelineRepositoryService.kt | 56 ++++++++++--------- .../api/ServicePipelineResourceImpl.kt | 8 +-- .../process/api/UserPipelineResourceImpl.kt | 7 +-- .../api/UserPipelineVersionResourceImpl.kt | 2 +- .../service/PipelineInfoFacadeService.kt | 3 +- .../builds/PipelineBuildFacadeService.kt | 22 +++++++- .../service/template/TemplateFacadeService.kt | 2 +- 11 files changed, 63 insertions(+), 62 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt index d83b39edb69..32d4d02e30e 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/service/ServicePipelineResource.kt @@ -115,10 +115,7 @@ interface ServicePipelineResource { @ApiParam("是否修改最后修改人", required = false) @QueryParam("updateLastModifyUser") @DefaultValue("true") - updateLastModifyUser: Boolean? = true, - @QueryParam("draft") - @DefaultValue("false") - saveDraft: Boolean? = false + updateLastModifyUser: Boolean? = true ): Result @ApiOperation("复制流水线编排") @@ -177,10 +174,7 @@ interface ServicePipelineResource { modelAndSetting: PipelineModelAndSetting, @ApiParam("渠道号,默认为BS", required = false) @QueryParam("channelCode") - channelCode: ChannelCode, - @QueryParam("draft") - @DefaultValue("false") - saveDraft: Boolean? = false + channelCode: ChannelCode ): Result @ApiOperation("获取流水线编排") diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt index f4eb6eb1e3d..0ecb447b01f 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineResource.kt @@ -201,10 +201,7 @@ interface UserPipelineResource { @PathParam("pipelineId") pipelineId: String, @ApiParam(value = "流水线模型", required = true) - pipeline: Model, - @QueryParam("draft") - @DefaultValue("false") - saveDraft: Boolean? = false + pipeline: Model ): Result @ApiOperation("编辑流水线编排以及设置") @@ -223,10 +220,7 @@ interface UserPipelineResource { pipelineId: String, @ApiParam(value = "流水线模型与设置", required = true) @Valid - modelAndSetting: PipelineModelAndSetting, - @QueryParam("draft") - @DefaultValue("false") - saveDraft: Boolean? = false + modelAndSetting: PipelineModelAndSetting ): Result @ApiOperation("保存流水线设置") diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/constant/ProcessMessageCode.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/constant/ProcessMessageCode.kt index e627c915c6b..27144be723c 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/constant/ProcessMessageCode.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/constant/ProcessMessageCode.kt @@ -281,7 +281,8 @@ object ProcessMessageCode { const val GET_PIPELINE_ATOM_INFO_NO_PERMISSION = "2101180" // 无权访问插件{0}的流水线信息,请联系组件管理员 const val GROUP_IS_EXIST = "2101181" // 分组({0})已存在/group ({0}) is already exist const val GROUP_LABEL_IS_EXIST = "2101182" // 分组标签({0})已存在/group label ({0}) is already exist - const val ERROR_NO_PIPELINE_VERSION_EXISTS_BY_ID = "2101183" // 流水线[{0}]不存在 + const val ERROR_NO_PIPELINE_VERSION_EXISTS_BY_ID = "2101183" // 流水线版本[{0}]不存在 + const val ERROR_NO_PIPELINE_DRAFT_EXISTS = "2101184" // 该流水不存在草稿版本 const val BK_SUCCESSFULLY_DISTRIBUTED = "bkSuccessfullyDistributed" // 跨项目构件分发成功,共分发了{0}个文件 const val BK_SUCCESSFULLY_FAILED = "bkSuccessfullyFailed" // 跨项目构件分发失败, diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceVersionDao.kt index 4ed5d0709d0..cd54df61269 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceVersionDao.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/dao/PipelineResourceVersionDao.kt @@ -84,7 +84,7 @@ class PipelineResourceVersionDao { pipelineId: String, creator: String, version: Int, - versionName: String = "init", + versionName: String? = null, modelStr: String, baseVersion: Int, yamlStr: String?, diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt index 1587cb1d5a4..f67964fe02e 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineRepositoryService.kt @@ -235,7 +235,6 @@ class PipelineRepositoryService constructor( } } } - // TODO #8161 保存接口的 saveDraft 字段变成status枚举参数 return if (!create) { val pipelineSetting = savedSetting ?: pipelineSettingDao.getSetting(dslContext, projectId, pipelineId) @@ -1077,38 +1076,43 @@ class PipelineRepositoryService constructor( dslContext = context, projectId = projectId, pipelineId = pipelineId + ) ?: throw ErrorCodeException( + statusCode = Response.Status.NOT_FOUND.statusCode, + errorCode = ProcessMessageCode.ERROR_PIPELINE_NOT_EXISTS, + params = arrayOf(version.toString()) ) - // TODO #8161 增加报错逻辑 val targetVersion = pipelineResourceVersionDao.getVersionResource( dslContext = context, projectId = projectId, pipelineId = pipelineId, version = version + ) ?: throw ErrorCodeException( + statusCode = Response.Status.NOT_FOUND.statusCode, + errorCode = ProcessMessageCode.ERROR_NO_PIPELINE_VERSION_EXISTS_BY_ID, + params = arrayOf(version.toString()) + ) + resultVersion = targetVersion.copy(version = latestVersion.version + 1, versionName = "init") + pipelineResourceVersionDao.clearDraftVersion( + dslContext = context, + projectId = projectId, + pipelineId = pipelineId + ) + pipelineResourceVersionDao.create( + dslContext = context, + projectId = projectId, + pipelineId = pipelineId, + creator = userId, + version = resultVersion!!.version, + versionName = resultVersion!!.versionName ?: "init", + model = resultVersion!!.model, + baseVersion = targetVersion.version, + yaml = resultVersion!!.yaml, + pipelineVersion = resultVersion!!.pipelineVersion, + triggerVersion = resultVersion!!.triggerVersion, + settingVersion = resultVersion!!.settingVersion, + versionStatus = VersionStatus.COMMITTING, + description = null ) - if (latestVersion != null && targetVersion != null) { - resultVersion = targetVersion.copy(version = latestVersion.version + 1, versionName = "init") - pipelineResourceVersionDao.clearDraftVersion( - dslContext = context, - projectId = projectId, - pipelineId = pipelineId - ) - pipelineResourceVersionDao.create( - dslContext = context, - projectId = projectId, - pipelineId = pipelineId, - creator = userId, - version = resultVersion!!.version, - versionName = resultVersion!!.versionName ?: "init", - model = resultVersion!!.model, - baseVersion = targetVersion.version, - yaml = resultVersion!!.yaml, - pipelineVersion = resultVersion!!.pipelineVersion, - triggerVersion = resultVersion!!.triggerVersion, - settingVersion = resultVersion!!.settingVersion, - versionStatus = VersionStatus.COMMITTING, - description = null - ) - } } return resultVersion } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt index 4f3a96f578c..0001a1f8f63 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/ServicePipelineResourceImpl.kt @@ -39,7 +39,6 @@ import com.tencent.devops.common.event.pojo.measure.PipelineLabelRelateInfo import com.tencent.devops.common.pipeline.Model import com.tencent.devops.common.pipeline.ModelUpdate import com.tencent.devops.common.pipeline.enums.ChannelCode -import com.tencent.devops.common.pipeline.enums.VersionStatus import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting import com.tencent.devops.common.web.RestResource import com.tencent.devops.common.web.utils.I18nUtil @@ -126,8 +125,7 @@ class ServicePipelineResourceImpl @Autowired constructor( pipelineId: String, pipeline: Model, channelCode: ChannelCode, - updateLastModifyUser: Boolean?, - saveDraft: Boolean? + updateLastModifyUser: Boolean? ): Result { checkParams(userId, projectId) val deployPipelineResult = pipelineInfoFacadeService.editPipeline( @@ -218,8 +216,7 @@ class ServicePipelineResourceImpl @Autowired constructor( projectId: String, pipelineId: String, modelAndSetting: PipelineModelAndSetting, - channelCode: ChannelCode, - saveDraft: Boolean? + channelCode: ChannelCode ): Result { modelAndSetting.setting.checkParam() val buildNumRule = modelAndSetting.setting.buildNumRule @@ -232,7 +229,6 @@ class ServicePipelineResourceImpl @Autowired constructor( pipelineId = pipelineId, model = modelAndSetting.model, setting = modelAndSetting.setting, - versionStatus = VersionStatus.RELEASED, channelCode = ChannelCode.BS ) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt index 29ce3a0858c..dce7462c1c3 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineResourceImpl.kt @@ -235,8 +235,7 @@ class UserPipelineResourceImpl @Autowired constructor( userId: String, projectId: String, pipelineId: String, - pipeline: Model, - saveDraft: Boolean? + pipeline: Model ): Result { checkParam(userId, projectId) val pipelineResult = pipelineInfoFacadeService.editPipeline( @@ -266,8 +265,7 @@ class UserPipelineResourceImpl @Autowired constructor( userId: String, projectId: String, pipelineId: String, - modelAndSetting: PipelineModelAndSetting, - saveDraft: Boolean? + modelAndSetting: PipelineModelAndSetting ): Result { checkParam(userId, projectId) modelAndSetting.setting.checkParam() @@ -281,7 +279,6 @@ class UserPipelineResourceImpl @Autowired constructor( pipelineId = pipelineId, model = modelAndSetting.model, setting = modelAndSetting.setting, - versionStatus = VersionStatus.RELEASED, channelCode = ChannelCode.BS ) auditService.createAudit( diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt index e7d0013c94b..36de54ce892 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineVersionResourceImpl.kt @@ -153,7 +153,7 @@ class UserPipelineVersionResourceImpl @Autowired constructor( channelCode = ChannelCode.BS, checkPermission = false, instanceType = request.instanceType, - saveDraft = true, + versionStatus = VersionStatus.COMMITTING, useSubscriptionSettings = request.useSubscriptionSettings, useLabelSettings = request.useLabelSettings, useConcurrencyGroup = request.useConcurrencyGroup diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index 2b3b85183e5..9790cf94256 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -241,7 +241,6 @@ class PipelineInfoFacadeService @Autowired constructor( return Pair(pipelineInfo?.pipelineName ?: "", pipelineInfo?.version ?: 0) } - // TODO #8161 旧接口传参改造 fun createPipeline( userId: String, projectId: String, @@ -254,7 +253,7 @@ class PipelineInfoFacadeService @Autowired constructor( buildNo: BuildNo? = null, param: List? = null, fixTemplateVersion: Long? = null, - saveDraft: Boolean? = false, + versionStatus: VersionStatus? = VersionStatus.COMMITTING, useSubscriptionSettings: Boolean? = false, useLabelSettings: Boolean? = false, useConcurrencyGroup: Boolean? = false diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/builds/PipelineBuildFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/builds/PipelineBuildFacadeService.kt index 8c7eb6a7dc4..328b695fe73 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/builds/PipelineBuildFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/builds/PipelineBuildFacadeService.kt @@ -224,7 +224,8 @@ class PipelineBuildFacadeService( ) if (resource == null || resource.status == VersionStatus.COMMITTING) { throw ErrorCodeException( - + statusCode = Response.Status.NOT_FOUND.statusCode, + errorCode = ProcessMessageCode.ERROR_NO_PIPELINE_DRAFT_EXISTS ) } resource.model @@ -609,8 +610,23 @@ class PipelineBuildFacadeService( val startEpoch = System.currentTimeMillis() try { - // TODO #8164 检查传入版本是否为草稿 - val model = getModel(projectId, pipelineId, version) + val model = if (version != null) { + val resource = pipelineRepositoryService.getPipelineResourceVersion( + projectId = projectId, + pipelineId = pipelineId, + version = version, + includeDraft = true + ) + if (resource == null || resource.status == VersionStatus.COMMITTING) { + throw ErrorCodeException( + statusCode = Response.Status.NOT_FOUND.statusCode, + errorCode = ProcessMessageCode.ERROR_NO_PIPELINE_DRAFT_EXISTS + ) + } + resource.model + } else { + getModel(projectId, pipelineId) + } /** * 验证流水线参数构建启动参数 diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt index c1b0dd5705b..ec8e61e94f5 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/template/TemplateFacadeService.kt @@ -2100,7 +2100,7 @@ class TemplateFacadeService @Autowired constructor( dslContext.transaction { t -> val context = DSL.using(t) projectCodeList.forEach { - // TODO #8161 判断模板名称是否已经关联过,通过setting判断考虑下可否优化 + // 判断模板名称是否已经关联过 val pipelineSettingRecord = pipelineSettingDao.getSetting( dslContext = context, projectId = it, From c422bb7e1efadac34bd570e63855d07bf1ba358d Mon Sep 17 00:00:00 2001 From: royalhuang Date: Sun, 3 Sep 2023 17:07:48 +0800 Subject: [PATCH 095/852] =?UTF-8?q?feat=EF=BC=9A=E6=B5=81=E6=B0=B4?= =?UTF-8?q?=E7=BA=BF=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86=E6=9C=BA=E5=88=B6?= =?UTF-8?q?=20#8161=20=E7=BB=86=E5=8C=96=E6=8E=A5=E5=8F=A3=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- support-files/i18n/process/message_en_US.properties | 1 + support-files/i18n/process/message_zh_CN.properties | 1 + 2 files changed, 2 insertions(+) diff --git a/support-files/i18n/process/message_en_US.properties b/support-files/i18n/process/message_en_US.properties index 205a72427eb..c5ec4bdd84e 100644 --- a/support-files/i18n/process/message_en_US.properties +++ b/support-files/i18n/process/message_en_US.properties @@ -181,6 +181,7 @@ 2101181=group ({0}) is already exist 2101182=group label ({0}) is already exist 2101183=Pipeline version ({0}) does not exist +2101184=There is no draft version of this pipeline ATOM_POST_EXECUTE_TIP=###Tip:this is the post-action hooked by [step{0}]{1}### BK_CI_BUILD_ID=Currently build ID BK_CI_BUILD_JOB_ID=Pipelined JOB ID diff --git a/support-files/i18n/process/message_zh_CN.properties b/support-files/i18n/process/message_zh_CN.properties index 23b609c3b5a..94c559904f0 100644 --- a/support-files/i18n/process/message_zh_CN.properties +++ b/support-files/i18n/process/message_zh_CN.properties @@ -181,6 +181,7 @@ 2101181=分组({0})已存在 2101182=分组标签({0})已存在 2101183=流水线版本({0})不存在 +2101184=该流水不存在草稿版本 ATOM_POST_EXECUTE_TIP=###Tip:this is the post-action hooked by [step{0}]{1}### BK_CI_BUILD_ID=当前构建ID BK_CI_BUILD_JOB_ID=流水线JOB ID From 6cb4ce938360822fcd8e524aeab5356cbaca60ef Mon Sep 17 00:00:00 2001 From: royalhuang Date: Mon, 4 Sep 2023 21:08:12 +0800 Subject: [PATCH 096/852] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=BB=BA/?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=97=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=B0=83=E8=AF=95=E6=B5=81=E6=B0=B4=E7=BA=BF=20#8164?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0pac=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/constant/ProcessMessageCode.kt | 1 + .../pojo/setting/PipelineBranchVersion.kt | 53 ++++++++++ .../process/pojo/transfer/TransferBody.kt | 2 +- .../process/dao/PipelineBranchVersionDao.kt | 100 ++++++++++++++++++ .../api/UserPipelineTransferResourceImpl.kt | 1 + .../service/PipelineBranchVersionService.kt | 69 ++++++++++++ .../service/PipelineInfoFacadeService.kt | 63 +++++++++-- .../transfer/PipelineTransferYamlService.kt | 10 +- 8 files changed, 288 insertions(+), 11 deletions(-) create mode 100644 src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineBranchVersion.kt create mode 100644 src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineBranchVersionDao.kt create mode 100644 src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineBranchVersionService.kt diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/constant/ProcessMessageCode.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/constant/ProcessMessageCode.kt index 27144be723c..4436f8a793a 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/constant/ProcessMessageCode.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/constant/ProcessMessageCode.kt @@ -283,6 +283,7 @@ object ProcessMessageCode { const val GROUP_LABEL_IS_EXIST = "2101182" // 分组标签({0})已存在/group label ({0}) is already exist const val ERROR_NO_PIPELINE_VERSION_EXISTS_BY_ID = "2101183" // 流水线版本[{0}]不存在 const val ERROR_NO_PIPELINE_DRAFT_EXISTS = "2101184" // 该流水不存在草稿版本 + const val ERROR_OCCURRED_IN_TRANSFER = "2101185" // 转换时出现报错 const val BK_SUCCESSFULLY_DISTRIBUTED = "bkSuccessfullyDistributed" // 跨项目构件分发成功,共分发了{0}个文件 const val BK_SUCCESSFULLY_FAILED = "bkSuccessfullyFailed" // 跨项目构件分发失败, diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineBranchVersion.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineBranchVersion.kt new file mode 100644 index 00000000000..a1428b45a14 --- /dev/null +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/setting/PipelineBranchVersion.kt @@ -0,0 +1,53 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.pojo.setting + +import com.tencent.devops.common.pipeline.pojo.setting.Subscription +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty +import java.time.LocalDateTime + +@ApiModel("") +data class PipelineBranchVersion( + @ApiModelProperty("项目id", required = false) + val projectId: String, + @ApiModelProperty("流水线id", required = false) + val pipelineId: String, + @ApiModelProperty("分支名", required = false) + var branch: String, + @ApiModelProperty("版本号", required = false) + var version: Int, + @ApiModelProperty("创建者", required = false) + var creator: String, + @ApiModelProperty("更新者", required = false) + var updater: String, + @ApiModelProperty("创建时间", required = false) + var createTime: LocalDateTime, + @ApiModelProperty("更新时间", required = false) + var updateTime: LocalDateTime +) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferBody.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferBody.kt index f55c12e0594..4f657df4488 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferBody.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/pojo/transfer/TransferBody.kt @@ -34,7 +34,7 @@ import io.swagger.annotations.ApiModelProperty @ApiModel("构建模型-ID") data class TransferBody( @ApiModelProperty("modelAndSetting") - val modelAndSetting: PipelineModelAndSetting, + val modelAndSetting: PipelineModelAndSetting? = null, @ApiModelProperty("当前yaml内容") val oldYaml: String = "" ) diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineBranchVersionDao.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineBranchVersionDao.kt new file mode 100644 index 00000000000..c093565e20e --- /dev/null +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/dao/PipelineBranchVersionDao.kt @@ -0,0 +1,100 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.dao + +import com.tencent.devops.model.process.tables.TPipelineBranchVersion +import com.tencent.devops.model.process.tables.records.TPipelineBranchVersionRecord +import com.tencent.devops.process.pojo.setting.PipelineBranchVersion +import org.jooq.DSLContext +import org.jooq.RecordMapper +import org.springframework.stereotype.Repository +import java.time.LocalDateTime + +@Suppress("LongParameterList") +@Repository +class PipelineBranchVersionDao { + + // 重复的分支版本直接更新,不再插入 + fun saveBranchRefer( + dslContext: DSLContext, + userId: String, + projectId: String, + pipelineId: String, + branchName: String, + version: Int + ): Int { + with(TPipelineBranchVersion.T_PIPELINE_BRANCH_VERSION) { + return dslContext.insertInto(this) + .set(PROJECT_ID, projectId) + .set(PIPELINE_ID, pipelineId) + .set(BRANCH, branchName) + .set(VERSION, version) + .set(CREATOR, userId) + .set(UPDATER, userId) + .onDuplicateKeyUpdate() + .set(VERSION, version) + .set(UPDATER, userId) + .set(UPDATE_TIME, LocalDateTime.now()) + .execute() + } + } + + fun getBranchVersions( + dslContext: DSLContext, + projectId: String, + pipelineId: String + ): List { + with(TPipelineBranchVersion.T_PIPELINE_BRANCH_VERSION) { + return dslContext.selectFrom(this) + .where(PIPELINE_ID.eq(pipelineId)) + .and(PROJECT_ID.eq(projectId)) + .fetch(mapper) + } + } + + class PipelineBranchVersionJooqMapper : RecordMapper { + override fun map(record: TPipelineBranchVersionRecord?): PipelineBranchVersion? { + return record?.let { t -> + PipelineBranchVersion( + projectId = t.projectId, + pipelineId = t.pipelineId, + branch = t.branch, + version = t.version, + creator = t.creator, + updater = t.updater, + createTime = t.createTime, + updateTime = t.updateTime + ) + } + } + } + + companion object { + private val mapper = PipelineBranchVersionJooqMapper() + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt index 21272efd985..160fa398948 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/api/UserPipelineTransferResourceImpl.kt @@ -47,6 +47,7 @@ class UserPipelineTransferResourceImpl @Autowired constructor( private val pipelinePermissionService: PipelinePermissionService, private val transferService: PipelineTransferYamlService ) : UserPipelineTransferResource { + override fun transfer( userId: String, projectId: String, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineBranchVersionService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineBranchVersionService.kt new file mode 100644 index 00000000000..9c340d04ee3 --- /dev/null +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineBranchVersionService.kt @@ -0,0 +1,69 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.service + +import com.tencent.devops.process.dao.PipelineBranchVersionDao +import com.tencent.devops.process.pojo.setting.PipelineBranchVersion +import org.jooq.DSLContext +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Service + +@Service +class PipelineBranchVersionService @Autowired constructor( + private val dslContext: DSLContext, + private val pipelineBranchVersionDao: PipelineBranchVersionDao +) { + + fun saveBranchVersion( + userId: String, + projectId: String, + pipelineId: String, + branchName: String, + version: Int + ): Int { + return pipelineBranchVersionDao.saveBranchRefer( + dslContext = dslContext, + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + branchName = branchName, + version = version + ) + } + + fun getPipelineSettingVersion( + projectId: String, + pipelineId: String + ): List { + return pipelineBranchVersionDao.getBranchVersions( + dslContext = dslContext, + projectId = projectId, + pipelineId = pipelineId + ) + } +} diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index 9790cf94256..a5ac50b6ad5 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -76,8 +76,11 @@ import com.tencent.devops.process.pojo.pipeline.PipelineResourceVersion import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.pojo.template.TemplateType +import com.tencent.devops.process.pojo.transfer.TransferActionType +import com.tencent.devops.process.pojo.transfer.TransferBody import com.tencent.devops.process.service.label.PipelineGroupService import com.tencent.devops.process.service.pipeline.PipelineSettingFacadeService +import com.tencent.devops.process.service.transfer.PipelineTransferYamlService import com.tencent.devops.process.service.view.PipelineViewGroupService import com.tencent.devops.process.template.service.TemplateService import com.tencent.devops.store.api.template.ServiceTemplateResource @@ -111,6 +114,8 @@ class PipelineInfoFacadeService @Autowired constructor( private val processJmxApi: ProcessJmxApi, private val client: Client, private val pipelineInfoDao: PipelineInfoDao, + private val transferService: PipelineTransferYamlService, + private val pipelineBranchVersionService: PipelineBranchVersionService, private val redisOperation: RedisOperation, private val pipelineRecentUseService: PipelineRecentUseService ) { @@ -490,15 +495,60 @@ class PipelineInfoFacadeService @Autowired constructor( userId: String, projectId: String, yml: String, + branchName: String, defaultBranch: Boolean ): DeployPipelineResult { - // TODO 待补充 - return DeployPipelineResult( - pipelineId = "p-001", - pipelineName = "yml-001-pipeline", - version = 1, - versionName = "1.0" + + val (newModel, newYaml) = try { + val result = transferService.transfer( + userId = userId, + projectId = projectId, + pipelineId = null, + actionType = TransferActionType.FULL_YAML2MODEL, + data = TransferBody(oldYaml = yml) + ) + if (result.newYaml == null || result.modelAndSetting == null) { + logger.warn( + "TRANSFER_YAML|$projectId|$userId|$defaultBranch|newYaml=\n${result.newYaml}\n" + + "modelAndSetting=${result.modelAndSetting}" + ) + throw ErrorCodeException( + errorCode = ProcessMessageCode.ERROR_OCCURRED_IN_TRANSFER + ) + } + Pair(result.modelAndSetting!!, result.newYaml!!) + } catch (ignore: Throwable) { + if (ignore is ErrorCodeException) throw ignore + logger.warn("TRANSFER_YAML|$projectId|$userId|$branchName|$defaultBranch|yml=\n$yml", ignore) + throw ErrorCodeException( + // TODO #8161 增加错误码配置 + errorCode = ProcessMessageCode.ERROR_OCCURRED_IN_TRANSFER + ) + } + val versionStatus = if (defaultBranch) { + VersionStatus.RELEASED + } else { + + VersionStatus.BRANCH + } + val result = createPipeline( + userId = userId, + projectId = projectId, + model = newModel.model, + channelCode = ChannelCode.BS, + yaml = newYaml, + versionStatus = versionStatus ) + if (!defaultBranch) { + pipelineBranchVersionService.saveBranchVersion( + userId = userId, + projectId = projectId, + pipelineId = result.pipelineId, + branchName = branchName, + version = result.version + ) + } + return result } fun updateYamlPipeline( @@ -506,6 +556,7 @@ class PipelineInfoFacadeService @Autowired constructor( projectId: String, pipelineId: String, yml: String, + branchName: String, defaultBranch: Boolean ): DeployPipelineResult { // TODO 待补充 diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt index 833a33c6a65..14ce0bd79a3 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt @@ -82,7 +82,7 @@ class PipelineTransferYamlService @Autowired constructor( fun transfer( userId: String, projectId: String, - pipelineId: String, + pipelineId: String?, actionType: TransferActionType, data: TransferBody ): TransferResponse { @@ -93,8 +93,8 @@ class PipelineTransferYamlService @Autowired constructor( watcher.start("step_1|FULL_MODEL2YAML start") val yml = modelTransfer.model2yaml( ModelTransferInput( - data.modelAndSetting.model, - data.modelAndSetting.setting, + data.modelAndSetting!!.model, + data.modelAndSetting!!.setting, YamlVersion.Version.V3_0 ) ) @@ -106,7 +106,9 @@ class PipelineTransferYamlService @Autowired constructor( } TransferActionType.FULL_YAML2MODEL -> { watcher.start("step_1|FULL_YAML2MODEL start") - val pipelineInfo = pipelineRepositoryService.getPipelineInfo(projectId, pipelineId) + val pipelineInfo = pipelineId?.let { + pipelineRepositoryService.getPipelineInfo(projectId, pipelineId) + } val pYml = TransferMapper.getObjectMapper() .readValue(data.oldYaml, object : TypeReference() {}) watcher.start("step_2|parse template") From a4873d4164b229dc128ff91de8a081785ec8b8ea Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Mon, 4 Sep 2023 21:37:08 +0800 Subject: [PATCH 097/852] =?UTF-8?q?=E3=80=90PAC=E3=80=91feat=EF=BC=9A?= =?UTF-8?q?=E5=BC=80=E5=90=AFPAC=E6=A8=A1=E5=BC=8F=E7=9A=84=E4=BB=A3?= =?UTF-8?q?=E7=A0=81=E5=BA=93=E6=94=AF=E6=8C=81=E8=87=AA=E5=8A=A8=E5=90=8C?= =?UTF-8?q?=E6=AD=A5=E4=BB=A3=E7=A0=81=E5=BA=93YAML=E5=8F=98=E6=9B=B4?= =?UTF-8?q?=E5=88=B0=E8=93=9D=E7=9B=BE=20#8130?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops/process/service/PipelineInfoFacadeService.kt | 6 ++++-- .../devops/process/trigger/PacYamlResourceService.kt | 8 ++++++-- .../trigger/actions/data/context/PacTriggerContext.kt | 2 ++ .../process/trigger/actions/pacActions/PacEnableAction.kt | 1 + 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index 5d8c81c9281..6eba56141a4 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -476,7 +476,8 @@ class PipelineInfoFacadeService @Autowired constructor( userId: String, projectId: String, yml: String, - defaultBranch: Boolean + branchName: String, + isDefaultBranch: Boolean ): DeployPipelineResult { // TODO 待补充 return DeployPipelineResult(pipelineId = "p-001", pipelineName = "yml-001-pipeline", version = 1) @@ -487,7 +488,8 @@ class PipelineInfoFacadeService @Autowired constructor( projectId: String, pipelineId: String, yml: String, - defaultBranch: Boolean + branchName: String, + isDefaultBranch: Boolean ): DeployPipelineResult { // TODO 待补充 return DeployPipelineResult(pipelineId = "p-001", pipelineName = "yml-001-pipeline", version = 1) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/PacYamlResourceService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/PacYamlResourceService.kt index 2cc019cba30..06f79e7dc67 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/PacYamlResourceService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/PacYamlResourceService.kt @@ -92,11 +92,13 @@ class PacYamlResourceService @Autowired constructor( entry: YamlPathListEntry ) { val yamlContent = action.getYamlContent(entry.yamlPath) + val branch = action.data.eventCommon.branch val deployPipelineResult = pipelineInfoFacadeService.createYamlPipeline( userId = action.data.setting.enableUser, projectId = projectId, yml = yamlContent.content, - defaultBranch = true + branchName = branch, + isDefaultBranch = branch == action.data.context.defaultBranch ) dslContext.transaction { configuration -> val transactionContext = DSL.using(configuration) @@ -128,12 +130,14 @@ class PacYamlResourceService @Autowired constructor( entry: YamlPathListEntry ) { val yamlContent = action.getYamlContent(entry.yamlPath) + val branch = action.data.eventCommon.branch val deployPipelineResult = pipelineInfoFacadeService.updateYamlPipeline( userId = action.data.setting.enableUser, projectId = projectId, pipelineId = pipelineId, yml = yamlContent.content, - defaultBranch = true + branchName = branch, + isDefaultBranch = branch == action.data.context.defaultBranch ) pipelineYamlVersionDao.save( dslContext = dslContext, diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/context/PacTriggerContext.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/context/PacTriggerContext.kt index c7476a5bd8a..9851f8231dc 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/context/PacTriggerContext.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/data/context/PacTriggerContext.kt @@ -40,6 +40,8 @@ import com.tencent.devops.scm.pojo.GitMrReviewInfo data class PacTriggerContext( var hookRequestId: Long? = null, var eventId: Long? = null, + // 默认分支 + var defaultBranch: String? = null, // 缓存 var gitMrReviewInfo: GitMrReviewInfo? = null, var gitMrInfo: GitMrInfo? = null diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/pacActions/PacEnableAction.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/pacActions/PacEnableAction.kt index 08e5062edb2..4c40217bb3d 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/pacActions/PacEnableAction.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/trigger/actions/pacActions/PacEnableAction.kt @@ -67,6 +67,7 @@ class PacEnableAction : BaseAction { projectName = data.setting.projectName, scmType = event.scmType ) + this.data.context.defaultBranch = defaultBranch return this } From 9290795df1c272ea4a188839d6fb6a7b8b35e75d Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 5 Sep 2023 10:15:19 +0800 Subject: [PATCH 098/852] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=BB=BA/?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=97=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=B0=83=E8=AF=95=E6=B5=81=E6=B0=B4=E7=BA=BF=20#8164?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0pac=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/service/transfer/PipelineTransferYamlService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt index 14ce0bd79a3..8366681087b 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt @@ -138,7 +138,7 @@ class PipelineTransferYamlService @Autowired constructor( } } } catch (t: Throwable) { - logger.warn("PAC|TRANSFER|transferAction") + logger.warn("PAC|TRANSFER|transferAction", t) } finally { watcher.stop() } From 9bd5e4863901d9730e2e1fa3afcb30dc564f7367 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 5 Sep 2023 10:19:52 +0800 Subject: [PATCH 099/852] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=BB=BA/?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=97=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=B0=83=E8=AF=95=E6=B5=81=E6=B0=B4=E7=BA=BF=20#8164?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0pac=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../process/service/PipelineInfoFacadeService.kt | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index a5ac50b6ad5..2abfe66b256 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -499,7 +499,7 @@ class PipelineInfoFacadeService @Autowired constructor( defaultBranch: Boolean ): DeployPipelineResult { - val (newModel, newYaml) = try { + val newModel = try { val result = transferService.transfer( userId = userId, projectId = projectId, @@ -507,16 +507,13 @@ class PipelineInfoFacadeService @Autowired constructor( actionType = TransferActionType.FULL_YAML2MODEL, data = TransferBody(oldYaml = yml) ) - if (result.newYaml == null || result.modelAndSetting == null) { - logger.warn( - "TRANSFER_YAML|$projectId|$userId|$defaultBranch|newYaml=\n${result.newYaml}\n" + - "modelAndSetting=${result.modelAndSetting}" - ) + if (result.modelAndSetting == null) { + logger.warn("TRANSFER_YAML|$projectId|$userId|$defaultBranch|yml=\n$yml") throw ErrorCodeException( errorCode = ProcessMessageCode.ERROR_OCCURRED_IN_TRANSFER ) } - Pair(result.modelAndSetting!!, result.newYaml!!) + result.modelAndSetting!! } catch (ignore: Throwable) { if (ignore is ErrorCodeException) throw ignore logger.warn("TRANSFER_YAML|$projectId|$userId|$branchName|$defaultBranch|yml=\n$yml", ignore) From 044a504a8e4d97ef419a0945917d5ccc6f89d672 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 5 Sep 2023 10:20:08 +0800 Subject: [PATCH 100/852] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=BB=BA/?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=97=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=B0=83=E8=AF=95=E6=B5=81=E6=B0=B4=E7=BA=BF=20#8164?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0pac=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tencent/devops/process/service/PipelineInfoFacadeService.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index 2abfe66b256..3bbc193ed2e 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -533,7 +533,7 @@ class PipelineInfoFacadeService @Autowired constructor( projectId = projectId, model = newModel.model, channelCode = ChannelCode.BS, - yaml = newYaml, + yaml = yml, versionStatus = versionStatus ) if (!defaultBranch) { From a35220586e527ae01767415d5de0dd867aa0cff4 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 5 Sep 2023 20:13:39 +0800 Subject: [PATCH 101/852] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=BB=BA/?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=97=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=B0=83=E8=AF=95=E6=B5=81=E6=B0=B4=E7=BA=BF=20#8164?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0pac=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../api/user/UserPipelineVersionResource.kt | 4 +- .../service/PipelineInfoFacadeService.kt | 63 ++++++++++++++----- 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt index ab33395ca8e..9e78d8b0846 100644 --- a/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt +++ b/src/backend/ci/core/process/api-process/src/main/kotlin/com/tencent/devops/process/api/user/UserPipelineVersionResource.kt @@ -256,7 +256,5 @@ interface UserPipelineVersionResource { version: Int ): Result - // TODO 模板查询:在新建预览页带简要信息:3个bool - - // + // TODO #8161 模板查询:返回模板的model和yaml用于展示,在新建预览页带简要配置信息:3个bool } diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index 3bbc193ed2e..0e4ecc584f7 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -518,23 +518,20 @@ class PipelineInfoFacadeService @Autowired constructor( if (ignore is ErrorCodeException) throw ignore logger.warn("TRANSFER_YAML|$projectId|$userId|$branchName|$defaultBranch|yml=\n$yml", ignore) throw ErrorCodeException( - // TODO #8161 增加错误码配置 errorCode = ProcessMessageCode.ERROR_OCCURRED_IN_TRANSFER ) } - val versionStatus = if (defaultBranch) { - VersionStatus.RELEASED - } else { - - VersionStatus.BRANCH - } val result = createPipeline( userId = userId, projectId = projectId, model = newModel.model, channelCode = ChannelCode.BS, yaml = yml, - versionStatus = versionStatus + versionStatus = if (defaultBranch) { + VersionStatus.RELEASED + } else { + VersionStatus.BRANCH + } ) if (!defaultBranch) { pipelineBranchVersionService.saveBranchVersion( @@ -556,13 +553,51 @@ class PipelineInfoFacadeService @Autowired constructor( branchName: String, defaultBranch: Boolean ): DeployPipelineResult { - // TODO 待补充 - return DeployPipelineResult( - pipelineId = "p-001", - pipelineName = "yml-001-pipeline", - version = 1, - versionName = "1.0" + val newModel = try { + val result = transferService.transfer( + userId = userId, + projectId = projectId, + pipelineId = null, + actionType = TransferActionType.FULL_YAML2MODEL, + data = TransferBody(oldYaml = yml) + ) + if (result.modelAndSetting == null) { + logger.warn("TRANSFER_YAML|$projectId|$userId|$defaultBranch|yml=\n$yml") + throw ErrorCodeException( + errorCode = ProcessMessageCode.ERROR_OCCURRED_IN_TRANSFER + ) + } + result.modelAndSetting!! + } catch (ignore: Throwable) { + if (ignore is ErrorCodeException) throw ignore + logger.warn("TRANSFER_YAML|$projectId|$userId|$branchName|$defaultBranch|yml=\n$yml", ignore) + throw ErrorCodeException( + errorCode = ProcessMessageCode.ERROR_OCCURRED_IN_TRANSFER + ) + } + val result = editPipeline( + userId = userId, + projectId = projectId, + pipelineId = pipelineId, + model = newModel.model, + channelCode = ChannelCode.BS, + yaml = yml, + versionStatus = if (defaultBranch) { + VersionStatus.RELEASED + } else { + VersionStatus.BRANCH + } ) + if (!defaultBranch) { + pipelineBranchVersionService.saveBranchVersion( + userId = userId, + projectId = projectId, + pipelineId = result.pipelineId, + branchName = branchName, + version = result.version + ) + } + return result } /** From 58919ec2f8b0472a9b29872b3fb4a4900a3b3a7a Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 5 Sep 2023 20:13:52 +0800 Subject: [PATCH 102/852] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=BB=BA/?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=97=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=B0=83=E8=AF=95=E6=B5=81=E6=B0=B4=E7=BA=BF=20#8164?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0pac=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- support-files/i18n/process/message_en_US.properties | 1 + support-files/i18n/process/message_zh_CN.properties | 1 + 2 files changed, 2 insertions(+) diff --git a/support-files/i18n/process/message_en_US.properties b/support-files/i18n/process/message_en_US.properties index c5ec4bdd84e..3651e883fcd 100644 --- a/support-files/i18n/process/message_en_US.properties +++ b/support-files/i18n/process/message_en_US.properties @@ -182,6 +182,7 @@ 2101182=group label ({0}) is already exist 2101183=Pipeline version ({0}) does not exist 2101184=There is no draft version of this pipeline +2101185=An error occurred while converting ATOM_POST_EXECUTE_TIP=###Tip:this is the post-action hooked by [step{0}]{1}### BK_CI_BUILD_ID=Currently build ID BK_CI_BUILD_JOB_ID=Pipelined JOB ID diff --git a/support-files/i18n/process/message_zh_CN.properties b/support-files/i18n/process/message_zh_CN.properties index 94c559904f0..74b9e973454 100644 --- a/support-files/i18n/process/message_zh_CN.properties +++ b/support-files/i18n/process/message_zh_CN.properties @@ -182,6 +182,7 @@ 2101182=分组标签({0})已存在 2101183=流水线版本({0})不存在 2101184=该流水不存在草稿版本 +2101185=转换YAML时出现异常 ATOM_POST_EXECUTE_TIP=###Tip:this is the post-action hooked by [step{0}]{1}### BK_CI_BUILD_ID=当前构建ID BK_CI_BUILD_JOB_ID=流水线JOB ID From 5e462920c87385bdb4c8be807aee101e844db3d7 Mon Sep 17 00:00:00 2001 From: royalhuang Date: Tue, 5 Sep 2023 21:17:28 +0800 Subject: [PATCH 103/852] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=BB=BA/?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=97=B6=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=B0=83=E8=AF=95=E6=B5=81=E6=B0=B4=E7=BA=BF=20#8164?= =?UTF-8?q?=20=E5=A2=9E=E5=8A=A0pac=E7=89=88=E6=9C=AC=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/PipelineInfoFacadeService.kt | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt index 0e4ecc584f7..38d2d082035 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/PipelineInfoFacadeService.kt @@ -496,7 +496,7 @@ class PipelineInfoFacadeService @Autowired constructor( projectId: String, yml: String, branchName: String, - defaultBranch: Boolean + isDefaultBranch: Boolean ): DeployPipelineResult { val newModel = try { @@ -508,7 +508,7 @@ class PipelineInfoFacadeService @Autowired constructor( data = TransferBody(oldYaml = yml) ) if (result.modelAndSetting == null) { - logger.warn("TRANSFER_YAML|$projectId|$userId|$defaultBranch|yml=\n$yml") + logger.warn("TRANSFER_YAML|$projectId|$userId|$isDefaultBranch|yml=\n$yml") throw ErrorCodeException( errorCode = ProcessMessageCode.ERROR_OCCURRED_IN_TRANSFER ) @@ -516,7 +516,7 @@ class PipelineInfoFacadeService @Autowired constructor( result.modelAndSetting!! } catch (ignore: Throwable) { if (ignore is ErrorCodeException) throw ignore - logger.warn("TRANSFER_YAML|$projectId|$userId|$branchName|$defaultBranch|yml=\n$yml", ignore) + logger.warn("TRANSFER_YAML|$projectId|$userId|$branchName|$isDefaultBranch|yml=\n$yml", ignore) throw ErrorCodeException( errorCode = ProcessMessageCode.ERROR_OCCURRED_IN_TRANSFER ) @@ -527,13 +527,13 @@ class PipelineInfoFacadeService @Autowired constructor( model = newModel.model, channelCode = ChannelCode.BS, yaml = yml, - versionStatus = if (defaultBranch) { + versionStatus = if (isDefaultBranch) { VersionStatus.RELEASED } else { VersionStatus.BRANCH } ) - if (!defaultBranch) { + if (!isDefaultBranch) { pipelineBranchVersionService.saveBranchVersion( userId = userId, projectId = projectId, @@ -551,7 +551,7 @@ class PipelineInfoFacadeService @Autowired constructor( pipelineId: String, yml: String, branchName: String, - defaultBranch: Boolean + isDefaultBranch: Boolean ): DeployPipelineResult { val newModel = try { val result = transferService.transfer( @@ -562,7 +562,7 @@ class PipelineInfoFacadeService @Autowired constructor( data = TransferBody(oldYaml = yml) ) if (result.modelAndSetting == null) { - logger.warn("TRANSFER_YAML|$projectId|$userId|$defaultBranch|yml=\n$yml") + logger.warn("TRANSFER_YAML|$projectId|$userId|$isDefaultBranch|yml=\n$yml") throw ErrorCodeException( errorCode = ProcessMessageCode.ERROR_OCCURRED_IN_TRANSFER ) @@ -570,7 +570,7 @@ class PipelineInfoFacadeService @Autowired constructor( result.modelAndSetting!! } catch (ignore: Throwable) { if (ignore is ErrorCodeException) throw ignore - logger.warn("TRANSFER_YAML|$projectId|$userId|$branchName|$defaultBranch|yml=\n$yml", ignore) + logger.warn("TRANSFER_YAML|$projectId|$userId|$branchName|$isDefaultBranch|yml=\n$yml", ignore) throw ErrorCodeException( errorCode = ProcessMessageCode.ERROR_OCCURRED_IN_TRANSFER ) @@ -582,13 +582,13 @@ class PipelineInfoFacadeService @Autowired constructor( model = newModel.model, channelCode = ChannelCode.BS, yaml = yml, - versionStatus = if (defaultBranch) { + versionStatus = if (isDefaultBranch) { VersionStatus.RELEASED } else { VersionStatus.BRANCH } ) - if (!defaultBranch) { + if (!isDefaultBranch) { pipelineBranchVersionService.saveBranchVersion( userId = userId, projectId = projectId, From 1bf5bb93bf7f33851757c217eee54f6ea4783aa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?yongyiduan=28=E6=AE=B5=E6=B0=B8=E5=84=84=29?= Date: Wed, 6 Sep 2023 12:00:43 +0800 Subject: [PATCH 104/852] =?UTF-8?q?feat=EF=BC=9A=E6=96=B0=E5=BB=BA/?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E6=B5=81=E6=B0=B4=E7=BA=BF=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E4=BB=A5=20Code=20=E6=96=B9=E5=BC=8F=E7=BC=96=E6=8E=92?= =?UTF-8?q?=E6=B5=81=E6=B0=B4=E7=BA=BF=20#8125=20core?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit # Conflicts: # src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/SchedulesRule.kt # src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/transfer/PipelineTransferYamlService.kt --- .../devops/common/api/enums/ScmType.kt | 1 + .../process/yaml/modelCreate/ModelCommon.kt | 31 + .../yaml/modelCreate/ModelContainer.kt | 212 +--- .../yaml/modelTransfer/ContainerTransfer.kt | 29 +- .../yaml/modelTransfer/DispatchTransfer.kt | 19 +- .../yaml/modelTransfer/ElementTransfer.kt | 168 +-- .../yaml/modelTransfer/ModelTransfer.kt | 60 +- .../yaml/modelTransfer/StageTransfer.kt | 41 +- .../modelTransfer/TransferCacheService.kt | 32 +- .../yaml/modelTransfer/TransferMapper.kt | 2 +- .../yaml/modelTransfer/TriggerTransfer.kt | 120 +- .../yaml/modelTransfer/VariableDefault.kt | 7 +- .../yaml/modelTransfer/VariableTransfer.kt | 179 +++ .../modelTransfer/inner/TransferCreator.kt | 8 +- .../inner/TransferCreatorImpl.kt | 14 +- .../modelTransfer/pojo/ModelTransferInput.kt | 1 + .../modelTransfer/pojo/YamlTransferInput.kt | 2 +- .../process/yaml/v2/enums/TemplateType.kt | 1 - .../devops/process/yaml/v2/models/Extends.kt | 8 +- .../devops/process/yaml/v2/models/Notices.kt | 146 +-- .../yaml/v2/models/PreScriptBuildYaml.kt | 15 +- .../v2/models/PreTemplateScriptBuildYaml.kt | 133 +- .../process/yaml/v2/models/ScriptBuildYaml.kt | 7 +- .../devops/process/yaml/v2/models/Template.kt | 1 - .../devops/process/yaml/v2/models/Variable.kt | 39 +- .../process/yaml/v2/models/image/Pool.kt | 19 +- .../process/yaml/v2/models/image/PoolType.kt | 107 +- .../devops/process/yaml/v2/models/job/Job.kt | 43 +- .../process/yaml/v2/models/job/PreJob.kt | 4 +- .../process/yaml/v2/models/on/IssueRule.kt | 1 - .../process/yaml/v2/models/on/MrRule.kt | 21 +- .../process/yaml/v2/models/on/NoteRule.kt | 7 +- .../process/yaml/v2/models/on/PushRule.kt | 9 +- .../process/yaml/v2/models/on/ReviewRule.kt | 7 +- .../yaml/v2/models/on/SchedulesRule.kt | 9 +- .../process/yaml/v2/models/on/TagRule.kt | 1 - .../process/yaml/v2/models/on/TriggerOn.kt | 116 +- .../process/yaml/v2/models/stage/PreStage.kt | 4 +- .../yaml/v2/models/stage/StageLabel.kt | 9 - .../process/yaml/v2/models/step/PreStep.kt | 4 +- .../yaml/v2/parsers/template/Constants.kt | 1 - .../template/ParametersExpressionParse.kt | 23 +- .../v2/parsers/template/TemplateLibrary.kt | 13 +- .../v2/parsers/template/TemplateYamlUtil.kt | 21 +- .../yaml/v2/parsers/template/YamlObjects.kt | 97 +- .../yaml/v2/parsers/template/YamlTemplate.kt | 170 +-- .../template/models/GetTemplateParam.kt | 3 +- .../template/models/TemplateDeepTreeNode.kt | 5 +- .../process/yaml/v2/utils/ScriptYmlUtils.kt | 169 +-- .../yaml/v2/utils/StreamDispatchUtils.kt | 242 ++++ .../process/yaml/v2/utils/StreamEnvUtils.kt | 3 +- .../yaml/v3/enums/StreamTriggerAction.kt | 59 + .../process/yaml/v3/enums/TemplateType.kt | 43 + .../v3/exception/YamlTemplateException.kt | 32 + .../process/yaml/v3/models/Concurrency.kt | 44 + .../devops/process/yaml/v3/models/Extends.kt | 45 + .../devops/process/yaml/v3/models/IfType.kt | 37 + .../devops/process/yaml/v3/models/Notices.kt | 196 +++ .../yaml/v3/models/PreScriptBuildYaml.kt | 81 ++ .../yaml/v3/models/PreScriptBuildYamlV3.kt | 18 +- .../v3/models/PreTemplateScriptBuildYaml.kt | 162 +++ .../v3/models/PreTemplateScriptBuildYamlV3.kt | 26 +- .../process/yaml/v3/models/RepositoryHook.kt | 80 ++ .../process/yaml/v3/models/Resources.kt | 64 + .../process/yaml/v3/models/ScriptBuildYaml.kt | 60 + .../yaml/v3/models/ScriptBuildYamlV3.kt | 16 +- .../devops/process/yaml/v3/models/Template.kt | 34 + .../devops/process/yaml/v3/models/Variable.kt | 207 ++++ .../process/yaml/v3/models/YamlMetaData.kt | 51 + .../yaml/v3/models/YamlTransferData.kt | 68 ++ .../devops/process/yaml/v3/models/YmlName.kt | 37 + .../process/yaml/v3/models/YmlVersion.kt | 37 + .../models/export/ExportPreScriptBuildYaml.kt | 60 + .../yaml/v3/models/gate/ContinueOnFail.kt | 32 + .../yaml/v3/models/image/Credential.kt | 39 + .../process/yaml/v3/models/image/Pool.kt | 66 + .../process/yaml/v3/models/image/PoolType.kt | 201 +++ .../devops/process/yaml/v3/models/job/Job.kt | 171 +++ .../process/yaml/v3/models/job/PreJob.kt | 73 ++ .../process/yaml/v3/models/on/DeleteRule.kt | 56 + .../process/yaml/v3/models/on/EnableType.kt | 33 + .../process/yaml/v3/models/on/IssueRule.kt | 38 + .../yaml/{v2 => v3}/models/on/ManualRule.kt | 2 +- .../process/yaml/v3/models/on/MatchRule.kt | 41 + .../process/yaml/v3/models/on/MrRule.kt | 81 ++ .../process/yaml/v3/models/on/NoteRule.kt | 39 + .../yaml/v3/models/on/PreTriggerOnV3.kt | 10 +- .../process/yaml/v3/models/on/PushRule.kt | 65 + .../process/yaml/v3/models/on/ReviewRule.kt | 39 + .../yaml/v3/models/on/SchedulesRule.kt | 52 + .../process/yaml/v3/models/on/TagRule.kt | 57 + .../process/yaml/v3/models/on/TriggerOn.kt | 143 +++ .../process/yaml/v3/models/stage/PreStage.kt | 59 + .../process/yaml/v3/models/stage/Stage.kt | 59 + .../yaml/v3/models/stage/StageLabel.kt | 47 + .../process/yaml/v3/models/step/PreStep.kt | 72 ++ .../process/yaml/v3/models/step/Step.kt | 60 + .../process/yaml/v3/parameter/Parameters.kt | 49 + .../yaml/v3/parameter/ParametersTemplate.kt | 40 + .../yaml/v3/parsers/template/Constants.kt | 83 ++ .../template/ParametersExpressionParse.kt | 554 +++++++++ .../yaml/v3/parsers/template/TemplateGraph.kt | 90 ++ .../v3/parsers/template/TemplateLibrary.kt | 83 ++ .../v3/parsers/template/TemplateYamlMapper.kt | 66 + .../v3/parsers/template/TemplateYamlUtil.kt | 163 +++ .../yaml/v3/parsers/template/YamlObjects.kt | 592 +++++++++ .../yaml/v3/parsers/template/YamlTemplate.kt | 800 ++++++++++++ .../v3/parsers/template/YamlTemplateConf.kt | 9 + .../template/models/ExpressionBlock.kt | 11 + .../template/models/GetTemplateParam.kt | 50 + .../yaml/v3/parsers/template/models/Graph.kt | 88 ++ .../template/models/NoReplaceStagTemplate.kt | 48 + .../template/models/NoReplaceTemplate.kt | 46 + .../template/models/TemplateDeepTreeNode.kt | 102 ++ .../template/models/TemplateProjectData.kt | 44 + .../devops/process/yaml/v3/stageCheck/Gate.kt | 43 + .../yaml/v3/stageCheck/GateTemplate.kt | 35 + .../yaml/v3/stageCheck/PreStageCheck.kt | 39 + .../yaml/v3/stageCheck/PreStageReviews.kt | 43 + .../v3/stageCheck/PreTemplateStageCheck.kt | 40 + .../yaml/v3/stageCheck/ReviewVariable.kt | 39 + .../process/yaml/v3/stageCheck/StageCheck.kt | 37 + .../yaml/v3/stageCheck/StageReviews.kt | 43 + .../process/yaml/v3/utils/ScriptYmlUtils.kt | 1073 +++++++++++++++++ .../{ => v3}/utils/StreamDispatchUtils.kt | 10 +- .../process/yaml/v3/utils/StreamEnvUtils.kt | 70 ++ .../process/yaml/v3/utils/YamlCommonUtils.kt | 58 + .../trigger/CodeGitWebHookTriggerElement.kt | 2 +- .../CodeGithubWebHookTriggerElement.kt | 2 +- .../CodeGitlabWebHookTriggerElement.kt | 14 +- .../trigger/CodeP4WebHookTriggerElement.kt | 2 +- .../trigger/CodeSVNWebHookTriggerElement.kt | 2 +- .../trigger/CodeTGitWebHookTriggerElement.kt | 2 +- .../api/service/ServicePipelineResource.kt | 23 +- .../atom/parser/DispatchTypeParserImpl.kt | 2 +- .../api/ServicePipelineResourceImpl.kt | 47 +- .../transfer/PipelineTransferYamlService.kt | 13 +- .../stream/trigger/ManualTriggerService.kt | 3 +- .../devops/stream/trigger/StreamYamlBuild.kt | 7 +- .../stream/trigger/StreamYamlTrigger.kt | 6 +- .../actions/github/GithubPushActionGit.kt | 4 +- .../trigger/actions/tgit/TGitPushActionGit.kt | 4 +- .../trigger/pojo/ManualPreScriptBuildYaml.kt | 7 +- 143 files changed, 8489 insertions(+), 1475 deletions(-) create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/VariableTransfer.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/StreamDispatchUtils.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/enums/StreamTriggerAction.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/enums/TemplateType.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/exception/YamlTemplateException.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Concurrency.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Extends.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/IfType.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Notices.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreScriptBuildYaml.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYaml.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/RepositoryHook.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Resources.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/ScriptBuildYaml.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Template.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Variable.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/YamlMetaData.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/YamlTransferData.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/YmlName.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/YmlVersion.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/export/ExportPreScriptBuildYaml.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/gate/ContinueOnFail.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/image/Credential.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/image/Pool.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/image/PoolType.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/job/Job.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/job/PreJob.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/DeleteRule.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/EnableType.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/IssueRule.kt rename src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/{v2 => v3}/models/on/ManualRule.kt (97%) create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/MatchRule.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/MrRule.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/NoteRule.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PushRule.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/ReviewRule.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/SchedulesRule.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/TagRule.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/TriggerOn.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/stage/PreStage.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/stage/Stage.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/stage/StageLabel.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/step/PreStep.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/step/Step.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parameter/Parameters.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parameter/ParametersTemplate.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/Constants.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/ParametersExpressionParse.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/TemplateGraph.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/TemplateLibrary.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/TemplateYamlMapper.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/TemplateYamlUtil.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/YamlObjects.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/YamlTemplate.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/YamlTemplateConf.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/ExpressionBlock.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/GetTemplateParam.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/Graph.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/NoReplaceStagTemplate.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/NoReplaceTemplate.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/TemplateDeepTreeNode.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/TemplateProjectData.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/Gate.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/GateTemplate.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/PreStageCheck.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/PreStageReviews.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/PreTemplateStageCheck.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/ReviewVariable.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/StageCheck.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/StageReviews.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/utils/ScriptYmlUtils.kt rename src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/{ => v3}/utils/StreamDispatchUtils.kt (96%) create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/utils/StreamEnvUtils.kt create mode 100644 src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/utils/YamlCommonUtils.kt diff --git a/src/backend/ci/core/common/common-api/src/main/kotlin/com/tencent/devops/common/api/enums/ScmType.kt b/src/backend/ci/core/common/common-api/src/main/kotlin/com/tencent/devops/common/api/enums/ScmType.kt index 0fc4722606f..32d0e905770 100644 --- a/src/backend/ci/core/common/common-api/src/main/kotlin/com/tencent/devops/common/api/enums/ScmType.kt +++ b/src/backend/ci/core/common/common-api/src/main/kotlin/com/tencent/devops/common/api/enums/ScmType.kt @@ -49,6 +49,7 @@ enum class ScmType(val alis: String) { } fun parse(alis: String?): ScmType? { + if (alis.isNullOrBlank()) return null values().forEach { if (alis == it.alis) return it } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelCommon.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelCommon.kt index dab2fa89afd..a5abc8612d2 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelCommon.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelCommon.kt @@ -38,6 +38,8 @@ import org.slf4j.LoggerFactory object ModelCommon { private val logger = LoggerFactory.getLogger(ModelCommon::class.java) + val regexMatch = Regex("""(.*)\s*==\s*'(.*)'""") + val regexNotMatch = Regex("""(.*)\s*!=\s*'(.*)'""") fun getBranchName(ref: String): String { return when { @@ -108,6 +110,20 @@ object ModelCommon { else ifString } + fun revertCustomVariableMatch(input: String): List? { + if (input.indexOf("&&") == -1) return null + val res = mutableListOf() + kotlin.runCatching { + input.split("&&").forEach { + regexMatch.matchEntire(it.trim())?.run { + val (key, value) = this.destructured + res.add(NameAndValue(key, value)) + } + } + }.onFailure { return null } + return res + } + fun customVariableMatchNotRun(input: List?): String? { val ifString = input?.joinToString(separator = " || ") { "${it.key} != '${it.value}' " @@ -115,4 +131,19 @@ object ModelCommon { return if (input?.isEmpty() == true) null else ifString } + + + fun revertCustomVariableNotMatch(input: String): List? { + if (input.indexOf("||") == -1) return null + val res = mutableListOf() + kotlin.runCatching { + input.split("||").forEach { + regexNotMatch.matchEntire(it.trim())?.run { + val (key, value) = this.destructured + res.add(NameAndValue(key, value)) + } + } + }.onFailure { return null } + return res + } } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelContainer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelContainer.kt index 81290ef492e..1c26d2f2cb0 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelContainer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelCreate/ModelContainer.kt @@ -31,7 +31,6 @@ import com.fasterxml.jackson.databind.ObjectMapper import com.tencent.devops.common.api.constant.CommonMessageCode.BK_ENV_NOT_YET_SUPPORTED import com.tencent.devops.common.api.exception.CustomException import com.tencent.devops.common.api.util.JsonUtil -import com.tencent.devops.common.api.util.MessageUtil import com.tencent.devops.common.api.util.YamlUtil import com.tencent.devops.common.client.Client import com.tencent.devops.common.pipeline.container.Container @@ -39,7 +38,6 @@ import com.tencent.devops.common.pipeline.container.MutexGroup import com.tencent.devops.common.pipeline.container.NormalContainer import com.tencent.devops.common.pipeline.container.VMBuildContainer import com.tencent.devops.common.pipeline.enums.DependOnType -import com.tencent.devops.common.pipeline.enums.DockerVersion import com.tencent.devops.common.pipeline.enums.JobRunCondition import com.tencent.devops.common.pipeline.enums.VMBaseOS import com.tencent.devops.common.pipeline.matrix.DispatchInfo @@ -47,34 +45,20 @@ import com.tencent.devops.common.pipeline.matrix.MatrixConfig.Companion.MATRIX_C import com.tencent.devops.common.pipeline.option.JobControlOption import com.tencent.devops.common.pipeline.option.MatrixControlOption import com.tencent.devops.common.pipeline.pojo.element.Element -import com.tencent.devops.common.pipeline.type.StoreDispatchType -import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentEnvDispatchType -import com.tencent.devops.common.pipeline.type.docker.DockerDispatchType -import com.tencent.devops.common.pipeline.type.docker.ImageType import com.tencent.devops.common.web.utils.I18nUtil -import com.tencent.devops.process.constant.ProcessMessageCode import com.tencent.devops.process.pojo.BuildTemplateAcrossInfo import com.tencent.devops.process.yaml.modelCreate.inner.InnerModelCreator import com.tencent.devops.process.yaml.modelTransfer.TransferCacheService -import com.tencent.devops.process.yaml.modelTransfer.VariableDefault -import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault import com.tencent.devops.process.yaml.pojo.StreamDispatchInfo import com.tencent.devops.process.yaml.utils.ModelCreateUtil -import com.tencent.devops.process.yaml.utils.StreamDispatchUtils import com.tencent.devops.process.yaml.v2.models.IfType import com.tencent.devops.process.yaml.v2.models.Resources -import com.tencent.devops.process.yaml.v2.models.job.Container2 -import com.tencent.devops.process.yaml.v2.models.job.Job -import com.tencent.devops.process.yaml.v2.models.job.JobRunsOnType -import com.tencent.devops.process.yaml.v2.models.job.Mutex -import com.tencent.devops.process.yaml.v2.models.job.PreJob -import com.tencent.devops.process.yaml.v2.models.job.RunsOn -import com.tencent.devops.process.yaml.v2.models.job.Strategy -import com.tencent.devops.process.yaml.v2.models.step.PreStep +import com.tencent.devops.process.yaml.v2.models.job.* +import com.tencent.devops.process.yaml.v2.utils.StreamDispatchUtils import com.tencent.devops.store.api.container.ServiceContainerAppResource +import javax.ws.rs.core.Response import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component -import javax.ws.rs.core.Response @Component class ModelContainer @Autowired(required = false) constructor( @@ -292,194 +276,4 @@ class ModelContainer @Autowired(required = false) constructor( timeout = resource.timeoutMinutes ?: 10 ) } - - fun addYamlNormalContainer( - job: NormalContainer, - steps: List? - ): PreJob { - return PreJob( - name = job.name, - runsOn = RunsOn( - selfHosted = null, - poolName = JobRunsOnType.AGENT_LESS.type, - container = null - ), - container = null, - services = null, - ifField = when (job.jobControlOption?.runCondition) { - JobRunCondition.CUSTOM_CONDITION_MATCH -> job.jobControlOption?.customCondition - JobRunCondition.CUSTOM_VARIABLE_MATCH -> ModelCommon.customVariableMatch( - job.jobControlOption?.customVariables - ) - JobRunCondition.CUSTOM_VARIABLE_MATCH_NOT_RUN -> ModelCommon.customVariableMatchNotRun( - job.jobControlOption?.customVariables - ) - else -> null - }, - steps = steps, - timeoutMinutes = job.jobControlOption?.timeout.nullIfDefault(VariableDefault.DEFAULT_JOB_TIME_OUT), - env = null, - continueOnError = job.jobControlOption?.continueWhenFailed - .nullIfDefault(VariableDefault.DEFAULT_CONTINUE_WHEN_FAILED), - strategy = if (job.matrixGroupFlag == true) { - getMatrixFromJob(job.matrixControlOption) - } else null, - // 蓝盾这边是自定义Job ID - dependOn = if (!job.jobControlOption?.dependOnId.isNullOrEmpty()) { - job.jobControlOption?.dependOnId - } else null - ) - } - - fun addYamlVMBuildContainer( - job: VMBuildContainer, - steps: List? - ): PreJob { - return PreJob( - name = job.name, - runsOn = getRunsOn(job), - container = null, - services = null, - ifField = when (job.jobControlOption?.runCondition) { - JobRunCondition.CUSTOM_CONDITION_MATCH -> job.jobControlOption?.customCondition - JobRunCondition.CUSTOM_VARIABLE_MATCH -> ModelCommon.customVariableMatch( - job.jobControlOption?.customVariables - ) - JobRunCondition.CUSTOM_VARIABLE_MATCH_NOT_RUN -> ModelCommon.customVariableMatchNotRun( - job.jobControlOption?.customVariables - ) - else -> null - }, - steps = steps, - timeoutMinutes = job.jobControlOption?.timeout.nullIfDefault(VariableDefault.DEFAULT_JOB_TIME_OUT), - env = null, - continueOnError = job.jobControlOption?.continueWhenFailed - .nullIfDefault(VariableDefault.DEFAULT_CONTINUE_WHEN_FAILED), - strategy = if (job.matrixGroupFlag == true) { - getMatrixFromJob(job.matrixControlOption) - } else null, - dependOn = if (!job.jobControlOption?.dependOnId.isNullOrEmpty()) { - job.jobControlOption?.dependOnId - } else null - ) - } - - fun getRunsOn( - job: VMBuildContainer - ): RunsOn = when (val dispatchType = job.dispatchType) { - is ThirdPartyAgentEnvDispatchType -> { - RunsOn( - selfHosted = true, - poolName = I18nUtil.getCodeLanMessage( - messageCode = ProcessMessageCode.BK_AUTOMATIC_EXPORT_NOT_SUPPORTED - ), - container = null, - agentSelector = listOf(job.baseOS.name.toLowerCase()), - needs = job.buildEnv - ) - } - is DockerDispatchType -> { - // todo 凭据是否处理 - val (containerImage, credentials) = getImageNameAndCredentials( - dispatchType - ) - RunsOn( - selfHosted = null, - poolName = JobRunsOnType.DOCKER.type, - container = Container2( - image = containerImage, - credentials = credentials, - options = null, - imagePullPolicy = null - ), - agentSelector = null, - needs = job.buildEnv - ) - } - else -> { - RunsOn( - selfHosted = null, - poolName = I18nUtil.getCodeLanMessage( - messageCode = ProcessMessageCode.BK_AUTOMATIC_EXPORT_NOT_SUPPORTED - ), - container = null, - agentSelector = null - ) - } - } - - fun getImageNameAndCredentials( - dispatchType: StoreDispatchType - ): Pair { - try { - when (dispatchType.imageType) { - ImageType.BKSTORE -> { - val imageRepoInfo = transferCache.getStoreImageInfo( - imageCode = dispatchType.imageCode ?: "", - imageVersion = dispatchType.imageVersion - ) ?: return Pair(dispatchType.imageCode ?: "", null) - val completeImageName = if (ImageType.BKDEVOPS == imageRepoInfo.sourceType) { - // 蓝盾项目源镜像 - "${imageRepoInfo.repoUrl}/${imageRepoInfo.repoName}" - } else { - // 第三方源镜像 - // dockerhub镜像名称不带斜杠前缀 - if (imageRepoInfo.repoUrl.isBlank()) { - imageRepoInfo.repoName - } else { - "${imageRepoInfo.repoUrl}/${imageRepoInfo.repoName}" - } - } + ":" + imageRepoInfo.repoTag - return if (imageRepoInfo.publicFlag) { - Pair(completeImageName, null) - } else Pair( - completeImageName, imageRepoInfo.ticketId - ) - } - ImageType.BKDEVOPS -> { - // 针对非商店的旧数据处理 - return if (dispatchType.value != DockerVersion.TLINUX1_2.value && - dispatchType.value != DockerVersion.TLINUX2_2.value - ) { - dispatchType.dockerBuildVersion = "bkdevops/" + dispatchType.value - Pair("bkdevops/" + dispatchType.value, null) - } else { - Pair( - MessageUtil.getMessageByLocale( - messageCode = ProcessMessageCode.BK_AUTOMATIC_EXPORT_NOT_SUPPORTED_IMAGE, - language = I18nUtil.getLanguage() - ), null - ) - } - } - else -> { - return if (dispatchType.credentialId.isNullOrBlank()) { - Pair(dispatchType.value, null) - } else Pair( - dispatchType.value, dispatchType.credentialId - ) - } - } - } catch (e: Exception) { - return Pair( - MessageUtil.getMessageByLocale( - messageCode = ProcessMessageCode.BK_ENTER_URL_ADDRESS_IMAGE, - language = I18nUtil.getLanguage() - ), null - ) - } - } - - fun getMatrixFromJob( - matrixControlOption: MatrixControlOption? - ): Strategy? { - if (matrixControlOption == null) { - return null - } - return Strategy( - matrix = matrixControlOption.convertMatrixToYamlConfig() ?: return null, - fastKill = matrixControlOption.fastKill, - maxParallel = matrixControlOption.maxConcurrency - ) - } } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ContainerTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ContainerTransfer.kt index 863fab17e63..7a865600458 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ContainerTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ContainerTransfer.kt @@ -45,21 +45,20 @@ import com.tencent.devops.process.yaml.modelCreate.ModelCommon import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_CONTINUE_WHEN_FAILED import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_JOB_MAX_QUEUE_MINUTES import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_JOB_MAX_RUNNING_MINUTES -import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_JOB_TIME_OUT import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_MUTEX_QUEUE_ENABLE import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_MUTEX_QUEUE_LENGTH import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_MUTEX_TIMEOUT_MINUTES import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault import com.tencent.devops.process.yaml.utils.ModelCreateUtil -import com.tencent.devops.process.yaml.v2.models.IfType -import com.tencent.devops.process.yaml.v2.models.Resources -import com.tencent.devops.process.yaml.v2.models.job.Job -import com.tencent.devops.process.yaml.v2.models.job.JobRunsOnType -import com.tencent.devops.process.yaml.v2.models.job.Mutex -import com.tencent.devops.process.yaml.v2.models.job.PreJob -import com.tencent.devops.process.yaml.v2.models.job.RunsOn -import com.tencent.devops.process.yaml.v2.models.job.Strategy -import com.tencent.devops.process.yaml.v2.models.step.PreStep +import com.tencent.devops.process.yaml.v3.models.IfType +import com.tencent.devops.process.yaml.v3.models.Resources +import com.tencent.devops.process.yaml.v3.models.job.Job +import com.tencent.devops.process.yaml.v3.models.job.JobRunsOnType +import com.tencent.devops.process.yaml.v3.models.job.Mutex +import com.tencent.devops.process.yaml.v3.models.job.PreJob +import com.tencent.devops.process.yaml.v3.models.job.RunsOn +import com.tencent.devops.process.yaml.v3.models.job.Strategy +import com.tencent.devops.process.yaml.v3.models.step.PreStep import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component @@ -149,13 +148,15 @@ class ContainerTransfer @Autowired(required = false) constructor( JobRunCondition.CUSTOM_VARIABLE_MATCH -> ModelCommon.customVariableMatch( job.jobControlOption?.customVariables ) + JobRunCondition.CUSTOM_VARIABLE_MATCH_NOT_RUN -> ModelCommon.customVariableMatchNotRun( job.jobControlOption?.customVariables ) + else -> null }, steps = steps, - timeoutMinutes = job.jobControlOption?.timeout.nullIfDefault(DEFAULT_JOB_TIME_OUT), + timeoutMinutes = job.jobControlOption?.timeout.nullIfDefault(DEFAULT_JOB_MAX_RUNNING_MINUTES), env = null, continueOnError = job.jobControlOption?.continueWhenFailed.nullIfDefault(DEFAULT_CONTINUE_WHEN_FAILED), strategy = if (job.matrixGroupFlag == true) { @@ -183,13 +184,15 @@ class ContainerTransfer @Autowired(required = false) constructor( JobRunCondition.CUSTOM_VARIABLE_MATCH -> ModelCommon.customVariableMatch( job.jobControlOption?.customVariables ) + JobRunCondition.CUSTOM_VARIABLE_MATCH_NOT_RUN -> ModelCommon.customVariableMatchNotRun( job.jobControlOption?.customVariables ) + else -> null }, steps = steps, - timeoutMinutes = job.jobControlOption?.timeout.nullIfDefault(DEFAULT_JOB_TIME_OUT), + timeoutMinutes = job.jobControlOption?.timeout.nullIfDefault(DEFAULT_JOB_MAX_RUNNING_MINUTES), env = null, continueOnError = job.jobControlOption?.continueWhenFailed.nullIfDefault(DEFAULT_CONTINUE_WHEN_FAILED), strategy = if (job.matrixGroupFlag == true) { @@ -288,7 +291,7 @@ class ContainerTransfer @Autowired(required = false) constructor( } } - private fun setUpTimeout(job: Job) = (job.timeoutMinutes ?: DEFAULT_JOB_TIME_OUT) + private fun setUpTimeout(job: Job) = (job.timeoutMinutes ?: DEFAULT_JOB_MAX_RUNNING_MINUTES) private fun getMutexModel(resource: Mutex?): MutexGroup? { if (resource == null) { diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/DispatchTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/DispatchTransfer.kt index 108158947b8..09c0b835f9e 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/DispatchTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/DispatchTransfer.kt @@ -38,6 +38,7 @@ import com.tencent.devops.common.pipeline.type.DispatchType import com.tencent.devops.common.pipeline.type.agent.Credential import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentDockerInfo import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentEnvDispatchType +import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentIDDispatchType import com.tencent.devops.common.pipeline.type.docker.ImageType import com.tencent.devops.common.web.utils.I18nUtil import com.tencent.devops.process.constant.ProcessMessageCode @@ -45,14 +46,14 @@ import com.tencent.devops.process.pojo.BuildTemplateAcrossInfo import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_JOB_PREPARE_TIMEOUT import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault import com.tencent.devops.process.yaml.modelTransfer.inner.TransferCreator -import com.tencent.devops.process.yaml.utils.StreamDispatchUtils -import com.tencent.devops.process.yaml.v2.models.image.Pool -import com.tencent.devops.process.yaml.v2.models.image.PoolImage -import com.tencent.devops.process.yaml.v2.models.image.PoolType -import com.tencent.devops.process.yaml.v2.models.job.Container3 -import com.tencent.devops.process.yaml.v2.models.job.Job -import com.tencent.devops.process.yaml.v2.models.job.JobRunsOnPoolType -import com.tencent.devops.process.yaml.v2.models.job.RunsOn +import com.tencent.devops.process.yaml.v3.models.image.Pool +import com.tencent.devops.process.yaml.v3.models.image.PoolImage +import com.tencent.devops.process.yaml.v3.models.image.PoolType +import com.tencent.devops.process.yaml.v3.models.job.Container3 +import com.tencent.devops.process.yaml.v3.models.job.Job +import com.tencent.devops.process.yaml.v3.models.job.JobRunsOnPoolType +import com.tencent.devops.process.yaml.v3.models.job.RunsOn +import com.tencent.devops.process.yaml.v3.utils.StreamDispatchUtils import org.json.JSONObject import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired @@ -118,7 +119,7 @@ class DispatchTransfer @Autowired(required = false) constructor( container = null, agentSelector = null ) - if (dispatchType is ThirdPartyAgentEnvDispatchType) { + if (dispatchType is ThirdPartyAgentEnvDispatchType || dispatchType is ThirdPartyAgentIDDispatchType) { runsOn.agentSelector = when (job.baseOS) { VMBaseOS.WINDOWS -> listOf("windows") VMBaseOS.LINUX -> listOf("linux") diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt index b27dad96358..863fd8896a8 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ElementTransfer.kt @@ -58,15 +58,15 @@ import com.tencent.devops.process.yaml.modelTransfer.pojo.RunAtomParam import com.tencent.devops.process.yaml.modelTransfer.pojo.WebHookTriggerElementChanger import com.tencent.devops.process.yaml.modelTransfer.pojo.YamlTransferInput import com.tencent.devops.process.yaml.utils.ModelCreateUtil -import com.tencent.devops.process.yaml.v2.models.IfType -import com.tencent.devops.process.yaml.v2.models.job.Job -import com.tencent.devops.process.yaml.v2.models.on.EnableType -import com.tencent.devops.process.yaml.v2.models.on.ManualRule -import com.tencent.devops.process.yaml.v2.models.on.SchedulesRule -import com.tencent.devops.process.yaml.v2.models.on.TriggerOn -import com.tencent.devops.process.yaml.v2.models.step.PreStep -import com.tencent.devops.process.yaml.v2.models.step.Step +import com.tencent.devops.process.yaml.v3.models.IfType import com.tencent.devops.process.yaml.v3.models.TriggerType +import com.tencent.devops.process.yaml.v3.models.job.Job +import com.tencent.devops.process.yaml.v3.models.on.EnableType +import com.tencent.devops.process.yaml.v3.models.on.ManualRule +import com.tencent.devops.process.yaml.v3.models.on.SchedulesRule +import com.tencent.devops.process.yaml.v3.models.on.TriggerOn +import com.tencent.devops.process.yaml.v3.models.step.PreStep +import com.tencent.devops.process.yaml.v3.models.step.Step import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component @@ -86,12 +86,13 @@ class ElementTransfer @Autowired(required = false) constructor( fun yaml2Triggers(yamlInput: YamlTransferInput, elements: MutableList) { yamlInput.yaml.formatTriggerOn(yamlInput.defaultScmType).forEach { when (it.first) { - TriggerType.BASE -> triggerTransfer.yaml2TriggerBase(it.second, elements) + TriggerType.BASE -> triggerTransfer.yaml2TriggerBase(yamlInput, it.second, elements) TriggerType.CODE_GIT -> triggerTransfer.yaml2TriggerGit(it.second, elements) TriggerType.CODE_TGIT -> triggerTransfer.yaml2TriggerTGit(it.second, elements) TriggerType.GITHUB -> triggerTransfer.yaml2TriggerGithub(it.second, elements) TriggerType.CODE_SVN -> triggerTransfer.yaml2TriggerSvn(it.second, elements) TriggerType.CODE_P4 -> triggerTransfer.yaml2TriggerP4(it.second, elements) + TriggerType.CODE_GITLAB -> triggerTransfer.yaml2TriggerGitlab(it.second, elements) } } } @@ -182,7 +183,7 @@ class ElementTransfer @Autowired(required = false) constructor( } if (!gitlabElement.isNullOrEmpty()) { val gitTrigger = triggerTransfer.git2YamlTriggerOn(gitlabElement, projectId) - res.putAll(gitTrigger.associateBy { ScmType.CODE_P4 }) + res.putAll(gitTrigger.associateBy { ScmType.CODE_GITLAB }) } return res } @@ -208,7 +209,35 @@ class ElementTransfer @Autowired(required = false) constructor( agentSelector: String? ): Element { val timeout = setupTimeout(step) + var customVariables: List? = null + val runCondition = when { + step.ifFiled.isNullOrBlank() -> RunCondition.PRE_TASK_SUCCESS + IfType.ALWAYS_UNLESS_CANCELLED.name == (step.ifFiled) -> + RunCondition.PRE_TASK_FAILED_BUT_CANCEL + + IfType.ALWAYS.name == (step.ifFiled) -> + RunCondition.PRE_TASK_FAILED_EVEN_CANCEL + + IfType.FAILURE.name == (step.ifFiled) -> + RunCondition.PRE_TASK_FAILED_ONLY + + else -> { + ModelCommon.revertCustomVariableMatch(step.ifFiled)?.let { + customVariables = it + RunCondition.CUSTOM_VARIABLE_MATCH + } ?: ModelCommon.revertCustomVariableNotMatch(step.ifFiled)?.let { + customVariables = it + RunCondition.CUSTOM_VARIABLE_MATCH_NOT_RUN + } ?: RunCondition.CUSTOM_CONDITION_MATCH + } + } + val customCondition = if (step.ifFiled.isNullOrBlank()) { + step.ifFiled + } else { + ModelCreateUtil.removeIfBrackets(step.ifFiled) + } val additionalOptions = ElementAdditionalOptions( + enable = step.enable ?: true, continueWhenFailed = step.continueOnError ?: VariableDefault.DEFAULT_CONTINUE_WHEN_FAILED, timeout = timeout.toLong(), timeoutVar = timeout.toString(), @@ -216,40 +245,27 @@ class ElementTransfer @Autowired(required = false) constructor( retryCount = step.retryTimes ?: VariableDefault.DEFAULT_RETRY_COUNT, enableCustomEnv = step.env != null, customEnv = getElementEnv(step.env), - runCondition = when { - step.ifFiled.isNullOrBlank() -> RunCondition.PRE_TASK_SUCCESS - IfType.ALWAYS_UNLESS_CANCELLED.name == (step.ifFiled) -> - RunCondition.PRE_TASK_FAILED_BUT_CANCEL - - IfType.ALWAYS.name == (step.ifFiled) -> - RunCondition.PRE_TASK_FAILED_EVEN_CANCEL - - IfType.FAILURE.name == (step.ifFiled) -> - RunCondition.PRE_TASK_FAILED_ONLY - - else -> RunCondition.CUSTOM_CONDITION_MATCH - }, - customCondition = if (step.ifFiled.isNullOrBlank()) { - step.ifFiled - } else { - ModelCreateUtil.removeIfBrackets(step.ifFiled) - }, - manualRetry = false + runCondition = runCondition, + customCondition = if (customVariables == null) customCondition else null, + customVariables = customVariables, + manualRetry = step.manualRetry ?: false ) // bash val element: Element = when { step.run != null -> { - makeRunElement(step, agentSelector, additionalOptions) + makeRunElement(step, agentSelector) } step.checkout != null -> { - creator.transferCheckoutElement(step, additionalOptions) + creator.transferCheckoutElement(step) } else -> { - creator.transferMarketBuildAtomElement(step, additionalOptions) + creator.transferMarketBuildAtomElement(step) } + }.apply { + this.additionalOptions = additionalOptions } return element } @@ -258,13 +274,13 @@ class ElementTransfer @Autowired(required = false) constructor( private fun makeRunElement( step: Step, - agentSelector: String?, - additionalOptions: ElementAdditionalOptions + agentSelector: String? ): Element { val type = step.runAdditionalOptions?.get(RunAtomParam::shell.name) ?: when (agentSelector) { "windows" -> RunAtomParam.ShellType.CMD.shellName + null -> null else -> RunAtomParam.ShellType.BASH.shellName } @@ -275,9 +291,9 @@ class ElementTransfer @Autowired(required = false) constructor( stepId = step.id, scriptType = BuildScriptType.SHELL, script = step.run ?: "", - continueNoneZero = false, - additionalOptions = additionalOptions + continueNoneZero = false ) + RunAtomParam.ShellType.CMD.shellName -> WindowsScriptElement( id = step.taskId, name = step.name ?: "run", @@ -285,6 +301,7 @@ class ElementTransfer @Autowired(required = false) constructor( scriptType = BuildScriptType.BAT, script = step.run ?: "" ) + else -> { val data = mutableMapOf() data["input"] = mapOf( @@ -297,8 +314,7 @@ class ElementTransfer @Autowired(required = false) constructor( stepId = step.id, atomCode = creator.runPlugInAtomCode ?: throw ModelCreateException("runPlugInAtomCode must exist"), version = creator.runPlugInVersion ?: throw ModelCreateException("runPlugInVersion must exist"), - data = data, - additionalOptions = additionalOptions + data = data ) } } @@ -320,15 +336,7 @@ class ElementTransfer @Autowired(required = false) constructor( @Suppress("ComplexMethod") fun element2YamlStep(element: Element, projectId: String): PreStep? { - val retryTimes = if (element.additionalOptions?.retryWhenFailed == true) { - element.additionalOptions?.retryCount - } else null - val timeoutMinutes = element.additionalOptions?.timeout?.toInt() - .nullIfDefault(VariableDefault.DEFAULT_TASK_TIME_OUT) - val continueOnError = element.additionalOptions?.continueWhenFailed - .nullIfDefault(VariableDefault.DEFAULT_CONTINUE_WHEN_FAILED) val uses = "${element.getAtomCode()}@${element.version}" - val env = element.additionalOptions?.customEnv?.associateBy({ it.key ?: "" }) { it.value }?.ifEmpty { null } return when { element is LinuxScriptElement -> { PreStep( @@ -338,15 +346,11 @@ class ElementTransfer @Autowired(required = false) constructor( ifFiled = parseStepIfFiled(element), uses = null, with = null, - timeoutMinutes = timeoutMinutes, - continueOnError = continueOnError, - retryTimes = retryTimes, - env = env, run = element.script, - checkout = null, shell = RunAtomParam.ShellType.BASH.shellName ) } + element is WindowsScriptElement -> { PreStep( name = element.name, @@ -355,15 +359,11 @@ class ElementTransfer @Autowired(required = false) constructor( ifFiled = parseStepIfFiled(element), uses = null, with = null, - timeoutMinutes = timeoutMinutes, - continueOnError = continueOnError, - retryTimes = retryTimes, - env = env, run = element.script, - checkout = null, shell = RunAtomParam.ShellType.CMD.shellName ) } + element.getAtomCode() == "checkout" && element is MarketBuildAtomElement -> { val input = element.data["input"] as Map? ?: emptyMap() val repositoryType = input[CheckoutAtomParam::repositoryType.name].toString().ifBlank { null }?.let { @@ -376,12 +376,15 @@ class ElementTransfer @Autowired(required = false) constructor( repositoryType == CheckoutAtomParam.CheckoutRepositoryType.ID && repositoryHashId != null -> { transferCache.getGitRepository(projectId, RepositoryType.ID, repositoryHashId)?.url } + repositoryType == CheckoutAtomParam.CheckoutRepositoryType.NAME && repositoryName != null -> { transferCache.getGitRepository(projectId, RepositoryType.NAME, repositoryName)?.url } + repositoryType == CheckoutAtomParam.CheckoutRepositoryType.URL && repositoryUrl != null -> { repositoryUrl } + else -> null } ?: "self" // todo 等待checkout插件新增self参数 @@ -392,15 +395,10 @@ class ElementTransfer @Autowired(required = false) constructor( ifFiled = parseStepIfFiled(element), uses = null, with = simplifyParams(uses, input).ifEmpty { null }, - timeoutMinutes = timeoutMinutes, - continueOnError = continueOnError, - retryTimes = retryTimes, - env = env, - run = null, - checkout = checkout, - shell = null + checkout = checkout ) } + element.getAtomCode() == "run" && element is MarketBuildAtomElement -> { val input = element.data["input"] as Map? ?: emptyMap() PreStep( @@ -415,15 +413,11 @@ class ElementTransfer @Autowired(required = false) constructor( it.key == RunAtomParam::shell.name || it.key == RunAtomParam::script.name } ).ifEmpty { null }, - timeoutMinutes = timeoutMinutes, - continueOnError = continueOnError, - retryTimes = retryTimes, - env = env, run = input[RunAtomParam::script.name]?.toString(), - checkout = null, shell = input[RunAtomParam::shell.name]?.toString() ) } + element is MarketBuildLessAtomElement -> { val input = element.data["input"] as Map? ?: emptyMap() PreStep( @@ -432,16 +426,10 @@ class ElementTransfer @Autowired(required = false) constructor( // 插件上的 ifFiled = parseStepIfFiled(element), uses = uses, - with = simplifyParams(uses, input).ifEmpty { null }, - timeoutMinutes = timeoutMinutes, - continueOnError = continueOnError, - retryTimes = retryTimes, - env = env, - run = null, - checkout = null, - shell = null + with = simplifyParams(uses, input).ifEmpty { null } ) } + element is MarketBuildAtomElement -> { val input = element.data["input"] as Map? ?: emptyMap() PreStep( @@ -450,17 +438,23 @@ class ElementTransfer @Autowired(required = false) constructor( // 插件上的 ifFiled = parseStepIfFiled(element), uses = uses, - with = simplifyParams(uses, input).ifEmpty { null }, - timeoutMinutes = timeoutMinutes, - continueOnError = continueOnError, - retryTimes = retryTimes, - env = env, - run = null, - checkout = null, - shell = null + with = simplifyParams(uses, input).ifEmpty { null } ) } + else -> null + }?.apply { + this.enable = element.isElementEnable().nullIfDefault(true) + this.timeoutMinutes = element.additionalOptions?.timeout?.toInt() + .nullIfDefault(VariableDefault.DEFAULT_TASK_TIME_OUT) + this.continueOnError = element.additionalOptions?.continueWhenFailed + .nullIfDefault(VariableDefault.DEFAULT_CONTINUE_WHEN_FAILED) + this.retryTimes = if (element.additionalOptions?.retryWhenFailed == true) { + element.additionalOptions?.retryCount + } else null + this.manualRetry = element.additionalOptions?.manualRetry?.nullIfDefault(false) + this.env = element.additionalOptions?.customEnv?.associateBy({ it.key ?: "" }) { it.value } + ?.ifEmpty { null } } } @@ -472,15 +466,20 @@ class ElementTransfer @Autowired(required = false) constructor( RunCondition.CUSTOM_VARIABLE_MATCH -> ModelCommon.customVariableMatch( step.additionalOptions?.customVariables ) + RunCondition.CUSTOM_VARIABLE_MATCH_NOT_RUN -> ModelCommon.customVariableMatchNotRun( step.additionalOptions?.customVariables ) + RunCondition.PRE_TASK_FAILED_BUT_CANCEL -> IfType.ALWAYS_UNLESS_CANCELLED.name + RunCondition.PRE_TASK_FAILED_EVEN_CANCEL -> IfType.ALWAYS.name + RunCondition.PRE_TASK_FAILED_ONLY -> IfType.FAILURE.name + else -> null } } @@ -512,6 +511,7 @@ class ElementTransfer @Autowired(required = false) constructor( val nameAndValueList = mutableListOf() env.forEach { + // todo 001 nameAndValueList.add( NameAndValue( key = it.key, diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt index 30dc784248d..89f7015549e 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/ModelTransfer.kt @@ -38,19 +38,11 @@ import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefau import com.tencent.devops.process.yaml.modelTransfer.pojo.ModelTransferInput import com.tencent.devops.process.yaml.modelTransfer.pojo.YamlTransferInput import com.tencent.devops.process.yaml.pojo.YamlVersion -import com.tencent.devops.process.yaml.v2.models.Concurrency -import com.tencent.devops.process.yaml.v2.models.GitNotices -import com.tencent.devops.process.yaml.v2.models.IPreTemplateScriptBuildYaml -import com.tencent.devops.process.yaml.v2.models.IfType -import com.tencent.devops.process.yaml.v2.models.Notices -import com.tencent.devops.process.yaml.v2.models.PacNotices -import com.tencent.devops.process.yaml.v2.models.PreTemplateScriptBuildYaml -import com.tencent.devops.process.yaml.v2.models.Variable -import com.tencent.devops.process.yaml.v2.models.on.IPreTriggerOn -import com.tencent.devops.process.yaml.v2.models.on.PreTriggerOn -import com.tencent.devops.process.yaml.v2.models.stage.PreStage -import com.tencent.devops.process.yaml.v3.models.PreTemplateScriptBuildYamlV3 +import com.tencent.devops.process.yaml.v3.models.* +import com.tencent.devops.process.yaml.v3.models.on.IPreTriggerOn +import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOn import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 +import com.tencent.devops.process.yaml.v3.models.stage.PreStage import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component @@ -59,7 +51,8 @@ import org.springframework.stereotype.Component class ModelTransfer @Autowired constructor( val client: Client, val modelStage: StageTransfer, - val modelElement: ElementTransfer, + val elementTransfer: ElementTransfer, + val variableTransfer: VariableTransfer, val transferCache: TransferCacheService ) { @@ -68,7 +61,7 @@ class ModelTransfer @Autowired constructor( } fun yaml2Labels(yamlInput: YamlTransferInput): List { - return preparePipelineLabels(yamlInput.projectCode, yamlInput.yaml) + return preparePipelineLabels(yamlInput.userId, yamlInput.projectCode, yamlInput.yaml) } fun yaml2Setting(yamlInput: YamlTransferInput): PipelineSetting { @@ -130,7 +123,6 @@ class ModelTransfer @Autowired constructor( // 蓝盾引擎会将stageId从1开始顺序强制重写,因此在生成model时保持一致 var stageIndex = 1 - // todo 需要trigger on stageList.add(modelStage.yaml2TriggerStage(yamlInput, stageIndex++)) // 其他的stage @@ -173,9 +165,9 @@ class ModelTransfer @Autowired constructor( val ymlStage = modelStage.model2YamlStage(stage, modelInput.setting.projectId) stages.add(ymlStage) } - val label = prepareYamlLabels(modelInput.setting).ifEmpty { null } + val label = prepareYamlLabels(modelInput.userId, modelInput.setting).ifEmpty { null } val triggerOn = makeTriggerOn(modelInput) - val variables = makeVariableFromModel(modelInput.model) + val variables = variableTransfer.makeVariableFromModel(modelInput.model) val lastStage = modelInput.model.stages.last() val finally = if (lastStage.finally) modelStage.model2YamlStage(lastStage, modelInput.setting.projectId).jobs else null @@ -195,6 +187,7 @@ class ModelTransfer @Autowired constructor( finally = finally, concurrency = concurrency ) + YamlVersion.Version.V3_0 -> PreTemplateScriptBuildYamlV3( version = "v3.0", name = modelInput.model.name, @@ -228,13 +221,13 @@ class ModelTransfer @Autowired constructor( private fun makeNoticesV3(setting: PipelineSetting): List { val res = mutableListOf() - setting.successSubscriptionList?.forEach { + setting.successSubscriptionList?.plus(setting.successSubscription)?.forEach { if (it.types.isNotEmpty()) { val notice = PacNotices(it, IfType.SUCCESS.name) res.add(prepareYamlGroups(setting.projectId, notice)) } } - setting.failSubscriptionList?.forEach { + setting.failSubscriptionList?.plus(setting.failSubscription)?.forEach { if (it.types.isNotEmpty()) { val notice = PacNotices(it, IfType.FAILURE.name) res.add(prepareYamlGroups(setting.projectId, notice)) @@ -259,8 +252,8 @@ class ModelTransfer @Autowired constructor( private fun makeTriggerOn(modelInput: ModelTransferInput): List { val triggers = (modelInput.model.stages[0].containers[0] as TriggerContainer).elements - val baseTrigger = modelElement.baseTriggers2yaml(triggers)?.toPre(modelInput.version) - val scmTrigger = modelElement.scmTriggers2Yaml(triggers, modelInput.setting.projectId) + val baseTrigger = elementTransfer.baseTriggers2yaml(triggers)?.toPre(modelInput.version) + val scmTrigger = elementTransfer.scmTriggers2Yaml(triggers, modelInput.setting.projectId) when (modelInput.version) { YamlVersion.Version.V2_0 -> { // 融合默认git触发器 + 基础触发器 @@ -281,6 +274,7 @@ class ModelTransfer @Autowired constructor( // 不带触发器 return emptyList() } + YamlVersion.Version.V3_0 -> { val trigger = mutableListOf() val triggerV3 = scmTrigger.map { on -> @@ -311,33 +305,16 @@ class ModelTransfer @Autowired constructor( } } - private fun makeVariableFromModel(model: Model): Map? { - val result = mutableMapOf() - (model.stages[0].containers[0] as TriggerContainer).params.forEach { - // todo 启动参数需要更详细的解析 - result[it.id] = Variable( - it.defaultValue.toString(), - readonly = it.readOnly.nullIfDefault(false), - allowModifyAtStartup = it.required.nullIfDefault(true), - valueNotEmpty = it.valueNotEmpty.nullIfDefault(false) - ) - } - return if (result.isEmpty()) { - null - } else { - result - } - } - @Suppress("NestedBlockDepth") private fun preparePipelineLabels( + userId: String, projectCode: String, yaml: IPreTemplateScriptBuildYaml ): List { val ymlLabel = yaml.label ?: return emptyList() val labels = mutableListOf() - transferCache.getPipelineLabel(projectCode)?.forEach { group -> + transferCache.getPipelineLabel(userId, projectCode)?.forEach { group -> group.labels.forEach { if (ymlLabel.contains(it.name)) labels.add(it.id) } @@ -346,11 +323,12 @@ class ModelTransfer @Autowired constructor( } private fun prepareYamlLabels( + userId: String, pipelineSetting: PipelineSetting ): List { val labels = mutableListOf() - transferCache.getPipelineLabel(pipelineSetting.projectId)?.forEach { group -> + transferCache.getPipelineLabel(userId, pipelineSetting.projectId)?.forEach { group -> group.labels.forEach { if (pipelineSetting.labels.contains(it.id)) labels.add(it.name) } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt index 2f1e053de98..7970f6883ce 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/StageTransfer.kt @@ -51,27 +51,24 @@ import com.tencent.devops.process.yaml.modelCreate.ModelCommon import com.tencent.devops.process.yaml.modelCreate.ModelCreateException import com.tencent.devops.process.yaml.modelTransfer.pojo.YamlTransferInput import com.tencent.devops.process.yaml.utils.ModelCreateUtil -import com.tencent.devops.process.yaml.v2.models.Variable -import com.tencent.devops.process.yaml.v2.models.job.Job -import com.tencent.devops.process.yaml.v2.models.job.JobRunsOnType -import com.tencent.devops.process.yaml.v2.models.stage.PreStage -import com.tencent.devops.process.yaml.v2.models.stage.StageLabel -import com.tencent.devops.process.yaml.v2.stageCheck.PreFlow -import com.tencent.devops.process.yaml.v2.stageCheck.PreStageCheck -import com.tencent.devops.process.yaml.v2.stageCheck.PreStageReviews -import com.tencent.devops.process.yaml.v2.stageCheck.ReviewVariable -import com.tencent.devops.process.yaml.v2.stageCheck.StageCheck +import com.tencent.devops.process.yaml.v3.models.Variable +import com.tencent.devops.process.yaml.v3.models.job.Job +import com.tencent.devops.process.yaml.v3.models.job.JobRunsOnType +import com.tencent.devops.process.yaml.v3.models.stage.PreStage +import com.tencent.devops.process.yaml.v3.models.stage.StageLabel +import com.tencent.devops.process.yaml.v3.stageCheck.* import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component -import com.tencent.devops.process.yaml.v2.models.stage.Stage as StreamV2Stage +import com.tencent.devops.process.yaml.v3.models.stage.Stage as StreamV2Stage @Component class StageTransfer @Autowired(required = false) constructor( val client: Client, val objectMapper: ObjectMapper, - val modelContainer: ContainerTransfer, - val modelElement: ElementTransfer + val containerTransfer: ContainerTransfer, + val elementTransfer: ElementTransfer, + val variableTransfer: VariableTransfer ) { companion object { private val logger = LoggerFactory.getLogger(StageTransfer::class.java) @@ -81,7 +78,7 @@ class StageTransfer @Autowired(required = false) constructor( fun yaml2TriggerStage(yamlInput: YamlTransferInput, stageIndex: Int): Stage { // 第一个stage,触发类 val triggerElementList = mutableListOf() - modelElement.yaml2Triggers(yamlInput, triggerElementList) + elementTransfer.yaml2Triggers(yamlInput, triggerElementList) val triggerContainer = TriggerContainer( id = "0", @@ -91,7 +88,7 @@ class StageTransfer @Autowired(required = false) constructor( startEpoch = null, systemElapsed = null, elementElapsed = null, - params = getBuildFormPropertyFromYmlVariable(yamlInput.yaml.formatVariables()) + params = variableTransfer.makeVariableFromYaml(yamlInput.yaml.formatVariables()) ) val stageId = VMUtils.genStageId(stageIndex) @@ -128,13 +125,13 @@ class StageTransfer @Autowired(required = false) constructor( val containerList = mutableListOf() stage.jobs.forEachIndexed { jobIndex, job -> - val elementList = modelElement.yaml2Elements( + val elementList = elementTransfer.yaml2Elements( job = job, yamlInput = yamlInput ) if (job.runsOn.poolName == JobRunsOnType.AGENT_LESS.type) { - modelContainer.addNormalContainer( + containerTransfer.addNormalContainer( job = job, elementList = elementList, containerList = containerList, @@ -142,7 +139,7 @@ class StageTransfer @Autowired(required = false) constructor( finalStage = finalStage ) } else { - modelContainer.addVmBuildContainer( + containerTransfer.addVmBuildContainer( job = job, elementList = elementList, containerList = containerList, @@ -191,11 +188,11 @@ class StageTransfer @Autowired(required = false) constructor( ): PreStage { val jobs = stage.containers.associate { job -> - val steps = modelElement.model2YamlSteps(job, projectId) + val steps = elementTransfer.model2YamlSteps(job, projectId) (job.jobId ?: "job_${job.id}") to when (job.getClassType()) { - NormalContainer.classType -> modelContainer.addYamlNormalContainer(job as NormalContainer, steps) - VMBuildContainer.classType -> modelContainer.addYamlVMBuildContainer(job as VMBuildContainer, steps) + NormalContainer.classType -> containerTransfer.addYamlNormalContainer(job as NormalContainer, steps) + VMBuildContainer.classType -> containerTransfer.addYamlVMBuildContainer(job as VMBuildContainer, steps) else -> throw ModelCreateException("unknown classType:(${job.getClassType()})") } } @@ -207,9 +204,11 @@ class StageTransfer @Autowired(required = false) constructor( StageRunCondition.CUSTOM_VARIABLE_MATCH -> ModelCommon.customVariableMatch( stage.stageControlOption?.customVariables ) + StageRunCondition.CUSTOM_VARIABLE_MATCH_NOT_RUN -> ModelCommon.customVariableMatchNotRun( stage.stageControlOption?.customVariables ) + else -> null }, fastKill = if (stage.fastKill == true) true else null, diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferCacheService.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferCacheService.kt index f034e77763e..ed9291ad9ea 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferCacheService.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferCacheService.kt @@ -2,13 +2,13 @@ package com.tencent.devops.process.yaml.modelTransfer import com.github.benmanes.caffeine.cache.Caffeine import com.tencent.devops.auth.api.service.ServiceProjectAuthResource -import com.tencent.devops.common.api.auth.AUTH_HEADER_USER_ID_DEFAULT_VALUE import com.tencent.devops.common.api.enums.RepositoryConfig import com.tencent.devops.common.api.enums.RepositoryType import com.tencent.devops.common.auth.api.pojo.BkAuthGroupAndUserList import com.tencent.devops.common.client.Client import com.tencent.devops.common.client.ClientTokenService import com.tencent.devops.process.api.service.ServicePipelineGroupResource +import com.tencent.devops.process.api.service.ServicePipelineResource import com.tencent.devops.process.pojo.classify.PipelineGroup import com.tencent.devops.repository.api.ServiceRepositoryResource import com.tencent.devops.repository.pojo.Repository @@ -26,7 +26,6 @@ class TransferCacheService @Autowired constructor( private val client: Client, private val tokenService: ClientTokenService ) { - companion object { private val logger = LoggerFactory.getLogger(TransferCacheService::class.java) } @@ -41,7 +40,6 @@ class TransferCacheService @Autowired constructor( .getAtomsDefaultValue(ElementThirdPartySearchParam(atomCode, version)).data }.onFailure { logger.warn("get $key default value error.") }.getOrNull() ?: emptyMap() } - private val storeImageInfoCache = Caffeine.newBuilder() .maximumSize(1000) .expireAfterWrite(1, TimeUnit.DAYS) @@ -55,7 +53,6 @@ class TransferCacheService @Autowired constructor( ).data }.onFailure { logger.warn("get $key ImageInfoByCodeAndVersion value error.") }.getOrNull() } - private val projectGroupAndUsersCache = Caffeine.newBuilder() .maximumSize(1000) .expireAfterWrite(10, TimeUnit.MINUTES) @@ -68,18 +65,17 @@ class TransferCacheService @Autowired constructor( ).data }.onFailure { logger.warn("get $key ProjectGroupAndUserList error.") }.getOrNull() } - private val pipelineLabel = Caffeine.newBuilder() .maximumSize(1000) .expireAfterWrite(10, TimeUnit.MINUTES) - .build?> { projectId -> + .build?> { key -> kotlin.runCatching { + val (userId, projectId) = key.split("@@") client.get(ServicePipelineGroupResource::class) - .getGroups(AUTH_HEADER_USER_ID_DEFAULT_VALUE, projectId) + .getGroups(userId, projectId) .data - }.onFailure { logger.warn("get $projectId default value error.") }.getOrNull() + }.onFailure { logger.warn("get $key pipeline label value error.") }.getOrNull() } - private val gitRepository = Caffeine.newBuilder() .maximumSize(1000) .expireAfterWrite(10, TimeUnit.MINUTES) @@ -95,7 +91,18 @@ class TransferCacheService @Autowired constructor( client.get(ServiceRepositoryResource::class) .get(projectId, config.getURLEncodeRepositoryId(), config.repositoryType) .data - }.onFailure { logger.warn("get $key value error.") }.getOrNull() + }.onFailure { logger.warn("get $key git repository error.") }.getOrNull() + } + private val pipelineRemoteToken = Caffeine.newBuilder() + .maximumSize(1000) + .expireAfterWrite(10, TimeUnit.MINUTES) + .build { key -> + kotlin.runCatching { + val (userId, projectId, pipelineId) = key.split("@@") + client.get(ServicePipelineResource::class) + .generateRemoteToken(userId, projectId, pipelineId) + .data?.token + }.onFailure { logger.warn("get $key remote token value error.") }.getOrNull() } fun getAtomDefaultValue(key: String) = atomDefaultValueCache.get(key) ?: emptyMap() @@ -105,8 +112,11 @@ class TransferCacheService @Autowired constructor( fun getProjectGroupAndUsers(projectId: String) = projectGroupAndUsersCache.get(projectId) - fun getPipelineLabel(projectId: String) = pipelineLabel.get(projectId) + fun getPipelineLabel(userId: String, projectId: String) = pipelineLabel.get("$userId@@$projectId") fun getGitRepository(projectId: String, repositoryType: RepositoryType, value: String) = gitRepository.get("$projectId@@${repositoryType.name}@@$value") + + fun getPipelineRemoteToken(userId: String, projectId: String, pipelineId: String) = + pipelineRemoteToken.get("$userId@@$projectId@@$pipelineId") } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferMapper.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferMapper.kt index 04a80e3822b..5da6d8e8faa 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferMapper.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TransferMapper.kt @@ -17,7 +17,7 @@ import com.github.difflib.patch.DeltaType import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.api.util.ReflectUtil import com.tencent.devops.process.pojo.transfer.TransferMark -import com.tencent.devops.process.yaml.v2.models.YAME_META_DATA_JSON_FILTER +import com.tencent.devops.process.yaml.v3.models.YAME_META_DATA_JSON_FILTER import org.json.JSONArray import org.json.JSONObject import org.slf4j.LoggerFactory diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt index 90d75a95c17..a98e8fc1d27 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/TriggerTransfer.kt @@ -32,31 +32,14 @@ import com.tencent.devops.common.client.Client import com.tencent.devops.common.pipeline.pojo.element.Element import com.tencent.devops.common.pipeline.pojo.element.ElementAdditionalOptions import com.tencent.devops.common.pipeline.pojo.element.RunCondition -import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGitWebHookTriggerElement -import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGithubWebHookTriggerElement -import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeP4WebHookTriggerData -import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeP4WebHookTriggerElement -import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeP4WebHookTriggerInput -import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeSVNWebHookTriggerElement -import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeTGitWebHookTriggerData -import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeTGitWebHookTriggerElement -import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeTGitWebHookTriggerInput -import com.tencent.devops.common.pipeline.pojo.element.trigger.ManualTriggerElement -import com.tencent.devops.common.pipeline.pojo.element.trigger.RemoteTriggerElement -import com.tencent.devops.common.pipeline.pojo.element.trigger.TimerTriggerElement +import com.tencent.devops.common.pipeline.pojo.element.trigger.* import com.tencent.devops.common.pipeline.pojo.element.trigger.enums.CodeEventType import com.tencent.devops.common.pipeline.pojo.element.trigger.enums.PathFilterType import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault import com.tencent.devops.process.yaml.modelTransfer.inner.TransferCreator import com.tencent.devops.process.yaml.modelTransfer.pojo.WebHookTriggerElementChanger -import com.tencent.devops.process.yaml.v2.models.on.EnableType -import com.tencent.devops.process.yaml.v2.models.on.IssueRule -import com.tencent.devops.process.yaml.v2.models.on.MrRule -import com.tencent.devops.process.yaml.v2.models.on.NoteRule -import com.tencent.devops.process.yaml.v2.models.on.PushRule -import com.tencent.devops.process.yaml.v2.models.on.ReviewRule -import com.tencent.devops.process.yaml.v2.models.on.TagRule -import com.tencent.devops.process.yaml.v2.models.on.TriggerOn +import com.tencent.devops.process.yaml.modelTransfer.pojo.YamlTransferInput +import com.tencent.devops.process.yaml.v3.models.on.* import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Component @@ -203,6 +186,7 @@ class TriggerTransfer @Autowired(required = false) constructor( repoHashId = name, repoName = transferCache.getGitRepository(projectId, RepositoryType.ID, name)?.aliasName ) + git.repositoryName -> TriggerOn(repoName = name) else -> TriggerOn() } @@ -220,6 +204,7 @@ class TriggerTransfer @Autowired(required = false) constructor( // todo action action = null ) + CodeEventType.TAG_PUSH -> nowExist.tag = TagRule( enable = git.enable.nullIfDefault(true), tags = git.tagName?.disjoin(), @@ -228,6 +213,7 @@ class TriggerTransfer @Autowired(required = false) constructor( users = git.includeUsers, usersIgnore = git.excludeUsers ) + CodeEventType.MERGE_REQUEST -> nowExist.mr = MrRule( enable = git.enable.nullIfDefault(true), targetBranches = git.branchName?.disjoin(), @@ -245,15 +231,18 @@ class TriggerTransfer @Autowired(required = false) constructor( // todo action action = null ) + CodeEventType.REVIEW -> nowExist.review = ReviewRule( enable = git.enable.nullIfDefault(true), states = git.includeCrState, types = git.includeCrTypes ) + CodeEventType.ISSUES -> nowExist.issue = IssueRule( enable = git.enable.nullIfDefault(true), action = git.includeIssueAction ) + CodeEventType.NOTE -> nowExist.note = NoteRule( enable = git.enable.nullIfDefault(true), types = git.includeNoteTypes?.map { @@ -265,6 +254,7 @@ class TriggerTransfer @Autowired(required = false) constructor( } } ) + CodeEventType.POST_COMMIT -> nowExist.push = PushRule( enable = git.enable.nullIfDefault(true), branches = null, @@ -274,6 +264,7 @@ class TriggerTransfer @Autowired(required = false) constructor( usersIgnore = git.excludeUsers, pathFilterType = git.pathFilterType?.name ) + CodeEventType.CHANGE_COMMIT -> nowExist.push = PushRule( enable = git.enable.nullIfDefault(true), branches = null, @@ -573,13 +564,13 @@ class TriggerTransfer @Autowired(required = false) constructor( repositoryName = triggerOn.repoName ) ) - ).checkTriggerElementEnable(push.enable) + ).checkTriggerElementEnable(push.enable).apply { version = "2.*" } ) } } @Suppress("ComplexMethod") - fun yaml2TriggerBase(triggerOn: TriggerOn, elementQueue: MutableList) { + fun yaml2TriggerBase(yamlInput: YamlTransferInput, triggerOn: TriggerOn, elementQueue: MutableList) { triggerOn.manual?.let { manual -> elementQueue.add( ManualTriggerElement( @@ -589,25 +580,94 @@ class TriggerTransfer @Autowired(required = false) constructor( ) ) } - triggerOn.remote?.let { remote -> - elementQueue.add( - RemoteTriggerElement( - // todo, - ).checkTriggerElementEnable(remote == EnableType.TRUE.value) - ) - } triggerOn.schedules?.let { remote -> remote.forEach { timer -> elementQueue.add( TimerTriggerElement( - newExpression = timer.cron?.disjoin(), + newExpression = timer.cron?.let { listOf(it) }, advanceExpression = timer.advanceCron, noScm = timer.always != true ).checkTriggerElementEnable(timer.enable) ) } } + + triggerOn.remote?.let { remote -> + elementQueue.add( + RemoteTriggerElement( + remoteToken = yamlInput.pipelineInfo?.pipelineId?.let { + transferCache.getPipelineRemoteToken( + userId = yamlInput.userId, + projectId = yamlInput.projectCode, + pipelineId = it + ) + } ?: "" + ).checkTriggerElementEnable(remote == EnableType.TRUE.value) + ) + } + } + + @Suppress("ComplexMethod") + fun yaml2TriggerGitlab(triggerOn: TriggerOn, elementQueue: MutableList) { + triggerOn.push?.let { push -> + elementQueue.add( + CodeGitlabWebHookTriggerElement( + branchName = push.branches.nonEmptyOrNull()?.join(), + excludeBranchName = push.branchesIgnore.nonEmptyOrNull()?.join(), + includePaths = push.paths.nonEmptyOrNull()?.join(), + excludePaths = push.pathsIgnore.nonEmptyOrNull()?.join(), + includeUsers = push.users, + excludeUsers = push.usersIgnore, + pathFilterType = push.pathFilterType?.let { PathFilterType.valueOf(it) }, + eventType = CodeEventType.PUSH, + // todo action + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.repoName + ).checkTriggerElementEnable(push.enable) + ) + } + + triggerOn.tag?.let { tag -> + elementQueue.add( + CodeGitlabWebHookTriggerElement( + tagName = tag.tags.nonEmptyOrNull()?.join(), + excludeTagName = tag.tagsIgnore.nonEmptyOrNull()?.join(), + includeUsers = tag.users, + excludeUsers = tag.usersIgnore, + eventType = CodeEventType.TAG_PUSH, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.repoName + ).checkTriggerElementEnable(tag.enable) + ) + } + + triggerOn.mr?.let { mr -> + elementQueue.add( + CodeGitlabWebHookTriggerElement( + branchName = mr.targetBranches.nonEmptyOrNull()?.join(), + excludeBranchName = mr.targetBranchesIgnore.nonEmptyOrNull()?.join(), + includeSourceBranchName = mr.sourceBranches.nonEmptyOrNull()?.join(), + excludeSourceBranchName = mr.sourceBranchesIgnore.nonEmptyOrNull()?.join(), + includePaths = mr.paths.nonEmptyOrNull()?.join(), + excludePaths = mr.pathsIgnore.nonEmptyOrNull()?.join(), + includeUsers = mr.users, + excludeUsers = mr.usersIgnore, + block = mr.block, + pathFilterType = mr.pathFilterType?.let { PathFilterType.valueOf(it) }, + // todo action + eventType = CodeEventType.MERGE_REQUEST, + repositoryType = if (triggerOn.repoHashId.isNullOrBlank()) + RepositoryType.NAME else RepositoryType.ID, + repositoryHashId = triggerOn.repoHashId, + repositoryName = triggerOn.repoName + ).checkTriggerElementEnable(mr.enable) + ) + } } private fun Element.checkTriggerElementEnable(enabled: Boolean?): Element { diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/VariableDefault.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/VariableDefault.kt index 602289f3bc7..b00233288ba 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/VariableDefault.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/VariableDefault.kt @@ -1,21 +1,20 @@ package com.tencent.devops.process.yaml.modelTransfer -import com.tencent.devops.process.yaml.v2.models.on.ManualRule +import com.tencent.devops.process.yaml.v3.models.on.ManualRule object VariableDefault { const val DEFAULT_TASK_TIME_OUT = 900 - const val DEFAULT_JOB_TIME_OUT = 900 const val DEFAULT_WAIT_QUEUE_TIME_MINUTE = 480 const val DEFAULT_RETRY_COUNT = 0 const val DEFAULT_CONTINUE_WHEN_FAILED = false const val DEFAULT_PIPELINE_SETTING_MAX_QUEUE_SIZE = 10 const val DEFAULT_JOB_PREPARE_TIMEOUT = 10 const val DEFAULT_JOB_MAX_QUEUE_MINUTES = 60 - const val DEFAULT_JOB_MAX_RUNNING_MINUTES = 60 + const val DEFAULT_JOB_MAX_RUNNING_MINUTES = 900 const val DEFAULT_MUTEX_QUEUE_LENGTH = 5 const val DEFAULT_MUTEX_TIMEOUT_MINUTES = 900 const val DEFAULT_MUTEX_QUEUE_ENABLE = false - val DEFAULT_MANUAL_RULE = ManualRule(canElementSkip = true, useLatestParameters = false) + val DEFAULT_MANUAL_RULE = ManualRule(canElementSkip = null, useLatestParameters = null) fun T.nullIfDefault(value: T) = if (this == value) null else this } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/VariableTransfer.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/VariableTransfer.kt new file mode 100644 index 00000000000..4376d51fd75 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/VariableTransfer.kt @@ -0,0 +1,179 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.modelTransfer + +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.common.pipeline.Model +import com.tencent.devops.common.pipeline.container.TriggerContainer +import com.tencent.devops.common.pipeline.enums.BuildFormPropertyType +import com.tencent.devops.common.pipeline.pojo.BuildFormProperty +import com.tencent.devops.common.pipeline.pojo.BuildFormValue +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault +import com.tencent.devops.process.yaml.v3.models.Variable +import com.tencent.devops.process.yaml.v3.models.VariablePropOption +import com.tencent.devops.process.yaml.v3.models.VariablePropType +import com.tencent.devops.process.yaml.v3.models.VariableProps +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.stereotype.Component + +@Component +class VariableTransfer @Autowired constructor() { + + companion object { + private val logger = LoggerFactory.getLogger(VariableTransfer::class.java) + } + + fun makeVariableFromModel(model: Model): Map? { + val result = mutableMapOf() + (model.stages[0].containers[0] as TriggerContainer).params.forEach { + val props = when { + // 不带 + it.type == BuildFormPropertyType.STRING && it.desc.isNullOrEmpty() -> null + it.type == BuildFormPropertyType.STRING -> VariableProps( + type = VariablePropType.VUEX_INPUT.value, + description = it.desc.nullIfDefault("") + ) + + it.type == BuildFormPropertyType.TEXTAREA -> VariableProps( + type = VariablePropType.VUEX_TEXTAREA.value, + description = it.desc.nullIfDefault("") + ) + + it.type == BuildFormPropertyType.ENUM -> VariableProps( + type = VariablePropType.SELECTOR.value, + description = it.desc.nullIfDefault(""), + options = it.options?.map { form -> + VariablePropOption(id = form.value, label = form.key) + }, + payload = it.payload + ) + + it.type == BuildFormPropertyType.DATE -> null // not use + it.type == BuildFormPropertyType.LONG -> null // not use + it.type == BuildFormPropertyType.BOOLEAN -> VariableProps( + type = VariablePropType.BOOLEAN.value, + description = it.desc.nullIfDefault("") + ) + + it.type == BuildFormPropertyType.SVN_TAG -> null // not use + it.type == BuildFormPropertyType.GIT_REF -> VariableProps( + type = VariablePropType.GIT_REF.value, + repoHashId = it.repoHashId, + description = it.desc.nullIfDefault("") + ) + + it.type == BuildFormPropertyType.MULTIPLE -> VariableProps( + type = VariablePropType.CHECKBOX.value, + description = it.desc.nullIfDefault(""), + options = it.options?.map { form -> + VariablePropOption(id = form.value, label = form.key) + }, + payload = it.payload + ) + + it.type == BuildFormPropertyType.CODE_LIB -> VariableProps( + type = VariablePropType.CODE_LIB.value, + scmType = it.scmType?.alis, + description = it.desc.nullIfDefault("") + ) + + it.type == BuildFormPropertyType.CONTAINER_TYPE -> VariableProps( + type = VariablePropType.CONTAINER_TYPE.value, + containerType = it.containerType, + description = it.desc.nullIfDefault("") + ) // 构建机类型(公共构建机,第三方构建机,PCG构建机等) + it.type == BuildFormPropertyType.ARTIFACTORY -> VariableProps( + type = VariablePropType.ARTIFACTORY.value, + glob = it.glob, + properties = it.properties?.ifEmpty { null }, + description = it.desc.nullIfDefault("") + ) // 版本仓库 + it.type == BuildFormPropertyType.SUB_PIPELINE -> VariableProps( + type = VariablePropType.SUB_PIPELINE.value, + description = it.desc.nullIfDefault("") + ) // 子流水线 + it.type == BuildFormPropertyType.CUSTOM_FILE -> VariableProps( + type = VariablePropType.CUSTOM_FILE.value, + description = it.desc.nullIfDefault("") + ) // 自定义仓库文件 + it.type == BuildFormPropertyType.PASSWORD -> null // not use + it.type == BuildFormPropertyType.TEMPORARY -> null // not use + else -> null + } + result[it.id] = Variable( + it.defaultValue.toString(), + readonly = it.readOnly.nullIfDefault(false), + allowModifyAtStartup = it.required.nullIfDefault(true), + valueNotEmpty = it.valueNotEmpty.nullIfDefault(false), + props = props + ) + } + return if (result.isEmpty()) { + null + } else { + result + } + } + + fun makeVariableFromYaml( + variables: Map? + ): List { + if (variables.isNullOrEmpty()) { + return emptyList() + } + val buildFormProperties = mutableListOf() + variables.forEach { (key, variable) -> + buildFormProperties.add( + BuildFormProperty( + id = key, + required = variable.allowModifyAtStartup ?: true, + type = VariablePropType.findType(variable.props?.type)?.toBuildFormPropertyType() + ?: BuildFormPropertyType.STRING, + defaultValue = variable.value ?: "", + options = variable.props?.options?.map { + BuildFormValue( + key = it.label ?: it.id.toString(), + value = it.id.toString() + ) + }, + desc = variable.props?.description, + repoHashId = variable.props?.repoHashId, + relativePath = null, + scmType = ScmType.parse(variable.props?.scmType), + containerType = variable.props?.containerType, + glob = variable.props?.glob, + properties = variable.props?.properties, + readOnly = variable.readonly, + valueNotEmpty = variable.valueNotEmpty + ) + ) + } + return buildFormProperties + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreator.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreator.kt index 509dc629242..b0a2d4df688 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreator.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreator.kt @@ -29,7 +29,7 @@ package com.tencent.devops.process.yaml.modelTransfer.inner import com.tencent.devops.common.pipeline.pojo.element.ElementAdditionalOptions import com.tencent.devops.common.pipeline.pojo.element.market.MarketBuildAtomElement -import com.tencent.devops.process.yaml.v2.models.step.Step +import com.tencent.devops.process.yaml.v3.models.step.Step /** * ModelCreate的内部类,用来放一些不同使用者的不同方法和参数 @@ -54,15 +54,13 @@ interface TransferCreator { * @param additionalOptions 插件的控制参数 */ fun transferCheckoutElement( - step: Step, - additionalOptions: ElementAdditionalOptions + step: Step ): MarketBuildAtomElement /** * 构造编译类的插件 */ fun transferMarketBuildAtomElement( - step: Step, - additionalOptions: ElementAdditionalOptions + step: Step ): MarketBuildAtomElement } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreatorImpl.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreatorImpl.kt index 3ffe994096d..db50f1bd8ef 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreatorImpl.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/inner/TransferCreatorImpl.kt @@ -30,7 +30,7 @@ package com.tencent.devops.process.yaml.modelTransfer.inner import com.tencent.devops.common.api.exception.CustomException import com.tencent.devops.common.pipeline.pojo.element.ElementAdditionalOptions import com.tencent.devops.common.pipeline.pojo.element.market.MarketBuildAtomElement -import com.tencent.devops.process.yaml.v2.models.step.Step +import com.tencent.devops.process.yaml.v3.models.step.Step import org.springframework.beans.factory.annotation.Autowired import org.springframework.beans.factory.annotation.Value import org.springframework.context.annotation.Primary @@ -69,8 +69,7 @@ class TransferCreatorImpl @Autowired constructor() : TransferCreator { get() = defaultImageData override fun transferCheckoutElement( - step: Step, - additionalOptions: ElementAdditionalOptions + step: Step ): MarketBuildAtomElement { // checkout插件装配 val inputMap = mutableMapOf() @@ -107,14 +106,12 @@ class TransferCreatorImpl @Autowired constructor() : TransferCreator { stepId = step.id, atomCode = "checkout", version = "1.*", - data = data, - additionalOptions = additionalOptions + data = data ) } override fun transferMarketBuildAtomElement( - step: Step, - additionalOptions: ElementAdditionalOptions + step: Step ): MarketBuildAtomElement { val data = mutableMapOf() data["input"] = step.with ?: Any() @@ -124,8 +121,7 @@ class TransferCreatorImpl @Autowired constructor() : TransferCreator { stepId = step.id, atomCode = step.uses!!.split('@')[0], version = step.uses!!.split('@')[1], - data = data, - additionalOptions = additionalOptions + data = data ) } } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/ModelTransferInput.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/ModelTransferInput.kt index ebd4c89e0a8..ec5ac94e634 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/ModelTransferInput.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/ModelTransferInput.kt @@ -6,6 +6,7 @@ import com.tencent.devops.common.pipeline.pojo.setting.PipelineSetting import com.tencent.devops.process.yaml.pojo.YamlVersion data class ModelTransferInput( + val userId: String, var model: Model, val setting: PipelineSetting, val version: YamlVersion.Version, diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/YamlTransferInput.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/YamlTransferInput.kt index a6d9f85e7dd..b6acf4f609b 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/YamlTransferInput.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/modelTransfer/pojo/YamlTransferInput.kt @@ -4,7 +4,7 @@ import com.tencent.devops.common.api.enums.ScmType import com.tencent.devops.common.api.pojo.PipelineAsCodeSettings import com.tencent.devops.process.engine.pojo.PipelineInfo import com.tencent.devops.process.pojo.BuildTemplateAcrossInfo -import com.tencent.devops.process.yaml.v2.models.IPreTemplateScriptBuildYaml +import com.tencent.devops.process.yaml.v3.models.IPreTemplateScriptBuildYaml data class YamlTransferInput( val userId: String, diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/enums/TemplateType.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/enums/TemplateType.kt index 1b7ad953631..18a0da33cdd 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/enums/TemplateType.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/enums/TemplateType.kt @@ -31,7 +31,6 @@ package com.tencent.devops.process.yaml.v2.enums * 模板类型,text为展示内容,content为模板在Yaml中的关键字 */ enum class TemplateType(val text: String, val content: String) { - TRIGGER_ON("triggerOn", "on"), VARIABLE("variable", "variables"), STAGE("stage", "stages"), JOB("job", "jobs"), diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Extends.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Extends.kt index baaba60c47a..d445eba2043 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Extends.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Extends.kt @@ -29,9 +29,6 @@ package com.tencent.devops.process.yaml.v2.models import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude -import com.tencent.devops.process.yaml.v2.models.job.IPreJob -import com.tencent.devops.process.yaml.v2.models.stage.IPreStage -import com.tencent.devops.process.yaml.v2.models.step.IPreStep /** * model @@ -40,6 +37,5 @@ import com.tencent.devops.process.yaml.v2.models.step.IPreStep @JsonIgnoreProperties(ignoreUnknown = true) data class Extends( val template: String, - val parameters: Map?, - val ref: String? -) : IPreStep, IPreJob, IPreStage + val parameters: Map? +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Notices.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Notices.kt index 0115e75727c..6f1a96df5e1 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Notices.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Notices.kt @@ -30,9 +30,6 @@ package com.tencent.devops.process.yaml.v2.models import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty -import com.tencent.devops.common.pipeline.pojo.setting.PipelineSubscriptionType -import com.tencent.devops.common.pipeline.pojo.setting.Subscription -import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault import io.swagger.annotations.ApiModelProperty /** @@ -40,22 +37,19 @@ import io.swagger.annotations.ApiModelProperty */ @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -interface Notices { - fun toSubscription() = Subscription() - - fun checkNotifyForSuccess() = false - - fun checkNotifyForFail() = false -} +open class Notices( + val type: String, + open val receivers: Set? +) /** * model Stream Yaml基本通知 */ @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -data class GitNotices( - val type: String, - val receivers: Set?, +class GitNotices( + type: String, + receivers: Set?, val title: String?, val content: String?, val ccs: Set?, @@ -65,125 +59,7 @@ data class GitNotices( @ApiModelProperty(name = "chat-id") @JsonProperty("chat-id") val chatId: Set? -) : Notices { - - constructor(subscription: Subscription, ifField: String?) : this( - type = subscription.types.map { PacNotices.toNotifyType(it) }.toMutableList().apply { sort() }.also { - if (subscription.wechatGroupFlag) it.add(NotifyType.RTX_GROUP.yamlText) - }.first(), - receivers = subscription.users.split(",").ifEmpty { null }?.toSet(), - title = null, - content = subscription.content.ifEmpty { null }, - ccs = null, - ifField = ifField, - chatId = subscription.wechatGroup.split(",").ifEmpty { null }?.toSet() - ) - - override fun toSubscription() = Subscription( - types = setOf(PacNotices.toPipelineSubscriptionType(type)), - groups = emptySet(), - users = receivers?.joinToString(",") ?: "", - wechatGroupFlag = type.contains(NotifyType.RTX_GROUP.yamlText), - wechatGroup = chatId?.joinToString(",") ?: "", - wechatGroupMarkdownFlag = false, - detailFlag = false, - content = content ?: "" - ) - - override fun checkNotifyForSuccess(): Boolean { - return ifField == null || ifField == IfType.SUCCESS.name || ifField == IfType.ALWAYS.name - } - - override fun checkNotifyForFail(): Boolean { - return ifField == null || ifField == IfType.FAILURE.name || ifField == IfType.ALWAYS.name - } -} - -/** - * pac 通知 - */ -@JsonInclude(JsonInclude.Include.NON_NULL) -@JsonIgnoreProperties(ignoreUnknown = true) -data class PacNotices( - @ApiModelProperty(name = "if") - @JsonProperty("if") - val ifField: String?, - val type: List, - val receivers: List?, - val groups: List?, - val content: String?, - @ApiModelProperty(name = "chat-id") - @JsonProperty("chat-id") - val chatId: List?, - @ApiModelProperty(name = "notify-markdown") - @JsonProperty("notify-markdown") - val notifyMarkdown: Boolean?, - @ApiModelProperty(name = "notify-detail-url") - @JsonProperty("notify-detail-url") - val notifyDetail: Boolean? -) : Notices { - - constructor(subscription: Subscription, ifField: String?) : this( - type = subscription.types.map { toNotifyType(it) }.toMutableList().apply { sort() }.also { - if (subscription.wechatGroupFlag) it.add(NotifyType.RTX_GROUP.yamlText) - }, - receivers = subscription.users.ifBlank { null }?.split(",")?.toSet()?.toList(), - groups = subscription.groups.ifEmpty { null }?.sorted(), - content = subscription.content.ifEmpty { null }, - ifField = ifField, - chatId = subscription.wechatGroup.ifBlank { null }?.split(",")?.toSet()?.toList(), - notifyMarkdown = subscription.wechatGroupMarkdownFlag.nullIfDefault(false), - notifyDetail = subscription.detailFlag.nullIfDefault(false) - ) - - companion object { - fun toPipelineSubscriptionType(type: String) = when (type) { - NotifyType.EMAIL.yamlText -> PipelineSubscriptionType.EMAIL - NotifyType.RTX_CUSTOM.yamlText -> PipelineSubscriptionType.RTX - NotifyType.SMS.yamlText -> PipelineSubscriptionType.SMS - else -> PipelineSubscriptionType.RTX - } - - fun toNotifyType(type: PipelineSubscriptionType) = when (type) { - PipelineSubscriptionType.EMAIL -> NotifyType.EMAIL.yamlText - PipelineSubscriptionType.RTX -> NotifyType.RTX_CUSTOM.yamlText - PipelineSubscriptionType.SMS -> NotifyType.SMS.yamlText - else -> NotifyType.RTX_GROUP.yamlText - } - } - - override fun toSubscription() = Subscription( - types = type.map { toPipelineSubscriptionType(it) }.toSet(), - groups = groups?.toSet() ?: emptySet(), - users = receivers?.joinToString(",") ?: "", - wechatGroupFlag = type.contains(NotifyType.RTX_GROUP.yamlText), - wechatGroup = chatId?.joinToString(",") ?: "", - wechatGroupMarkdownFlag = notifyMarkdown ?: false, - detailFlag = notifyDetail ?: false, - content = content ?: "" - ) - - override fun checkNotifyForSuccess(): Boolean { - return ifField == null || ifField == IfType.SUCCESS.name || ifField == IfType.ALWAYS.name - } - - override fun checkNotifyForFail(): Boolean { - return ifField == null || ifField == IfType.FAILURE.name || ifField == IfType.ALWAYS.name - } -} - -enum class NotifyType(val yamlText: String) { - // 企业微信客服 - SMS("sms"), - - RTX_CUSTOM("wework-message"), - - // 邮件 - EMAIL("email"), - - // 企业微信群 - RTX_GROUP("wework-chat"); -} +) : Notices(type, receivers) /** * model Stream 质量红线通知 @@ -191,6 +67,6 @@ enum class NotifyType(val yamlText: String) { @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) class GateNotices( - val type: String, - val receivers: Set? -) : Notices + type: String, + receivers: Set? +) : Notices(type, receivers) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreScriptBuildYaml.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreScriptBuildYaml.kt index 4de17bc070d..bafe1ba6a89 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreScriptBuildYaml.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreScriptBuildYaml.kt @@ -29,8 +29,6 @@ package com.tencent.devops.process.yaml.v2.models import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude -import com.fasterxml.jackson.annotation.JsonProperty -import com.tencent.devops.process.yaml.pojo.YamlVersion import com.tencent.devops.process.yaml.v2.models.job.PreJob import com.tencent.devops.process.yaml.v2.models.on.PreTriggerOn import com.tencent.devops.process.yaml.v2.models.stage.PreStage @@ -40,16 +38,18 @@ import com.tencent.devops.process.yaml.v2.models.step.PreStep * PreScriptBuildYamlI 是PreScriptBuildYaml的拓展,方便再既不修改data class的特性情况下,其他类可以在继承新增字段 * 注:PreScriptBuildYaml 新增的字段需要在这里新增 */ -interface PreScriptBuildYamlI : YamlVersion { +interface PreScriptBuildYamlI { var version: String? var name: String? var label: List? + var triggerOn: PreTriggerOn? var variables: Map? var stages: List? var jobs: Map? var steps: List? var extends: Extends? var resources: Resources? + var notices: List? var finally: Map? val concurrency: Concurrency? } @@ -65,17 +65,14 @@ data class PreScriptBuildYaml( override var version: String?, override var name: String?, override var label: List? = null, - @JsonProperty("on") - var triggerOn: PreTriggerOn?, + override var triggerOn: PreTriggerOn?, override var variables: Map? = null, override var stages: List? = null, override var jobs: Map? = null, override var steps: List? = null, override var extends: Extends? = null, override var resources: Resources?, - var notices: List?, + override var notices: List?, override var finally: Map? = null, override val concurrency: Concurrency? = null -) : PreScriptBuildYamlI { - override fun yamlVersion() = YamlVersion.Version.V2_0 -} +) : PreScriptBuildYamlI diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt index 91c48a8c463..a866f5a1a32 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/PreTemplateScriptBuildYaml.kt @@ -27,66 +27,9 @@ package com.tencent.devops.process.yaml.v2.models -import com.fasterxml.jackson.annotation.JsonIgnore import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude -import com.fasterxml.jackson.annotation.JsonProperty -import com.fasterxml.jackson.annotation.JsonSubTypes -import com.fasterxml.jackson.annotation.JsonTypeInfo -import com.tencent.devops.common.api.enums.ScmType -import com.tencent.devops.process.yaml.pojo.YamlVersion -import com.tencent.devops.process.yaml.v2.models.job.Job import com.tencent.devops.process.yaml.v2.models.on.PreTriggerOn -import com.tencent.devops.process.yaml.v2.models.on.TriggerOn -import com.tencent.devops.process.yaml.v2.models.stage.Stage -import com.tencent.devops.process.yaml.v2.utils.ScriptYmlUtils -import com.tencent.devops.process.yaml.v3.models.PreTemplateScriptBuildYamlV3 -import com.tencent.devops.process.yaml.v3.models.TriggerType - -@JsonTypeInfo( - use = JsonTypeInfo.Id.NAME, - include = JsonTypeInfo.As.EXISTING_PROPERTY, - property = "version", - defaultImpl = PreTemplateScriptBuildYaml::class -) -@JsonSubTypes( - JsonSubTypes.Type(value = PreTemplateScriptBuildYamlV3::class, name = YamlVersion.Version.V3), - JsonSubTypes.Type(value = PreTemplateScriptBuildYaml::class, name = YamlVersion.Version.V2) -) -interface IPreTemplateScriptBuildYaml : YamlVersion { - val version: String? - val name: String? - val label: List? - val notices: List? - val concurrency: Concurrency? - - fun replaceTemplate(f: (param: ITemplateFilter) -> PreScriptBuildYamlI) - - fun formatVariables(): Map - - fun formatTriggerOn(default: ScmType): List> - - fun formatStages(): List - - fun formatFinallyStage(): List - - fun formatResources(): Resources? -} - -/* -* ITemplateFilter 为模板替换所需材料 -*/ -interface ITemplateFilter : YamlVersion { - val variables: Map? - val stages: List>? - val jobs: Map? - val steps: List>? - val extends: Extends? - val resources: Resources? - var finally: Map? - - fun initPreScriptBuildYamlI(): PreScriptBuildYamlI -} /** * model @@ -96,67 +39,17 @@ interface ITemplateFilter : YamlVersion { @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class PreTemplateScriptBuildYaml( - override val version: String?, - override val name: String?, - override val label: List? = null, - @JsonProperty("on") + val version: String?, + val name: String?, + val label: List? = null, val triggerOn: PreTriggerOn?, - override val variables: Map?, - override val stages: List>?, - override val jobs: Map? = null, - override val steps: List>? = null, - override val extends: Extends?, - override val resources: Resources?, - override var finally: Map?, - override val notices: List?, - override val concurrency: Concurrency? = null -) : IPreTemplateScriptBuildYaml, ITemplateFilter { - override fun yamlVersion() = YamlVersion.Version.V2_0 - - override fun initPreScriptBuildYamlI(): PreScriptBuildYamlI { - return PreScriptBuildYaml( - version = version, - name = name, - label = label, - triggerOn = triggerOn, - resources = resources, - notices = notices, - concurrency = concurrency - ) - } - - @JsonIgnore - lateinit var preYaml: PreScriptBuildYaml - - override fun replaceTemplate(f: (param: ITemplateFilter) -> PreScriptBuildYamlI) { - preYaml = f(this) as PreScriptBuildYaml - } - - override fun formatVariables(): Map { - checkInitialized() - return preYaml.variables ?: emptyMap() - } - - override fun formatTriggerOn(default: ScmType): List> { - return listOf(TriggerType.parse(default) to ScriptYmlUtils.formatTriggerOn(triggerOn)) - } - - override fun formatStages(): List { - checkInitialized() - return ScriptYmlUtils.formatStage(preYaml) - } - - override fun formatFinallyStage(): List { - checkInitialized() - return ScriptYmlUtils.preJobs2Jobs(preYaml.finally) - } - - override fun formatResources(): Resources? { - checkInitialized() - return preYaml.resources - } - - private fun checkInitialized() { - if (!this::preYaml.isInitialized) throw RuntimeException("need replaceTemplate before") - } -} + val variables: Map?, + val stages: List>?, + val jobs: Map? = null, + val steps: List>? = null, + val extends: Extends?, + val resources: Resources?, + val notices: List?, + var finally: Map?, + val concurrency: Concurrency? = null +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/ScriptBuildYaml.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/ScriptBuildYaml.kt index d35c59f4d6d..7ad011153da 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/ScriptBuildYaml.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/ScriptBuildYaml.kt @@ -29,8 +29,6 @@ package com.tencent.devops.process.yaml.v2.models import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude -import com.fasterxml.jackson.annotation.JsonProperty -import com.tencent.devops.process.yaml.pojo.YamlVersion import com.tencent.devops.process.yaml.v2.models.job.Job import com.tencent.devops.process.yaml.v2.models.on.TriggerOn import com.tencent.devops.process.yaml.v2.models.stage.Stage @@ -46,7 +44,6 @@ data class ScriptBuildYaml( val version: String?, val name: String?, val label: List?, - @JsonProperty("on") val triggerOn: TriggerOn?, val variables: Map?, val stages: List, @@ -55,6 +52,4 @@ data class ScriptBuildYaml( val notices: List?, var finally: List?, val concurrency: Concurrency? -) : YamlVersion { - override fun yamlVersion() = YamlVersion.Version.V2_0 -} +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Template.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Template.kt index aa23de7ed17..168ebff9ff8 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Template.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Template.kt @@ -29,6 +29,5 @@ package com.tencent.devops.process.yaml.v2.models data class Template( val template: String, - val ref: String?, val parameters: Map? ) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Variable.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Variable.kt index df18a991ad6..17a384c80a5 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Variable.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/Variable.kt @@ -31,37 +31,6 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty -// @JsonDeserialize(using = IVariableDeserializer::class) -interface IVariable -// -// class IVariableDeserializer : StdDeserializer(IVariable::class.java) { -// override fun deserialize(p: JsonParser, ctxt: DeserializationContext): IVariable { -// val node: JsonNode = p.codec.readTree(p) -// return when (node) { -// is ObjectNode -> Variable( -// value = node.get(Variable::value.name)?.asText(), -// readonly = node.get(Variable::readonly.name)?.asBoolean(), -// allowModifyAtStartup = node.get(Variable::allowModifyAtStartup.name)?.asBoolean(), -// props = JsonUtil.toOrNull( -// node.get(Variable::props.name)?.toString(), object : TypeReference() {}), -// ) -// is ArrayNode -> TemplateVariable(JsonUtil.to(node.toString(), object : TypeReference>() {})) -// is TextNode -> ShortVariable(node.toString()) -// else -> throw Exception("") -// } -// } -// } -// -// class IVariableSerializer : StdSerializer(IVariable::class.java) { -// override fun serialize(value: IVariable, gen: JsonGenerator, provider: SerializerProvider) { -// when (value) { -// is ShortVariable -> gen.writeString(value.value) -// is Variable -> gen.writeObject(value.toMap()) -// is TemplateVariable -> gen.writeObject(value.toList()) -// } -// } -// } - /** * Variable model * @param allowModifyAtStartup 手动触发/openapi触发时生效 @@ -73,14 +42,8 @@ data class Variable( val readonly: Boolean? = false, @JsonProperty("allow-modify-at-startup") val allowModifyAtStartup: Boolean? = false, - @JsonProperty("value-not-empty") - val valueNotEmpty: Boolean? = false, val props: VariableProps? = null -) : IVariable - -data class ShortVariable(val value: String) : IVariable - -data class TemplateVariable(private val list: List) : List by list, IVariable +) /** * Variable 属性变量 diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/Pool.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/Pool.kt index 756152eaa4d..3bbdeeee2d3 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/Pool.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/Pool.kt @@ -30,34 +30,23 @@ package com.tencent.devops.process.yaml.v2.models.image import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.tencent.devops.common.pipeline.enums.VMBaseOS -import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentDockerInfo -import com.tencent.devops.common.pipeline.type.docker.ImageType @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class Pool( - val container: String? = null, - val credentialId: String? = null, - val third: Boolean? = null, + val container: String?, + val credential: Credential?, + val third: Boolean?, val performanceConfigId: String? = "0", val env: Map? = mapOf(), val type: PoolType? = null, val agentName: String? = null, val agentId: String? = null, val envName: String? = null, - val envProjectId: String? = null, val envId: String? = null, val os: VMBaseOS? = null, val workspace: String? = null, - val buildType: BuildType? = BuildType.DEVCLOUD, - val dockerInfo: ThirdPartyAgentDockerInfo? = null, - val image: PoolImage? = null -) - -data class PoolImage( - val imageCode: String, - val imageVersion: String, - val imageType: ImageType? = ImageType.THIRD + val buildType: BuildType? = BuildType.DEVCLOUD ) enum class BuildType { diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/PoolType.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/PoolType.kt index aa5fe852049..b64431e5a23 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/PoolType.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/image/PoolType.kt @@ -30,17 +30,10 @@ package com.tencent.devops.process.yaml.v2.models.image import com.tencent.devops.common.api.exception.OperationException import com.tencent.devops.common.pipeline.type.DispatchType import com.tencent.devops.common.pipeline.type.agent.AgentType -import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentDockerInfo import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentEnvDispatchType import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentIDDispatchType import com.tencent.devops.common.pipeline.type.docker.DockerDispatchType import com.tencent.devops.common.pipeline.type.docker.ImageType -import com.tencent.devops.process.yaml.v2.models.job.Container2 -import com.tencent.devops.process.yaml.v2.models.job.Container3 -import com.tencent.devops.process.yaml.v2.models.job.Credentials -import com.tencent.devops.process.yaml.v2.models.job.JobRunsOnPoolType -import com.tencent.devops.process.yaml.v2.models.job.JobRunsOnType -import com.tencent.devops.process.yaml.v2.models.job.RunsOn import org.slf4j.Logger import org.slf4j.LoggerFactory @@ -49,11 +42,9 @@ enum class PoolType { DockerOnVm { override fun transfer(pool: Pool): DispatchType { return DockerDispatchType( - dockerBuildVersion = pool.container ?: pool.image?.imageCode, - imageType = pool.image?.imageType ?: ImageType.THIRD, - credentialId = pool.credentialId, - imageVersion = pool.image?.imageVersion, - imageCode = pool.image?.imageCode + dockerBuildVersion = pool.container, + imageType = ImageType.THIRD, + credentialId = pool.credential?.credentialId ) } @@ -62,106 +53,41 @@ enum class PoolType { throw OperationException("当pool.type=$this, container参数不能为空") } } - - override fun transfer(dispatcher: DispatchType): RunsOn? { - if (dispatcher is DockerDispatchType) { - return RunsOn( - selfHosted = null, - poolName = JobRunsOnType.DOCKER.type, - container = when (dispatcher.imageType) { - ImageType.BKSTORE, ImageType.THIRD -> Container2( - image = "${dispatcher.dockerBuildVersion}:${dispatcher.imageVersion}", - credentials = dispatcher.credentialId - ) - else -> null - } - ) - } - return null - } }, SelfHosted { override fun transfer(pool: Pool): DispatchType { if (!pool.envName.isNullOrBlank()) { return ThirdPartyAgentEnvDispatchType( - envProjectId = pool.envProjectId, - envName = pool.envName, + envProjectId = null, + envName = pool.envName!!, workspace = pool.workspace, agentType = AgentType.NAME, - dockerInfo = pool.dockerInfo + dockerInfo = null ) } else if (!pool.envId.isNullOrBlank()) { return ThirdPartyAgentEnvDispatchType( - envProjectId = pool.envProjectId, - envName = pool.envId, + envProjectId = null, + envName = pool.envId!!, workspace = pool.workspace, agentType = AgentType.ID, - dockerInfo = pool.dockerInfo + dockerInfo = null ) } else if (!pool.agentId.isNullOrBlank()) { return ThirdPartyAgentIDDispatchType( - displayName = pool.agentId, + displayName = pool.agentId!!, workspace = pool.workspace, agentType = AgentType.ID, - dockerInfo = pool.dockerInfo + dockerInfo = null ) } else { return ThirdPartyAgentIDDispatchType( displayName = pool.agentName!!, workspace = pool.workspace, agentType = AgentType.NAME, - dockerInfo = pool.dockerInfo - ) - } - } - - override fun transfer(dispatcher: DispatchType): RunsOn? { - if (dispatcher is ThirdPartyAgentEnvDispatchType) { - return RunsOn( - selfHosted = true, - poolName = dispatcher.envName, - poolType = if (dispatcher.agentType == AgentType.NAME) { - JobRunsOnPoolType.ENV_NAME.name - } else { - JobRunsOnPoolType.ENV_ID.name - }, - workspace = dispatcher.workspace, - container = makeContainer(dispatcher.dockerInfo) - ) - } - if (dispatcher is ThirdPartyAgentIDDispatchType) { - return RunsOn( - selfHosted = true, - poolName = dispatcher.displayName, - poolType = if (dispatcher.agentType == AgentType.NAME) { - JobRunsOnPoolType.AGENT_NAME.name - } else { - JobRunsOnPoolType.AGENT_ID.name - }, - workspace = dispatcher.workspace, - container = makeContainer(dispatcher.dockerInfo) + dockerInfo = null ) } - return null - } - - private fun makeContainer(dockerInfo: ThirdPartyAgentDockerInfo?): Container3? { - if (dockerInfo == null) return null - return Container3( - image = dockerInfo.image, - imageType = null, - credentials = with(dockerInfo.credential) { - when { - this == null -> null - credentialId != null -> dockerInfo.credential?.credentialId?.ifBlank { null } - user != null && password != null -> Credentials(user!!, password!!) - else -> null - } - }, - options = dockerInfo.options, - imagePullPolicy = dockerInfo.imagePullPolicy - ) } override fun validatePool(pool: Pool) { @@ -183,15 +109,6 @@ enum class PoolType { */ protected abstract fun transfer(pool: Pool): DispatchType - /** - * 转换runsOn - */ - protected abstract fun transfer(dispatcher: DispatchType): RunsOn? - - fun toRunsOn(dispatcher: DispatchType): RunsOn? { - return this.transfer(dispatcher) - } - fun toDispatchType(pool: Pool): DispatchType { this.validatePool(pool) return this.transfer(pool) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/job/Job.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/job/Job.kt index 95fb40524ba..7d7c453ab8b 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/job/Job.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/job/Job.kt @@ -29,7 +29,6 @@ package com.tencent.devops.process.yaml.v2.models.job import com.fasterxml.jackson.annotation.JsonProperty import com.tencent.devops.common.pipeline.type.agent.DockerOptions -import com.tencent.devops.common.pipeline.type.docker.ImageType import com.tencent.devops.process.yaml.v2.models.step.Step import io.swagger.annotations.ApiModelProperty @@ -69,29 +68,18 @@ data class Job( data class Container( val image: String, - val imageType: String? = ImageType.THIRD.name, - val credentials: Credentials? = null, - val options: DockerOptions? = null, + val credentials: Credentials?, + val options: DockerOptions?, @JsonProperty("image-pull-policy") - val imagePullPolicy: String? = null + val imagePullPolicy: String? ) data class Container2( val image: String, - val imageType: String? = ImageType.THIRD.name, - val credentials: String? = null, - val options: DockerOptions? = null, + val credentials: String?, + val options: DockerOptions?, @JsonProperty("image-pull-policy") - val imagePullPolicy: String? = null -) - -data class Container3( - val image: String, - val imageType: String? = ImageType.THIRD.name, - val credentials: Any? = null, - val options: DockerOptions? = null, - @JsonProperty("image-pull-policy") - val imagePullPolicy: String? = null + val imagePullPolicy: String? ) enum class ImagePullPolicyEnum(val type: String) { @@ -131,18 +119,16 @@ data class RunsOn( @ApiModelProperty(name = "pool-name") @JsonProperty("pool-name") var poolName: String = JobRunsOnType.DOCKER.type, - @JsonProperty("pool-type") - val poolType: String? = JobRunsOnPoolType.ENV_NAME.name, val container: Any? = null, @ApiModelProperty(name = "agent-selector") @JsonProperty("agent-selector") - var agentSelector: List? = null, + val agentSelector: List? = null, val workspace: String? = null, val xcode: String? = null, @ApiModelProperty(name = "queue-timeout-minutes") @JsonProperty("queue-timeout-minutes") - var queueTimeoutMinutes: Int? = null, - var needs: Map? = null + val queueTimeoutMinutes: Int? = null, + val needs: Map? = null ) enum class JobRunsOnType(val type: String) { @@ -153,19 +139,10 @@ enum class JobRunsOnType(val type: String) { LOCAL("local") } -enum class JobRunsOnPoolType { - ENV_NAME, - ENV_ID, - AGENT_ID, - AGENT_NAME -} - data class Mutex( val label: String, @JsonProperty("queue-length") val queueLength: Int? = 0, @JsonProperty("timeout-minutes") - val timeoutMinutes: Int? = 10, - @JsonProperty("queue-enable") - val queueEnable: Boolean? = false + val timeoutMinutes: Int? = 10 ) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/job/PreJob.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/job/PreJob.kt index 473df9e2c8a..6426aad6809 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/job/PreJob.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/job/PreJob.kt @@ -35,8 +35,6 @@ import com.tencent.devops.process.yaml.v2.models.YamlMetaData import com.tencent.devops.process.yaml.v2.models.step.PreStep import io.swagger.annotations.ApiModelProperty -interface IPreJob - /** * WARN: 请谨慎修改这个类 , 不要随意添加或者删除变量 , 否则可能导致依赖yaml的功能(gitci,prebuild等)异常 */ @@ -70,4 +68,4 @@ data class PreJob( @JsonProperty("depend-on") val dependOn: List? = null, override val yamlMetaData: MetaData? = null -) : YamlMetaData, IPreJob +) : YamlMetaData diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/IssueRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/IssueRule.kt index a9d0a524912..4fc20022638 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/IssueRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/IssueRule.kt @@ -33,6 +33,5 @@ import com.fasterxml.jackson.annotation.JsonInclude @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class IssueRule( - val enable: Boolean? = true, val action: List? = null ) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/MrRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/MrRule.kt index a26bcb3340b..84bea742b71 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/MrRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/MrRule.kt @@ -38,11 +38,6 @@ import io.swagger.annotations.ApiModelProperty @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class MrRule( - val enable: Boolean? = true, - @ApiModelProperty(name = "source-branches") - @JsonProperty("source-branches") - val sourceBranches: List? = null, - @ApiModelProperty(name = "source-branches-ignore") @JsonProperty("source-branches-ignore") val sourceBranchesIgnore: List? = null, @@ -51,10 +46,6 @@ data class MrRule( @JsonProperty("target-branches") val targetBranches: List? = null, - @ApiModelProperty(name = "target-branches-ignore") - @JsonProperty("target-branches-ignore") - val targetBranchesIgnore: List? = null, - val paths: List? = null, @ApiModelProperty(name = "paths-ignore") @@ -67,15 +58,5 @@ data class MrRule( @ApiModelProperty(name = "users-ignore") @JsonProperty("users-ignore") - val usersIgnore: List? = null, - - val block: Boolean? = null, - - val webhookQueue: Boolean? = null, - - val enableCheck: Boolean? = null, - - @ApiModelProperty(name = "path-filter-type") - @JsonProperty("path-filter-type") - val pathFilterType: String? = null + val usersIgnore: List? = null ) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/NoteRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/NoteRule.kt index 861c18bf577..d2a26802890 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/NoteRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/NoteRule.kt @@ -32,8 +32,7 @@ import com.fasterxml.jackson.annotation.JsonInclude @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -class NoteRule( - val enable: Boolean? = true, - val types: List? = null, +class NoteRule { + val types: List? = null val comment: List? = null -) +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/PushRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/PushRule.kt index 93e441be6f1..6214ffd5a67 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/PushRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/PushRule.kt @@ -38,8 +38,7 @@ import io.swagger.annotations.ApiModelProperty @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class PushRule( - val enable: Boolean? = true, - val branches: List? = listOf("*"), + val branches: List = listOf("*"), @ApiModelProperty(name = "branches-ignore") @JsonProperty("branches-ignore") @@ -57,9 +56,5 @@ data class PushRule( @JsonProperty("users-ignore") val usersIgnore: List? = null, - val action: List? = null, - - @ApiModelProperty(name = "path-filter-type") - @JsonProperty("path-filter-type") - val pathFilterType: String? = null + val action: List? = null ) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ReviewRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ReviewRule.kt index 18cd25938f0..c9376760791 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ReviewRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ReviewRule.kt @@ -32,8 +32,7 @@ import com.fasterxml.jackson.annotation.JsonInclude @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) -data class ReviewRule( - val enable: Boolean? = true, - val types: List? = null, +class ReviewRule { + val types: List? = null val states: List? = null -) +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/SchedulesRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/SchedulesRule.kt index 1430b3bed65..e693487d4ff 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/SchedulesRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/SchedulesRule.kt @@ -29,8 +29,6 @@ package com.tencent.devops.process.yaml.v2.models.on import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude -import com.fasterxml.jackson.annotation.JsonProperty -import io.swagger.annotations.ApiModelProperty /** * model @@ -38,12 +36,7 @@ import io.swagger.annotations.ApiModelProperty @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class SchedulesRule( - val enable: Boolean? = true, - val cron: String? = null, - - @ApiModelProperty(name = "advance-cron") - @JsonProperty("advance-cron") - val advanceCron: List? = null, + val cron: String, val branches: List? = null, diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TagRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TagRule.kt index 009950765a3..f34fd78f1e3 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TagRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TagRule.kt @@ -38,7 +38,6 @@ import io.swagger.annotations.ApiModelProperty @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class TagRule( - val enable: Boolean? = true, val tags: List? = null, @ApiModelProperty(name = "tags-ignore") diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TriggerOn.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TriggerOn.kt index eca175c5726..b6b103a9718 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TriggerOn.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/TriggerOn.kt @@ -30,11 +30,7 @@ package com.tencent.devops.process.yaml.v2.models.on import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty -import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_MANUAL_RULE -import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault -import com.tencent.devops.process.yaml.pojo.YamlVersion import com.tencent.devops.process.yaml.v2.models.RepositoryHook -import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 import io.swagger.annotations.ApiModelProperty /** @@ -43,101 +39,35 @@ import io.swagger.annotations.ApiModelProperty @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class TriggerOn( - var push: PushRule? = null, - var tag: TagRule? = null, - var mr: MrRule? = null, - var schedules: List? = null, - var delete: DeleteRule? = null, - var issue: IssueRule? = null, - var review: ReviewRule? = null, - var note: NoteRule? = null, + val push: PushRule?, + val tag: TagRule?, + val mr: MrRule?, + val schedules: SchedulesRule? = null, + val delete: DeleteRule? = null, + val issue: IssueRule? = null, + val review: ReviewRule? = null, + val note: NoteRule? = null, @ApiModelProperty(name = "repo_hook") @JsonProperty("repo_hook") val repoHook: RepositoryHook? = null, - var manual: ManualRule? = null, - var remote: String? = null, - val openapi: String? = null, - var repoName: String? = null, - var triggerName: String? = null, - @JsonProperty("repoId") - @ApiModelProperty(name = "repoId") - var repoHashId: String? = null, - var credentials: String? = null -) { - fun toPre(version: YamlVersion.Version) = when (version) { - YamlVersion.Version.V2_0 -> toPreV2() - YamlVersion.Version.V3_0 -> toPreV3() - } - - private fun toPreV2() = PreTriggerOn( - push = push, - tag = tag, - mr = mr, - schedules = schedules?.firstOrNull(), - delete = delete, - issue = issue, - review = review, - note = note, - // todo - repoHook = null, - manual = manual?.let { EnableType.TRUE.value } ?: EnableType.FALSE.value, - openapi = openapi, - remote = remote - ) - - private fun toPreV3() = PreTriggerOnV3( - repoName = repoName, - repoHashId = repoHashId, - type = null, - credentials = credentials, - push = push, - tag = tag, - mr = mr, - schedules = if (schedules?.size == 1) schedules!!.first() else schedules, - delete = delete, - issue = issue, - review = review, - note = note, - // todo - repoHook = null, - manual = (manual ?: EnableType.FALSE.value).nullIfDefault(DEFAULT_MANUAL_RULE), - openapi = openapi, - remote = remote - ) -} - -interface IPreTriggerOn : YamlVersion { - val push: Any? - val tag: Any? - val mr: Any? - val schedules: Any? - val delete: DeleteRule? - val issue: IssueRule? - val review: ReviewRule? - val note: NoteRule? - val repoHook: List? - val manual: Any? - val openapi: String? - val remote: String? -} + val manual: String? = null, + val openapi: String? = null +) @JsonInclude(JsonInclude.Include.NON_NULL) @JsonIgnoreProperties(ignoreUnknown = true) data class PreTriggerOn( - override val push: Any?, - override val tag: Any?, - override val mr: Any?, - override val schedules: Any?, - override val delete: DeleteRule?, - override val issue: IssueRule? = null, - override val review: ReviewRule? = null, - override val note: NoteRule? = null, + val push: Any?, + val tag: Any?, + val mr: Any?, + val schedules: SchedulesRule?, + val delete: DeleteRule?, + val issue: IssueRule? = null, + val review: ReviewRule? = null, + val note: NoteRule? = null, @ApiModelProperty(name = "repo_hook") @JsonProperty("repo_hook") - override val repoHook: List? = null, - override val manual: Any? = null, - override val openapi: String? = null, - override val remote: String? = null -) : IPreTriggerOn { - override fun yamlVersion() = YamlVersion.Version.V2_0 -} + val repoHook: List? = null, + val manual: String? = null, + val openapi: String? = null +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/stage/PreStage.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/stage/PreStage.kt index d6089c15d63..e7bea39d6c2 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/stage/PreStage.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/stage/PreStage.kt @@ -32,8 +32,6 @@ import com.tencent.devops.process.yaml.v2.models.job.PreJob import com.tencent.devops.process.yaml.v2.stageCheck.PreStageCheck import io.swagger.annotations.ApiModelProperty -interface IPreStage - /** * WARN: 请谨慎修改这个类 , 不要随意添加或者删除变量 , 否则可能导致依赖yaml的功能(gitci,prebuild等)异常 */ @@ -56,4 +54,4 @@ data class PreStage( @ApiModelProperty(name = "check-out") @JsonProperty("check-out") val checkOut: PreStageCheck? -) : IPreStage +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/stage/StageLabel.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/stage/StageLabel.kt index bf75a7d855b..fd7eb872469 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/stage/StageLabel.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/stage/StageLabel.kt @@ -35,13 +35,4 @@ enum class StageLabel( APPROVE("Approve", "5168be68b9764edb91aa5b866e51a1a8"), DEPLOY("Deploy", "53b4d3f38e3e425cb1aaa97aa1b37857"), TEST("Test", "d0a06f6986fa4670af65ccad7bb49d3a"); - - companion object { - fun parseById(id: String): StageLabel { - values().forEach { - if (it.id == id) return it - } - return BUILD - } - } } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/step/PreStep.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/step/PreStep.kt index 20609ac79e9..94b22d650e6 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/step/PreStep.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/step/PreStep.kt @@ -34,8 +34,6 @@ import com.tencent.devops.process.yaml.v2.models.YAME_META_DATA_JSON_FILTER import com.tencent.devops.process.yaml.v2.models.YamlMetaData import io.swagger.annotations.ApiModelProperty -interface IPreStep - /** * 为了方便产生中间变量的过度类和Step一模一样 */ @@ -65,4 +63,4 @@ data class PreStep( val run: String?, val shell: String?, override val yamlMetaData: MetaData? = null -) : YamlMetaData, IPreStep +) : YamlMetaData diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/Constants.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/Constants.kt index d6f3b40ef5d..ced07ddd6fc 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/Constants.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/Constants.kt @@ -32,7 +32,6 @@ object Constants { // 引用模板的关键字 const val TEMPLATE_KEY = "template" - const val REF = "ref" // 模板变量关键字 const val PARAMETERS_KEY = "parameters" diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/ParametersExpressionParse.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/ParametersExpressionParse.kt index 2c5516fa6fd..fb5f7da908c 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/ParametersExpressionParse.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/ParametersExpressionParse.kt @@ -18,7 +18,6 @@ import com.tencent.devops.common.expression.context.StringContextData import com.tencent.devops.common.expression.expression.FunctionInfo import com.tencent.devops.common.expression.expression.sdk.NamedValueInfo import com.tencent.devops.common.expression.expression.specialFuctions.hashFiles.HashFilesFunction -import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.exception.YamlFormatException import com.tencent.devops.process.yaml.v2.exception.YamlTemplateException import com.tencent.devops.process.yaml.v2.parameter.Parameters @@ -44,8 +43,8 @@ object ParametersExpressionParse { * @param parameters 引用模板文件时传入的参数 */ fun parseTemplateParameters( - fromPath: TemplatePath, - path: TemplatePath, + fromPath: String, + path: String, template: String, templateParameters: MutableList?, parameters: Map? @@ -58,7 +57,7 @@ object ParametersExpressionParse { templateParameters.forEachIndexed { index, param -> if (param.name.contains(".")) { throw error( - Constants.PARAMETER_FORMAT_ERROR.format(path.toString(), "parameter name ${param.name} not allow contains '.'") + Constants.PARAMETER_FORMAT_ERROR.format(path, "parameter name ${param.name} not allow contains '.'") ) } @@ -75,8 +74,8 @@ object ParametersExpressionParse { if (!param.values.isNullOrEmpty() && !param.values.contains(newValue)) { throw error( Constants.VALUE_NOT_IN_ENUM.format( - fromPath.toString(), - path.toString(), + fromPath, + path, valueName, newValue, param.values.joinToString(",") @@ -100,7 +99,7 @@ object ParametersExpressionParse { if (param.default !is Iterable<*>) { throw error( Constants.PARAMETER_FORMAT_ERROR.format( - path.toString(), "parameter ${param.name} type is ${param.type} but value not" + path, "parameter ${param.name} type is ${param.type} but value not" ) ) } @@ -124,30 +123,30 @@ object ParametersExpressionParse { else -> throw error( Constants.PARAMETER_FORMAT_ERROR.format( - path.toString(), "parameter ${param.name} type ${param.type} not support" + path, "parameter ${param.name} type ${param.type} not support" ) ) } } - return parseParameterValue(path.toString(), template, expNameValues, expContext) + return parseParameterValue(path, template, expNameValues, expContext) } // 因为array的里面可能嵌套array所以先转成json再转成array - fun fromJsonToArrayContext(path: TemplatePath, parameterName: String, value: Iterable<*>): ArrayContextData { + fun fromJsonToArrayContext(path: String, parameterName: String, value: Iterable<*>): ArrayContextData { val jsonTree = try { JsonUtil.getObjectMapper().readTree(JsonUtil.toJson(value)) } catch (e: Throwable) { throw error( Constants.PARAMETER_FORMAT_ERROR.format( - path.toString(), "array parameter $parameterName value [$value] can't to json." + path, "array parameter $parameterName value [$value] can't to json." ) ) } if (!jsonTree.isArray) { throw error( Constants.PARAMETER_FORMAT_ERROR.format( - path.toString(), "array parameter $parameterName value [$value] json type [${jsonTree.nodeType}] not array." + path, "array parameter $parameterName value [$value] json type [${jsonTree.nodeType}] not array." ) ) } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/TemplateLibrary.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/TemplateLibrary.kt index 8535aa794d9..d0eac425e5e 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/TemplateLibrary.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/TemplateLibrary.kt @@ -27,7 +27,6 @@ package com.tencent.devops.process.yaml.v2.parsers.template -import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.enums.TemplateType import com.tencent.devops.process.yaml.v2.models.Repositories import com.tencent.devops.process.yaml.v2.parsers.template.models.GetTemplateParam @@ -44,13 +43,13 @@ data class TemplateLibrary( // 从模板库中获得数据,如果有直接取出,没有则根据保存的库信息从远程仓库拉取,再没有则报错 fun TemplateLibrary.getTemplate( - path: TemplatePath, + path: String, templateType: TemplateType?, nowRepo: Repositories?, toRepo: Repositories? ): String { - if (templates[path.toString()] != null) { - return templates[path.toString()]!! + if (templates[path] != null) { + return templates[path]!! } // 没有库信息说明是触发库 val template = if (toRepo == null) { @@ -75,9 +74,9 @@ fun TemplateLibrary.getTemplate( ) } setTemplate(path, template) - return templates[path.toString()]!! + return templates[path]!! } -fun TemplateLibrary.setTemplate(path: TemplatePath, template: String) { - templates[path.toString()] = template +fun TemplateLibrary.setTemplate(path: String, template: String) { + templates[path] = template } diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/TemplateYamlUtil.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/TemplateYamlUtil.kt index 9ba08b4e12c..fcf0c7e0c64 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/TemplateYamlUtil.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/TemplateYamlUtil.kt @@ -27,7 +27,6 @@ package com.tencent.devops.process.yaml.v2.parsers.template -import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.enums.TemplateType import com.tencent.devops.process.yaml.v2.exception.YamlFormatException import com.tencent.devops.process.yaml.v2.models.Repositories @@ -44,10 +43,10 @@ object TemplateYamlUtil { // 检查是否具有重复的ID,job,variable中使用 fun checkDuplicateKey( - filePath: TemplatePath, + filePath: String, keys: Set, newKeys: Set, - toPath: TemplatePath? = null + toPath: String? = null ): Boolean { val interSet = newKeys intersect keys return if (interSet.isEmpty() || (interSet.size == 1 && interSet.last() == Constants.TEMPLATE_KEY)) { @@ -56,7 +55,7 @@ object TemplateYamlUtil { if (toPath == null) { throw error( Constants.TEMPLATE_ROOT_ID_DUPLICATE.format( - filePath.toString(), + filePath, interSet.filter { it != Constants.TEMPLATE_KEY } ) ) @@ -64,8 +63,8 @@ object TemplateYamlUtil { throw error( Constants.TEMPLATE_ID_DUPLICATE.format( interSet.filter { it != Constants.TEMPLATE_KEY }, - filePath.toString(), - toPath.toString() + filePath, + toPath ) ) } @@ -74,7 +73,7 @@ object TemplateYamlUtil { // 校验当前模板的远程库信息,每个文件只可以使用当前文件下引用的远程库 fun checkAndGetRepo( - fromPath: TemplatePath, + fromPath: String, repoName: String, templateType: TemplateType, templateLib: TemplateLibrary, @@ -112,8 +111,8 @@ object TemplateYamlUtil { */ @Deprecated("旧版本,只是为了兼容,非必要不要使用") fun parseTemplateParametersOld( - fromPath: TemplatePath, - path: TemplatePath, + fromPath: String, + path: String, template: String, templateParameters: MutableList?, parameters: Map? @@ -128,8 +127,8 @@ object TemplateYamlUtil { if (!param.values.isNullOrEmpty() && !param.values!!.contains(newValue)) { throw error( Constants.VALUE_NOT_IN_ENUM.format( - fromPath.toString(), - path.toString(), + fromPath, + path, valueName, newValue.toString(), param.values.joinToString(",") diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlObjects.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlObjects.kt index a3201161d3a..84035513ccb 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlObjects.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlObjects.kt @@ -29,15 +29,12 @@ package com.tencent.devops.process.yaml.v2.parsers.template import com.fasterxml.jackson.core.type.TypeReference import com.tencent.devops.common.api.constant.CommonMessageCode.ERROR_YAML_FORMAT_EXCEPTION_NEED_PARAM -import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.pipeline.type.agent.DockerOptions import com.tencent.devops.common.web.utils.I18nUtil -import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.enums.TemplateType import com.tencent.devops.process.yaml.v2.exception.YamlFormatException import com.tencent.devops.process.yaml.v2.models.GitNotices import com.tencent.devops.process.yaml.v2.models.MetaData -import com.tencent.devops.process.yaml.v2.models.PacNotices import com.tencent.devops.process.yaml.v2.models.ResourcesPools import com.tencent.devops.process.yaml.v2.models.TemplateInfo import com.tencent.devops.process.yaml.v2.models.Variable @@ -57,15 +54,10 @@ import com.tencent.devops.process.yaml.v2.models.step.PreStep import com.tencent.devops.process.yaml.v2.parameter.Parameters import com.tencent.devops.process.yaml.v2.parsers.template.models.TemplateDeepTreeNode import com.tencent.devops.process.yaml.v2.utils.StreamEnvUtils -import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 object YamlObjects { - fun getTriggerOnV3(triggerOn: Map): PreTriggerOnV3 { - return JsonUtil.anyTo(triggerOn, object : TypeReference() {}) - } - - fun getVariable(fromPath: TemplatePath, key: String, variable: Map): Variable { + fun getVariable(fromPath: String, key: String, variable: Map): Variable { val va = Variable( value = variable["value"]?.toString(), readonly = getNullValue("readonly", variable)?.toBoolean(), @@ -107,7 +99,7 @@ object YamlObjects { return va } - private fun getVarProps(fromPath: TemplatePath, props: Any): VariableProps { + private fun getVarProps(fromPath: String, props: Any): VariableProps { val propsMap = transValue>(fromPath, "props", props) val po = VariableProps( label = getNullValue("label", propsMap), @@ -126,7 +118,7 @@ object YamlObjects { return po } - private fun getVarPropOptions(fromPath: TemplatePath, options: Any?): List? { + private fun getVarPropOptions(fromPath: String, options: Any?): List? { if (options == null) { return null } @@ -142,7 +134,7 @@ object YamlObjects { } } - private fun getVarPropDataSource(fromPath: TemplatePath, datasource: Any?): VariableDatasource? { + private fun getVarPropDataSource(fromPath: String, datasource: Any?): VariableDatasource? { if (datasource == null) { return null } @@ -160,7 +152,7 @@ object YamlObjects { ) } - fun getStep(fromPath: TemplatePath, step: Map, repo: TemplateInfo?): PreStep { + fun getStep(fromPath: String, step: Map, repo: TemplateInfo?): PreStep { val preStep = PreStep( name = step["name"]?.toString(), id = step["id"]?.toString(), @@ -197,7 +189,7 @@ object YamlObjects { throw YamlFormatException( I18nUtil.getCodeLanMessage( messageCode = ERROR_YAML_FORMAT_EXCEPTION_NEED_PARAM, - params = arrayOf(fromPath.toString()) + params = arrayOf(fromPath) ) ) } @@ -207,7 +199,7 @@ object YamlObjects { return preStep } - fun getResourceExclusiveDeclaration(fromPath: TemplatePath, resource: Any): Mutex { + fun getResourceExclusiveDeclaration(fromPath: String, resource: Any): Mutex { val resourceMap = transValue>(fromPath, "mutex", resource) return Mutex( label = getNotNullValue(key = "label", mapName = "mutex", map = resourceMap), @@ -216,7 +208,7 @@ object YamlObjects { ) } - fun getService(fromPath: TemplatePath, service: Any): Map { + fun getService(fromPath: String, service: Any): Map { val serviceMap = transValue>(fromPath, "services", service) val newServiceMap = mutableMapOf() serviceMap.forEach { (key, value) -> @@ -236,7 +228,7 @@ object YamlObjects { return newServiceMap } - fun getContainer(fromPath: TemplatePath, container: Any): Container { + fun getContainer(fromPath: String, container: Any): Container { val containerMap = transValue>(fromPath, "container", container) return Container( image = getNotNullValue(key = "image", mapName = "Container", map = containerMap), @@ -273,7 +265,7 @@ object YamlObjects { ) } - fun getStrategy(fromPath: TemplatePath, strategy: Any?): Strategy? { + fun getStrategy(fromPath: String, strategy: Any?): Strategy? { val strategyMap = transValue>(fromPath, "strategy", strategy) val matrix = strategyMap["matrix"] ?: return null return Strategy( @@ -283,7 +275,7 @@ object YamlObjects { ) } - fun getNoticeV2(fromPath: TemplatePath, notice: Map): GitNotices { + fun getNotice(fromPath: String, notice: Map): GitNotices { return GitNotices( type = notice["type"].toString(), title = notice["title"]?.toString(), @@ -302,49 +294,12 @@ object YamlObjects { chatId = if (notice["chat-id"] == null) { null } else { - transValue>(fromPath, "chat-id", notice["chat-id"]).toSet() - } - ) - } - - fun getNoticeV3(fromPath: TemplatePath, notice: Map): PacNotices { - return PacNotices( - type = if (notice["receivers"] == null) { - emptyList() - } else { - transValue(fromPath, "type", notice["type"]) - }, - receivers = if (notice["receivers"] == null) { - null - } else { - transValue>(fromPath, "receivers", notice["receivers"]) - }, - groups = if (notice["groups"] == null) { - null - } else { - transValue>(fromPath, "groups", notice["groups"]) - }, - content = notice["content"]?.toString(), - ifField = notice["if"]?.toString(), - chatId = if (notice["chat-id"] == null) { - null - } else { - transValue>(fromPath, "chat-id", notice["chat-id"]) - }, - notifyMarkdown = if (notice["notify-markdown"] == null) { - null - } else { - transValue(fromPath, "notify-markdown", notice["notify-markdown"]) - }, - notifyDetail = if (notice["notify-detail-url"] == null) { - null - } else { - transValue(fromPath, "notify-detail-url", notice["notify-detail-url"]) + transValue>(fromPath, "receivers", notice["chat-id"]).toSet() } ) } - fun getYamlMetaData(fromPath: TemplatePath, yamlMetaData: Any): MetaData { + fun getYamlMetaData(fromPath: String, yamlMetaData: Any): MetaData { val metaData = transValue>(fromPath, "yamlMetaData", yamlMetaData) if (metaData["templateInfo"] == null) { return MetaData(templateInfo = null) @@ -358,7 +313,7 @@ object YamlObjects { ) } - fun getParameter(fromPath: TemplatePath, param: Map): Parameters { + fun getParameter(fromPath: String, param: Map): Parameters { return Parameters( name = getNotNullValue(key = "name", mapName = TemplateType.PARAMETERS.text, map = param), type = getNotNullValue(key = "type", mapName = TemplateType.PARAMETERS.text, map = param), @@ -371,7 +326,7 @@ object YamlObjects { ) } - fun getResourcePools(fromPath: TemplatePath, resources: Any): List { + fun getResourcePools(fromPath: String, resources: Any): List { val resourcesD = transValue>(fromPath, "resources", resources) if (resourcesD["pools"] == null) { return emptyList() @@ -385,33 +340,33 @@ object YamlObjects { } } - inline fun getObjectFromYaml(path: TemplatePath, template: String): T { + inline fun getObjectFromYaml(path: String, template: String): T { return try { TemplateYamlMapper.getObjectMapper().readValue(template, object : TypeReference() {}) } catch (e: Exception) { - throw YamlFormatException(Constants.YAML_FORMAT_ERROR.format("${path.path} ${path.ref ?: ""}", e.message)) + throw YamlFormatException(Constants.YAML_FORMAT_ERROR.format(path, e.message)) } } - inline fun transValue(file: TemplatePath, type: String, value: Any?): T { + inline fun transValue(file: String, type: String, value: Any?): T { if (value == null) { - throw YamlFormatException(Constants.TRANS_AS_ERROR.format(file.toString(), type)) + throw YamlFormatException(Constants.TRANS_AS_ERROR.format(file, type)) } return try { value as T } catch (e: Exception) { - throw YamlFormatException(Constants.TRANS_AS_ERROR.format(file.toString(), type)) + throw YamlFormatException(Constants.TRANS_AS_ERROR.format(file, type)) } } - inline fun transNullValue(file: TemplatePath, type: String, key: String, map: Map): T? { + inline fun transNullValue(file: String, type: String, key: String, map: Map): T? { return if (map[key] == null) { null } else { return try { map[key] as T } catch (e: Exception) { - throw YamlFormatException(Constants.TRANS_AS_ERROR.format(file.toString(), type)) + throw YamlFormatException(Constants.TRANS_AS_ERROR.format(file, type)) } } } @@ -441,11 +396,7 @@ object YamlObjects { } } -fun YamlTemplate.getStage( - fromPath: TemplatePath, - stage: Map, - deepTree: TemplateDeepTreeNode -): PreStage { +fun YamlTemplate.getStage(fromPath: String, stage: Map, deepTree: TemplateDeepTreeNode): PreStage { return PreStage( name = stage["name"]?.toString(), label = stage["label"], @@ -494,7 +445,7 @@ fun YamlTemplate.getStage( } // 构造对象,因为未保存远程库的template信息,所以在递归回溯时无法通过yaml文件直接生成,故手动构造 -fun YamlTemplate.getJob(fromPath: TemplatePath, job: Map, deepTree: TemplateDeepTreeNode): PreJob { +fun YamlTemplate.getJob(fromPath: String, job: Map, deepTree: TemplateDeepTreeNode): PreJob { val preJob = PreJob( name = job["name"]?.toString(), runsOn = job["runs-on"], diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlTemplate.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlTemplate.kt index 9d038875d4f..92909e596a4 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlTemplate.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/YamlTemplate.kt @@ -28,20 +28,13 @@ package com.tencent.devops.process.yaml.v2.parsers.template import com.fasterxml.jackson.core.JsonProcessingException -import com.fasterxml.jackson.core.type.TypeReference import com.tencent.devops.common.api.constant.CommonMessageCode.ERROR_YAML_FORMAT_EXCEPTION_LENGTH_LIMIT_EXCEEDED -import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.web.utils.I18nUtil -import com.tencent.devops.process.yaml.pojo.TemplatePath -import com.tencent.devops.process.yaml.pojo.YamlVersion import com.tencent.devops.process.yaml.v2.enums.TemplateType import com.tencent.devops.process.yaml.v2.exception.YamlFormatException import com.tencent.devops.process.yaml.v2.models.Extends import com.tencent.devops.process.yaml.v2.models.GitNotices -import com.tencent.devops.process.yaml.v2.models.ITemplateFilter -import com.tencent.devops.process.yaml.v2.models.PacNotices import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYaml -import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYamlI import com.tencent.devops.process.yaml.v2.models.PreTemplateScriptBuildYaml import com.tencent.devops.process.yaml.v2.models.Repositories import com.tencent.devops.process.yaml.v2.models.ResourcesPools @@ -61,17 +54,15 @@ import com.tencent.devops.process.yaml.v2.stageCheck.Gate import com.tencent.devops.process.yaml.v2.stageCheck.GateTemplate import com.tencent.devops.process.yaml.v2.stageCheck.PreStageCheck import com.tencent.devops.process.yaml.v2.stageCheck.PreTemplateStageCheck -import com.tencent.devops.process.yaml.v3.models.PreScriptBuildYamlV3 -import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 @Suppress("ALL") class YamlTemplate( val extraParameters: T, // 当前文件 - var filePath: TemplatePath, + var filePath: String, // 文件对象 - var yamlObject: ITemplateFilter?, + var yamlObject: PreTemplateScriptBuildYaml?, // 当前库信息 val nowRepo: Repositories?, // 目标库信息(发起库没有库信息) @@ -84,7 +75,7 @@ class YamlTemplate( val conf: YamlTemplateConf = YamlTemplateConf(), // 来自文件 - private val fileFromPath: TemplatePath? = null, + private val fileFromPath: String? = null, // 远程模板类型(用来校验远程打平的模板的格式) private val resTemplateType: TemplateType? = null, @@ -114,11 +105,11 @@ class YamlTemplate( ) fun replace( parameters: Map? = null - ): PreScriptBuildYamlI { + ): PreScriptBuildYaml { // 针对远程库进行打平替换时,根文件没有被替换Parameters val newYamlObject = if (repo != null) { val template = parseTemplateParameters( - fromPath = fileFromPath ?: TemplatePath(""), + fromPath = fileFromPath ?: "", path = filePath, template = templateLib.getTemplate( path = filePath, @@ -135,24 +126,34 @@ class YamlTemplate( } else { templateLib.setTemplate(filePath, TemplateYamlMapper.toYaml(yamlObject!!)) yamlObject - } ?: throw RuntimeException("yamlObject cannot be null") + } - val preYamlObject = newYamlObject.initPreScriptBuildYamlI() + val preYamlObject = with(newYamlObject!!) { + PreScriptBuildYaml( + version = version, + name = name, + label = label, + triggerOn = triggerOn, + resources = resources, + notices = notices, + concurrency = concurrency + ) + } if (newYamlObject.extends != null) { - replaceExtends(newYamlObject.extends!!, preYamlObject, rootDeepTree) + replaceExtends(newYamlObject.extends, preYamlObject, rootDeepTree) } if (newYamlObject.variables != null) { - replaceVariables(newYamlObject.variables!!, preYamlObject, rootDeepTree) + replaceVariables(newYamlObject.variables, preYamlObject, rootDeepTree) } if (newYamlObject.stages != null) { - replaceStages(newYamlObject.stages!!, preYamlObject, rootDeepTree) + replaceStages(newYamlObject.stages, preYamlObject, rootDeepTree) } if (newYamlObject.jobs != null) { - replaceJobs(newYamlObject.jobs!!, preYamlObject, rootDeepTree) + replaceJobs(newYamlObject.jobs, preYamlObject, rootDeepTree) } if (newYamlObject.steps != null) { - replaceSteps(newYamlObject.steps!!, preYamlObject, rootDeepTree) + replaceSteps(newYamlObject.steps, preYamlObject, rootDeepTree) } if (newYamlObject.finally != null) { replaceFinally(newYamlObject.finally!!, preYamlObject, rootDeepTree) @@ -163,28 +164,16 @@ class YamlTemplate( private fun replaceExtends( extend: Extends, - preYamlObject: PreScriptBuildYamlI, + preYamlObject: PreScriptBuildYaml, deepTree: TemplateDeepTreeNode ) { - val toPath = TemplatePath(extend.template, extend.ref) + val toPath = extend.template val parameters = extend.parameters // 根据远程模板获取 val templateObject = replaceResAndParam(TemplateType.EXTEND, toPath, parameters, filePath, deepTree) // 获取extends模板后filePath就为被替换的文件了 this.filePath = toPath // 需要替换模板的的递归替换 - if (templateObject[TemplateType.TRIGGER_ON.content] != null) { - replaceTriggerOn( - triggerOn = YamlObjects.transValue( - file = filePath, - type = TemplateType.TRIGGER_ON.text, - value = templateObject[TemplateType.TRIGGER_ON.content] - ), - preYamlObject = preYamlObject, - deepTree = deepTree - ) - } - if (templateObject[TemplateType.VARIABLE.content] != null) { replaceVariables( variables = YamlObjects.transValue( @@ -229,23 +218,12 @@ class YamlTemplate( ) } // notices只用做一次模板替换没有嵌套模板 - if (templateObject["notices"] != null && preYamlObject is PreScriptBuildYaml) { + if (templateObject["notices"] != null) { val notices = mutableListOf() val temNotices = YamlObjects.transValue>>(filePath, "notices", templateObject["notices"]) temNotices.forEach { - notices.add(YamlObjects.getNoticeV2(filePath, it)) - } - preYamlObject.notices = notices - } - - // notices只用做一次模板替换没有嵌套模板 - if (templateObject["notices"] != null && preYamlObject is PreScriptBuildYamlV3) { - val notices = mutableListOf() - val temNotices = - YamlObjects.transValue>>(filePath, "notices", templateObject["notices"]) - temNotices.forEach { - notices.add(YamlObjects.getNoticeV3(filePath, it)) + notices.add(YamlObjects.getNotice(filePath, it)) } preYamlObject.notices = notices } @@ -261,24 +239,9 @@ class YamlTemplate( } } - private fun replaceTriggerOn( - triggerOn: Any, - preYamlObject: PreScriptBuildYamlI, - deepTree: TemplateDeepTreeNode - ) { - if (preYamlObject.yamlVersion() != YamlVersion.Version.V3_0) return - val triggerOnV3s = when (triggerOn) { - // 简写方式 - is Map<*, *> -> listOf(JsonUtil.anyTo(triggerOn, object : TypeReference() {})) - is List<*> -> JsonUtil.anyTo(triggerOn, object : TypeReference>() {}) - else -> null - } - (preYamlObject as PreScriptBuildYamlV3).triggerOn = triggerOnV3s - } - private fun replaceVariables( variables: Map, - preYamlObject: PreScriptBuildYamlI, + preYamlObject: PreScriptBuildYaml, deepTree: TemplateDeepTreeNode ) { val variableMap = mutableMapOf() @@ -299,7 +262,7 @@ class YamlTemplate( private fun replaceStages( stages: List>, - preYamlObject: PreScriptBuildYamlI, + preYamlObject: PreScriptBuildYaml, deepTree: TemplateDeepTreeNode ) { val stageList = mutableListOf() @@ -311,7 +274,7 @@ class YamlTemplate( private fun replaceJobs( jobs: Map, - preYamlObject: PreScriptBuildYamlI, + preYamlObject: PreScriptBuildYaml, deepTree: TemplateDeepTreeNode ) { val jobMap = mutableMapOf() @@ -328,7 +291,7 @@ class YamlTemplate( private fun replaceSteps( steps: List>, - preYamlObject: PreScriptBuildYamlI, + preYamlObject: PreScriptBuildYaml, deepTree: TemplateDeepTreeNode ) { val stepList = mutableListOf() @@ -340,7 +303,7 @@ class YamlTemplate( private fun replaceFinally( finally: Map, - preYamlObject: PreScriptBuildYamlI, + preYamlObject: PreScriptBuildYaml, deepTree: TemplateDeepTreeNode ) { // finally: 与jobs: 的结构相同 @@ -359,7 +322,7 @@ class YamlTemplate( // 进行模板替换 private fun replaceVariableTemplate( variables: Map, - fromPath: TemplatePath, + fromPath: String, deepTree: TemplateDeepTreeNode ): Map { val variableMap = mutableMapOf() @@ -369,13 +332,9 @@ class YamlTemplate( val toPathList = YamlObjects.transValue>>(fromPath, TemplateType.VARIABLE.text, value) toPathList.forEach { item -> - val toPath = TemplatePath( - item[Constants.OBJECT_TEMPLATE_PATH].toString(), item[Constants.REF]?.toString() - ) + val toPath = item[Constants.OBJECT_TEMPLATE_PATH].toString() // 保存并检查是否存在循环引用模板 - templateGraph.saveAndCheckCyclicTemplate( - fromPath.toString(), toPath.toString(), TemplateType.VARIABLE - ) + templateGraph.saveAndCheckCyclicTemplate(fromPath, toPath, TemplateType.VARIABLE) // 获取需要替换的变量 val parameters = YamlObjects.transNullValue>( file = fromPath, @@ -423,16 +382,14 @@ class YamlTemplate( private fun replaceStageTemplate( stages: List>, - fromPath: TemplatePath, + fromPath: String, deepTree: TemplateDeepTreeNode ): List { val stageList = mutableListOf() stages.forEach { stage -> if (Constants.TEMPLATE_KEY in stage.keys) { - val toPath = TemplatePath( - stage[Constants.TEMPLATE_KEY].toString(), stage[Constants.REF]?.toString() - ) - templateGraph.saveAndCheckCyclicTemplate(fromPath.toString(), toPath.toString(), TemplateType.STAGE) + val toPath = stage[Constants.TEMPLATE_KEY].toString() + templateGraph.saveAndCheckCyclicTemplate(fromPath, toPath, TemplateType.STAGE) val parameters = YamlObjects.transNullValue>( file = fromPath, @@ -462,7 +419,7 @@ class YamlTemplate( fun replaceJobTemplate( jobs: Map, - fromPath: TemplatePath, + fromPath: String, deepTree: TemplateDeepTreeNode ): Map { val jobMap = mutableMapOf() @@ -470,10 +427,8 @@ class YamlTemplate( if (key == Constants.TEMPLATE_KEY) { val toPathList = YamlObjects.transValue>>(fromPath, TemplateType.JOB.text, value) toPathList.forEach { item -> - val toPath = TemplatePath( - item[Constants.OBJECT_TEMPLATE_PATH].toString(), item[Constants.REF]?.toString() - ) - templateGraph.saveAndCheckCyclicTemplate(fromPath.toString(), toPath.toString(), TemplateType.JOB) + val toPath = item[Constants.OBJECT_TEMPLATE_PATH].toString() + templateGraph.saveAndCheckCyclicTemplate(fromPath, toPath, TemplateType.JOB) val parameters = YamlObjects.transNullValue>( file = fromPath, @@ -507,7 +462,7 @@ class YamlTemplate( throw YamlFormatException( I18nUtil.getCodeLanMessage( messageCode = ERROR_YAML_FORMAT_EXCEPTION_LENGTH_LIMIT_EXCEEDED, - params = arrayOf(fromPath.toString(), key) + params = arrayOf(fromPath, key) ) ) } @@ -519,17 +474,15 @@ class YamlTemplate( fun replaceStepTemplate( steps: List>, - fromPath: TemplatePath, + fromPath: String, deepTree: TemplateDeepTreeNode ): List { val stepList = mutableListOf() steps.forEach { step -> if (Constants.TEMPLATE_KEY in step.keys) { - val toPath = TemplatePath( - step[Constants.TEMPLATE_KEY].toString(), step[Constants.REF]?.toString() - ) + val toPath = step[Constants.TEMPLATE_KEY].toString() - templateGraph.saveAndCheckCyclicTemplate(fromPath.toString(), toPath.toString(), TemplateType.STEP) + templateGraph.saveAndCheckCyclicTemplate(fromPath, toPath, TemplateType.STEP) val parameters = YamlObjects.transNullValue>( file = fromPath, @@ -572,7 +525,7 @@ class YamlTemplate( fun replaceStageCheckTemplate( stageName: String, check: Map?, - fromPath: TemplatePath, + fromPath: String, deepTree: TemplateDeepTreeNode ): PreStageCheck? { if (check == null) { @@ -597,7 +550,7 @@ class YamlTemplate( YamlObjects.getObjectFromYaml(fromPath, TemplateYamlMapper.toYaml(check)) checkObject.gates?.forEach { gate -> - val toPath = TemplatePath(gate.template, gate.ref) + val toPath = gate.template val templateObject = replaceResAndParam( templateType = TemplateType.GATE, toPath = toPath, @@ -629,24 +582,21 @@ class YamlTemplate( // 替换远程库和参数信息 private fun replaceResAndParam( templateType: TemplateType, - toPath: TemplatePath, + toPath: String, parameters: Map?, - fromPath: TemplatePath, + fromPath: String, deepTree: TemplateDeepTreeNode ): Map { // 判断是否为远程库,如果是远程库将其远程库文件打平进行替换 - var newTemplate = if (toPath.path.contains(Constants.FILE_REPO_SPLIT)) { + var newTemplate = if (toPath.contains(Constants.FILE_REPO_SPLIT)) { // 针对没有循环嵌套做特殊处理 if (templateType == TemplateType.GATE || templateType == TemplateType.PARAMETERS) { templateLib.getTemplate( - path = TemplatePath( - path = toPath.path.split(Constants.FILE_REPO_SPLIT).first(), - ref = toPath.ref - ), + path = toPath.split(Constants.FILE_REPO_SPLIT).first(), nowRepo = repo, toRepo = TemplateYamlUtil.checkAndGetRepo( fromPath = fromPath, - repoName = toPath.path.split(Constants.FILE_REPO_SPLIT)[1], + repoName = toPath.split(Constants.FILE_REPO_SPLIT)[1], templateType = templateType, templateLib = templateLib, nowRepo = nowRepo, @@ -661,7 +611,7 @@ class YamlTemplate( parameters = parameters, toRepo = TemplateYamlUtil.checkAndGetRepo( fromPath = fromPath, - repoName = toPath.path.split(Constants.FILE_REPO_SPLIT)[1], + repoName = toPath.split(Constants.FILE_REPO_SPLIT)[1], templateType = templateType, templateLib = templateLib, nowRepo = nowRepo, @@ -702,20 +652,18 @@ class YamlTemplate( // 对远程仓库中的模板进行远程仓库替换 private fun replaceResTemplateFile( templateType: TemplateType, - toPath: TemplatePath, + toPath: String, parameters: Map?, toRepo: Repositories, deepTree: TemplateDeepTreeNode ): String { // 判断是否有库之间的循环依赖 - templateGraph.saveAndCheckCyclicRepo(fromPath = filePath.toString(), repo = repo, toRepo = toRepo) + templateGraph.saveAndCheckCyclicRepo(fromPath = filePath, repo = repo, toRepo = toRepo) val resYamlObject = YamlTemplate( yamlObject = null, fileFromPath = filePath, - filePath = TemplatePath( - toPath.path.split(Constants.FILE_REPO_SPLIT)[0], toPath.path - ), + filePath = toPath.split(Constants.FILE_REPO_SPLIT)[0], extraParameters = extraParameters, nowRepo = repo, repo = toRepo, @@ -739,8 +687,8 @@ class YamlTemplate( // 在parameters替换前做统一处理,例如替换模板 private fun parseTemplateParameters( - fromPath: TemplatePath, - path: TemplatePath, + fromPath: String, + path: String, template: String, parameters: Map?, deepTree: TemplateDeepTreeNode @@ -753,9 +701,7 @@ class YamlTemplate( preTemplateParam?.forEach { preParam -> if (Constants.TEMPLATE_KEY in preParam) { - val toPath = TemplatePath( - preParam[Constants.TEMPLATE_KEY].toString(), preParam[Constants.REF]?.toString() - ) + val toPath = preParam[Constants.TEMPLATE_KEY].toString() // 因为这里是替换模板的模板参数,所以frompath需要使用模板文件而不是来源文件 val templateObject = replaceResAndParam( templateType = TemplateType.PARAMETERS, diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/models/GetTemplateParam.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/models/GetTemplateParam.kt index e3cad38f828..5194dc4c950 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/models/GetTemplateParam.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/models/GetTemplateParam.kt @@ -27,7 +27,6 @@ package com.tencent.devops.process.yaml.v2.parsers.template.models -import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.enums.TemplateType import com.tencent.devops.process.yaml.v2.models.Repositories @@ -40,7 +39,7 @@ import com.tencent.devops.process.yaml.v2.models.Repositories * @param extraParameters 额外参数,由各个服务具体定义 */ data class GetTemplateParam( - val path: TemplatePath, + val path: String, val templateType: TemplateType?, val nowRepoId: String?, val targetRepo: Repositories?, diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/models/TemplateDeepTreeNode.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/models/TemplateDeepTreeNode.kt index 369e4293aba..c6412e1868a 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/models/TemplateDeepTreeNode.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/parsers/template/models/TemplateDeepTreeNode.kt @@ -27,11 +27,10 @@ package com.tencent.devops.process.yaml.v2.parsers.template.models -import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.exception.YamlFormatException class TemplateDeepTreeNode( - val path: TemplatePath, + val path: String, val parent: TemplateDeepTreeNode?, val children: MutableList ) { @@ -46,7 +45,7 @@ class TemplateDeepTreeNode( "[%s]The template nesting depth exceeds the threshold [$MAX_TEMPLATE_DEEP}]" } - fun add(nodePath: TemplatePath): TemplateDeepTreeNode { + fun add(nodePath: String): TemplateDeepTreeNode { val node = TemplateDeepTreeNode( path = nodePath, parent = this, diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/ScriptYmlUtils.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/ScriptYmlUtils.kt index 4ba51911949..ed74c8e3599 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/ScriptYmlUtils.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/ScriptYmlUtils.kt @@ -50,13 +50,11 @@ import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.common.api.util.UUIDUtil import com.tencent.devops.common.api.util.YamlUtil import com.tencent.devops.common.web.utils.I18nUtil -import com.tencent.devops.process.yaml.modelTransfer.TransferMapper import com.tencent.devops.process.yaml.v2.enums.StreamMrEventAction import com.tencent.devops.process.yaml.v2.enums.TemplateType import com.tencent.devops.process.yaml.v2.exception.YamlFormatException import com.tencent.devops.process.yaml.v2.models.PreRepositoryHook import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYaml -import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYamlI import com.tencent.devops.process.yaml.v2.models.RepositoryHook import com.tencent.devops.process.yaml.v2.models.ScriptBuildYaml import com.tencent.devops.process.yaml.v2.models.YamlTransferData @@ -71,9 +69,7 @@ import com.tencent.devops.process.yaml.v2.models.job.RunsOn import com.tencent.devops.process.yaml.v2.models.job.Service import com.tencent.devops.process.yaml.v2.models.on.DeleteRule import com.tencent.devops.process.yaml.v2.models.on.EnableType -import com.tencent.devops.process.yaml.v2.models.on.IPreTriggerOn import com.tencent.devops.process.yaml.v2.models.on.IssueRule -import com.tencent.devops.process.yaml.v2.models.on.ManualRule import com.tencent.devops.process.yaml.v2.models.on.MrRule import com.tencent.devops.process.yaml.v2.models.on.NoteRule import com.tencent.devops.process.yaml.v2.models.on.PreTriggerOn @@ -92,13 +88,12 @@ import com.tencent.devops.process.yaml.v2.stageCheck.Flow import com.tencent.devops.process.yaml.v2.stageCheck.PreStageCheck import com.tencent.devops.process.yaml.v2.stageCheck.StageCheck import com.tencent.devops.process.yaml.v2.stageCheck.StageReviews -import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 -import org.apache.commons.text.StringEscapeUtils -import org.slf4j.LoggerFactory import java.io.BufferedReader import java.io.StringReader import java.util.Random import java.util.regex.Pattern +import org.apache.commons.text.StringEscapeUtils +import org.slf4j.LoggerFactory @Suppress("MaximumLineLength", "ComplexCondition") object ScriptYmlUtils { @@ -121,9 +116,9 @@ object ScriptYmlUtils { @Throws(JsonProcessingException::class) fun formatYaml(yamlStr: String): String { // replace custom tag -// val yamlNormal = formatYamlCustom(yamlStr) + val yamlNormal = formatYamlCustom(yamlStr) // replace anchor tag - return TransferMapper.formatYaml(yamlStr) + return YamlUtil.loadYamlRetryOnAccident(yamlNormal) } fun parseVersion(yamlStr: String?): YmlVersion? { @@ -293,7 +288,7 @@ object ScriptYmlUtils { return sb.toString() } - fun formatStage(preScriptBuildYaml: PreScriptBuildYamlI, transferData: YamlTransferData? = null): List { + fun formatStage(preScriptBuildYaml: PreScriptBuildYaml, transferData: YamlTransferData?): List { return when { preScriptBuildYaml.steps != null -> { val jobId = randomString(jobNamespace) @@ -329,7 +324,7 @@ object ScriptYmlUtils { } } - fun preJobs2Jobs(preJobs: Map?, transferData: YamlTransferData? = null): List { + fun preJobs2Jobs(preJobs: Map?, transferData: YamlTransferData?): List { if (preJobs == null) { return emptyList() } @@ -457,38 +452,32 @@ object ScriptYmlUtils { // 检测step env合法性 StreamEnvUtils.checkEnv(preStep.env) + val taskId = "e-${UUIDUtil.generate()}" stepList.add( - preStepToStep(preStep, transferData) + Step( + name = preStep.name, + id = preStep.id, + ifFiled = preStep.ifFiled, + ifModify = preStep.ifModify, + uses = preStep.uses, + with = preStep.with, + timeoutMinutes = preStep.timeoutMinutes, + continueOnError = preStep.continueOnError, + retryTimes = preStep.retryTimes, + env = preStep.env, + run = preStep.run, + runAdditionalOptions = mapOf("shell" to preStep.shell), + checkout = preStep.checkout, + taskId = taskId + ) ) + + transferData?.add(taskId, TemplateType.STEP, preStep.yamlMetaData?.templateInfo?.remoteTemplateProjectId) } return stepList } - fun preStepToStep( - preStep: PreStep, - transferData: YamlTransferData? = null - ): Step { - val taskId = "e-${UUIDUtil.generate()}" - transferData?.add(taskId, TemplateType.STEP, preStep.yamlMetaData?.templateInfo?.remoteTemplateProjectId) - return Step( - name = preStep.name, - id = preStep.id, - ifFiled = preStep.ifFiled, - ifModify = preStep.ifModify, - uses = preStep.uses, - with = preStep.with, - timeoutMinutes = preStep.timeoutMinutes, - continueOnError = preStep.continueOnError, - retryTimes = preStep.retryTimes, - env = preStep.env, - run = preStep.run, - runAdditionalOptions = mapOf("shell" to preStep.shell), - checkout = preStep.checkout, - taskId = taskId - ) - } - private fun preStages2Stages(preStageList: List?, transferData: YamlTransferData?): List { if (preStageList == null) { return emptyList() @@ -606,14 +595,14 @@ object ScriptYmlUtils { ) } - fun formatRepoHookTriggerOn(preTriggerOn: IPreTriggerOn?, name: String?): TriggerOn? { + fun formatRepoHookTriggerOn(preTriggerOn: PreTriggerOn?, name: String?): TriggerOn? { if (preTriggerOn?.repoHook == null) { return null } val repositoryHookList = try { YamlUtil.getObjectMapper().readValue( - JsonUtil.toJson(preTriggerOn.repoHook!!), + JsonUtil.toJson(preTriggerOn.repoHook), object : TypeReference>() {} ) } catch (e: MismatchedInputException) { @@ -659,15 +648,14 @@ object ScriptYmlUtils { note = noteRule(repoPreTriggerOn), repoHook = repoHookRule(repositoryHook), manual = manualRule(repoPreTriggerOn), - openapi = openapiRule(repoPreTriggerOn), - remote = remoteRule(repoPreTriggerOn) + openapi = openapiRule(repoPreTriggerOn) ) } logger.warn("repo hook has none effective TriggerOn in ($repositoryHookList)") return null } - fun formatTriggerOn(preTriggerOn: IPreTriggerOn?): TriggerOn { + fun formatTriggerOn(preTriggerOn: PreTriggerOn?): TriggerOn { if (preTriggerOn == null) { return TriggerOn( @@ -687,7 +675,8 @@ object ScriptYmlUtils { ) ) } - val res = TriggerOn( + + return TriggerOn( push = pushRule(preTriggerOn), tag = tagRule(preTriggerOn), mr = mrRule(preTriggerOn), @@ -697,16 +686,8 @@ object ScriptYmlUtils { review = reviewRule(preTriggerOn), note = noteRule(preTriggerOn), manual = manualRule(preTriggerOn), - openapi = openapiRule(preTriggerOn), - remote = remoteRule(preTriggerOn) + openapi = openapiRule(preTriggerOn) ) - - if (preTriggerOn is PreTriggerOnV3) { - res.repoName = preTriggerOn.repoName - res.credentials = preTriggerOn.credentials - } - - return res } fun repoHookRule( @@ -747,28 +728,21 @@ object ScriptYmlUtils { } private fun manualRule( - preTriggerOn: IPreTriggerOn - ): ManualRule? { + preTriggerOn: PreTriggerOn + ): String? { if (preTriggerOn.manual == null) { - return ManualRule() + return null } - return when { - preTriggerOn.manual is String && preTriggerOn.manual == EnableType.TRUE.value -> { - return ManualRule() - } - preTriggerOn.manual is String && preTriggerOn.manual == EnableType.FALSE.value -> { - return null - } - preTriggerOn.manual is Map<*, *> -> kotlin.runCatching { - JsonUtil.anyTo(preTriggerOn.manual, object : TypeReference() {}) - }.getOrElse { ManualRule() } - else -> ManualRule() + if (preTriggerOn.manual != EnableType.TRUE.value && preTriggerOn.manual != EnableType.FALSE.value) { + throw YamlFormatException("not allow manual type ${preTriggerOn.manual}") } + + return preTriggerOn.manual } private fun openapiRule( - preTriggerOn: IPreTriggerOn + preTriggerOn: PreTriggerOn ): String? { if (preTriggerOn.openapi == null) { return null @@ -781,25 +755,11 @@ object ScriptYmlUtils { return preTriggerOn.openapi } - private fun remoteRule( - preTriggerOn: IPreTriggerOn - ): String? { - if (preTriggerOn.remote == null) { - return null - } - - if (preTriggerOn.remote != EnableType.TRUE.value && preTriggerOn.remote != EnableType.FALSE.value) { - throw YamlFormatException("not allow remote type ${preTriggerOn.openapi}") - } - - return preTriggerOn.remote - } - private fun noteRule( - preTriggerOn: IPreTriggerOn + preTriggerOn: PreTriggerOn ): NoteRule? { if (preTriggerOn.note != null) { - val note = preTriggerOn.note!! + val note = preTriggerOn.note return try { YamlUtil.getObjectMapper().readValue( JsonUtil.toJson(note), @@ -813,10 +773,10 @@ object ScriptYmlUtils { } private fun reviewRule( - preTriggerOn: IPreTriggerOn + preTriggerOn: PreTriggerOn ): ReviewRule? { if (preTriggerOn.review != null) { - val issues = preTriggerOn.review!! + val issues = preTriggerOn.review return try { YamlUtil.getObjectMapper().readValue( JsonUtil.toJson(issues), @@ -830,10 +790,10 @@ object ScriptYmlUtils { } private fun issueRule( - preTriggerOn: IPreTriggerOn + preTriggerOn: PreTriggerOn ): IssueRule? { if (preTriggerOn.issue != null) { - val issues = preTriggerOn.issue!! + val issues = preTriggerOn.issue return try { YamlUtil.getObjectMapper().readValue( JsonUtil.toJson(issues), @@ -847,10 +807,10 @@ object ScriptYmlUtils { } private fun deleteRule( - preTriggerOn: IPreTriggerOn + preTriggerOn: PreTriggerOn ): DeleteRule? { if (preTriggerOn.delete != null) { - val delete = preTriggerOn.delete!! + val delete = preTriggerOn.delete return try { YamlUtil.getObjectMapper().readValue( JsonUtil.toJson(delete), @@ -864,26 +824,27 @@ object ScriptYmlUtils { } private fun schedulesRule( - preTriggerOn: IPreTriggerOn - ): List? { + preTriggerOn: PreTriggerOn + ): SchedulesRule? { if (preTriggerOn.schedules != null) { - val schedules = preTriggerOn.schedules!! - return kotlin.runCatching { - when (schedules) { - is Map<*, *> -> listOf(JsonUtil.anyTo(schedules, object : TypeReference() {})) - is List<*> -> JsonUtil.anyTo(schedules, object : TypeReference>() {}) - else -> null - } - }.getOrNull() + val schedules = preTriggerOn.schedules + return try { + YamlUtil.getObjectMapper().readValue( + JsonUtil.toJson(schedules), + SchedulesRule::class.java + ) + } catch (e: MismatchedInputException) { + null + } } return null } private fun mrRule( - preTriggerOn: IPreTriggerOn + preTriggerOn: PreTriggerOn ): MrRule? { if (preTriggerOn.mr != null) { - val mr = preTriggerOn.mr!! + val mr = preTriggerOn.mr return try { YamlUtil.getObjectMapper().readValue( JsonUtil.toJson(mr), @@ -913,10 +874,10 @@ object ScriptYmlUtils { } private fun tagRule( - preTriggerOn: IPreTriggerOn + preTriggerOn: PreTriggerOn ): TagRule? { if (preTriggerOn.tag != null) { - val tag = preTriggerOn.tag!! + val tag = preTriggerOn.tag return try { YamlUtil.getObjectMapper().readValue( JsonUtil.toJson(tag), @@ -945,10 +906,10 @@ object ScriptYmlUtils { } private fun pushRule( - preTriggerOn: IPreTriggerOn + preTriggerOn: PreTriggerOn ): PushRule? { if (preTriggerOn.push != null) { - val push = preTriggerOn.push!! + val push = preTriggerOn.push return try { YamlUtil.getObjectMapper().readValue( JsonUtil.toJson(push), diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/StreamDispatchUtils.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/StreamDispatchUtils.kt new file mode 100644 index 00000000000..92af8cb6681 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/StreamDispatchUtils.kt @@ -0,0 +1,242 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v2.utils + +import com.fasterxml.jackson.core.JsonProcessingException +import com.tencent.devops.common.api.constant.CommonMessageCode.BUILD_RESOURCE_NOT_EXIST +import com.tencent.devops.common.api.exception.CustomException +import com.tencent.devops.common.api.exception.ParamBlankException +import com.tencent.devops.common.api.util.EnvUtils +import com.tencent.devops.common.api.util.JsonUtil +import com.tencent.devops.common.api.util.YamlUtil +import com.tencent.devops.common.pipeline.enums.VMBaseOS +import com.tencent.devops.common.pipeline.type.DispatchType +import com.tencent.devops.common.pipeline.type.agent.AgentType +import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentDockerInfo +import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentEnvDispatchType +import com.tencent.devops.common.pipeline.type.docker.DockerDispatchType +import com.tencent.devops.common.pipeline.type.docker.ImageType +import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.process.pojo.BuildTemplateAcrossInfo +import com.tencent.devops.process.yaml.pojo.ThirdPartyContainerInfo +import com.tencent.devops.process.yaml.v2.models.job.Container +import com.tencent.devops.process.yaml.v2.models.job.Container2 +import com.tencent.devops.process.yaml.v2.models.job.Job +import com.tencent.devops.process.yaml.v2.models.job.JobRunsOnType +import javax.ws.rs.core.Response +import org.slf4j.LoggerFactory +import com.tencent.devops.common.pipeline.type.agent.Credential as thirdPartDockerCredential + +@Suppress("ALL") +object StreamDispatchUtils { + + private val logger = LoggerFactory.getLogger(StreamDispatchUtils::class.java) + + fun getBaseOs(job: Job, context: Map? = null): VMBaseOS { + val poolName = EnvUtils.parseEnv(job.runsOn.poolName, context ?: mapOf()) + // 公共构建机池 + if (poolName == JobRunsOnType.DOCKER.type) { + return VMBaseOS.LINUX + } else if (poolName.startsWith("macos")) { + return VMBaseOS.MACOS + } + + // agentSelector 也要支持占位符 + if (job.runsOn.agentSelector.isNullOrEmpty()) { + return VMBaseOS.ALL + } + return when (EnvUtils.parseEnv(job.runsOn.agentSelector!![0], context ?: mapOf())) { + "linux" -> VMBaseOS.LINUX + "macos" -> VMBaseOS.MACOS + "windows" -> VMBaseOS.WINDOWS + else -> VMBaseOS.LINUX + } + } + + fun getBuildEnv(job: Job, context: Map? = null): Map? { + return if (job.runsOn.selfHosted == false) { + job.runsOn.needs?.map { it -> + it.key to EnvUtils.parseEnv(it.value, context ?: mapOf()) + }?.toMap() + } else { + null + } + } + + @Throws( + JsonProcessingException::class, + ParamBlankException::class, + CustomException::class + ) + fun getDispatchType( + job: Job, + defaultImage: String, + context: Map? = null, + containsMatrix: Boolean? = false, + buildTemplateAcrossInfo: BuildTemplateAcrossInfo? + ): DispatchType { + + val poolName = EnvUtils.parseEnv(job.runsOn.poolName, context ?: mapOf()) + val workspace = EnvUtils.parseEnv(job.runsOn.workspace, context ?: mapOf()) + + // 第三方构建机 + if (job.runsOn.selfHosted == true) { + if (job.runsOn.container == null) { + return ThirdPartyAgentEnvDispatchType( + envProjectId = null, + envName = poolName, + workspace = workspace, + agentType = AgentType.NAME, + dockerInfo = null + ) + } + + val info = parseRunsOnContainer( + job = job, + buildTemplateAcrossInfo = buildTemplateAcrossInfo + ) + + val dockerInfo = ThirdPartyAgentDockerInfo( + image = info.image, + credential = thirdPartDockerCredential( + user = info.userName, + password = info.password, + credentialId = info.credId, + acrossTemplateId = info.acrossTemplateId, + jobId = job.id + ), + options = info.options, + imagePullPolicy = info.imagePullPolicy + ) + + return ThirdPartyAgentEnvDispatchType( + envProjectId = null, + envName = poolName, + workspace = workspace, + agentType = AgentType.NAME, + dockerInfo = dockerInfo + ) + } + + // macos构建机 + if (poolName.startsWith("macos")) { + // 外部版暂时不支持macos构建机,遇到直接报错 + throw CustomException( + Response.Status.BAD_REQUEST, + I18nUtil.getCodeLanMessage(messageCode = BUILD_RESOURCE_NOT_EXIST, params = arrayOf("macos")) + ) + } + + // 公共docker构建机 + if (poolName == "docker") { + var image = defaultImage + var credentialId = "" + var env: Map? + + if (job.runsOn.container != null) { + try { + val container = YamlUtil.getObjectMapper().readValue( + JsonUtil.toJson(job.runsOn.container!!), + Container::class.java + ) + + image = EnvUtils.parseEnv(container.image, context ?: mapOf()) + env = job.env + } catch (e: Exception) { + val container = YamlUtil.getObjectMapper().readValue( + JsonUtil.toJson(job.runsOn.container!!), + Container2::class.java + ) + + image = EnvUtils.parseEnv(container.image, context ?: mapOf()) + credentialId = EnvUtils.parseEnv(container.credentials, context ?: mapOf()) + env = job.env + } + } + + return DockerDispatchType( + dockerBuildVersion = image, + credentialId = credentialId, + imageType = ImageType.THIRD + ) + } + + if (containsMatrix == true) { + return DockerDispatchType(defaultImage) + } else { + throw CustomException( + Response.Status.NOT_FOUND, I18nUtil.getCodeLanMessage( + messageCode = BUILD_RESOURCE_NOT_EXIST, + params = arrayOf("public") + ) + ) + } + } + + /** + * 解析 jobs.runsOn.container + * 注:因为要蓝盾也要支持所以环境变量替换会在蓝盾层面去做 + * @return image,username,password + */ + fun parseRunsOnContainer( + job: Job, + buildTemplateAcrossInfo: BuildTemplateAcrossInfo? + ): ThirdPartyContainerInfo { + return try { + val container = YamlUtil.getObjectMapper().readValue( + JsonUtil.toJson(job.runsOn.container!!), + Container::class.java + ) + + ThirdPartyContainerInfo( + image = container.image, + userName = container.credentials?.username, + password = container.credentials?.password, + credId = null, + acrossTemplateId = null, + options = container.options, + imagePullPolicy = container.imagePullPolicy + ) + } catch (e: Exception) { + val container = YamlUtil.getObjectMapper().readValue( + JsonUtil.toJson(job.runsOn.container!!), + Container2::class.java + ) + + ThirdPartyContainerInfo( + image = container.image, + userName = null, + password = null, + credId = container.credentials, + acrossTemplateId = buildTemplateAcrossInfo?.templateId, + options = container.options, + imagePullPolicy = container.imagePullPolicy + ) + } + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/StreamEnvUtils.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/StreamEnvUtils.kt index 31c3b4bd06d..43977e8841a 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/StreamEnvUtils.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/utils/StreamEnvUtils.kt @@ -30,11 +30,10 @@ package com.tencent.devops.process.yaml.v2.utils import com.tencent.devops.common.api.constant.CommonMessageCode.ERROR_YAML_FORMAT_EXCEPTION_ENV_QUANTITY_LIMIT_EXCEEDED import com.tencent.devops.common.api.constant.CommonMessageCode.ERROR_YAML_FORMAT_EXCEPTION_ENV_VARIABLE_LENGTH_LIMIT_EXCEEDED import com.tencent.devops.common.web.utils.I18nUtil -import com.tencent.devops.process.yaml.pojo.TemplatePath import com.tencent.devops.process.yaml.v2.exception.YamlFormatException object StreamEnvUtils { - fun checkEnv(env: Map?, fileName: TemplatePath? = null): Boolean { + fun checkEnv(env: Map?, fileName: String? = null): Boolean { if (env != null) { if (env.size > 100) { throw YamlFormatException( diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/enums/StreamTriggerAction.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/enums/StreamTriggerAction.kt new file mode 100644 index 00000000000..c041c360da9 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/enums/StreamTriggerAction.kt @@ -0,0 +1,59 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.enums + +enum class StreamTriggerAction + +enum class StreamObjectKind(val value: String) { + PUSH("push"), + TAG_PUSH("tag_push"), + MERGE_REQUEST("merge_request"), + PULL_REQUEST("pull_request"), + MANUAL("manual"), + SCHEDULE("schedule"), + DELETE("delete"), + OPENAPI("openApi"), + ISSUE("issue"), + REVIEW("review"), + NOTE("note"); +} + +fun StreamObjectKind.needInput() = this == StreamObjectKind.MANUAL || this == StreamObjectKind.OPENAPI + +enum class StreamPushActionType(val value: String) { + NEW_BRANCH("new-branch"), + PUSH_FILE("push-file"); +} + +enum class StreamMrEventAction(val value: String) { + OPEN("open"), + CLOSE("close"), + REOPEN("reopen"), + PUSH_UPDATE("push-update"), + MERGE("merge"); +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/enums/TemplateType.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/enums/TemplateType.kt new file mode 100644 index 00000000000..feea3abad29 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/enums/TemplateType.kt @@ -0,0 +1,43 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.enums + +/** + * 模板类型,text为展示内容,content为模板在Yaml中的关键字 + */ +enum class TemplateType(val text: String, val content: String) { + TRIGGER_ON("triggerOn", "on"), + VARIABLE("variable", "variables"), + STAGE("stage", "stages"), + JOB("job", "jobs"), + STEP("step", "steps"), + FINALLY("finally", "finally"), + EXTEND("extend", "extend"), + GATE("gate", "gates"), + PARAMETERS("parameter", "parameters") +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/exception/YamlTemplateException.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/exception/YamlTemplateException.kt new file mode 100644 index 00000000000..2f28f7947f1 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/exception/YamlTemplateException.kt @@ -0,0 +1,32 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.exception + +open class YamlTemplateException(message: String? = null) : RuntimeException(message) + +class YamlFormatException(message: String, messageParams: List? = null) : YamlTemplateException(message) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Concurrency.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Concurrency.kt new file mode 100644 index 00000000000..24ce8799d0e --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Concurrency.kt @@ -0,0 +1,44 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class Concurrency( + val group: String?, + @JsonProperty("cancel-in-progress") + val cancelInProgress: Boolean?, + @JsonProperty("queue-length") + val queueLength: Int?, + @JsonProperty("queue-timeout-minutes") + val queueTimeoutMinutes: Int? +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Extends.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Extends.kt new file mode 100644 index 00000000000..d2ae773174d --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Extends.kt @@ -0,0 +1,45 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.tencent.devops.process.yaml.v3.models.job.IPreJob +import com.tencent.devops.process.yaml.v3.models.stage.IPreStage +import com.tencent.devops.process.yaml.v3.models.step.IPreStep + +/** + * model + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class Extends( + val template: String, + val parameters: Map?, + val ref: String? +) : IPreStep, IPreJob, IPreStage diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/IfType.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/IfType.kt new file mode 100644 index 00000000000..a2a911be029 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/IfType.kt @@ -0,0 +1,37 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +enum class IfType { + SUCCESS, + FAILURE, + CANCELLED, // 兼容存量的使用,后续文档引导用户使用 CANCELED + CANCELED, + ALWAYS, + ALWAYS_UNLESS_CANCELLED +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Notices.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Notices.kt new file mode 100644 index 00000000000..15c1cf1cac2 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Notices.kt @@ -0,0 +1,196 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.common.pipeline.pojo.setting.PipelineSubscriptionType +import com.tencent.devops.common.pipeline.pojo.setting.Subscription +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault +import io.swagger.annotations.ApiModelProperty + +/** + * model Stream 通知类型基类 + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +interface Notices { + fun toSubscription() = Subscription() + + fun checkNotifyForSuccess() = false + + fun checkNotifyForFail() = false +} + +/** + * model Stream Yaml基本通知 + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class GitNotices( + val type: String, + val receivers: Set?, + val title: String?, + val content: String?, + val ccs: Set?, + @ApiModelProperty(name = "if") + @JsonProperty("if") + val ifField: String?, + @ApiModelProperty(name = "chat-id") + @JsonProperty("chat-id") + val chatId: Set? +) : Notices { + + constructor(subscription: Subscription, ifField: String?) : this( + type = subscription.types.map { PacNotices.toNotifyType(it) }.toMutableList().apply { sort() }.also { + if (subscription.wechatGroupFlag) it.add(NotifyType.RTX_GROUP.yamlText) + }.first(), + receivers = subscription.users.split(",").ifEmpty { null }?.toSet(), + title = null, + content = subscription.content.ifEmpty { null }, + ccs = null, + ifField = ifField, + chatId = subscription.wechatGroup.split(",").ifEmpty { null }?.toSet() + ) + + override fun toSubscription() = Subscription( + types = setOf(PacNotices.toPipelineSubscriptionType(type)), + groups = emptySet(), + users = receivers?.joinToString(",") ?: "", + wechatGroupFlag = type.contains(NotifyType.RTX_GROUP.yamlText), + wechatGroup = chatId?.joinToString(",") ?: "", + wechatGroupMarkdownFlag = false, + detailFlag = false, + content = content ?: "" + ) + + override fun checkNotifyForSuccess(): Boolean { + return ifField == null || ifField == IfType.SUCCESS.name || ifField == IfType.ALWAYS.name + } + + override fun checkNotifyForFail(): Boolean { + return ifField == null || ifField == IfType.FAILURE.name || ifField == IfType.ALWAYS.name + } +} + +/** + * pac 通知 + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class PacNotices( + @ApiModelProperty(name = "if") + @JsonProperty("if") + val ifField: String?, + val type: List, + val receivers: List?, + val groups: List?, + val content: String?, + @ApiModelProperty(name = "chat-id") + @JsonProperty("chat-id") + val chatId: List?, + @ApiModelProperty(name = "notify-markdown") + @JsonProperty("notify-markdown") + val notifyMarkdown: Boolean?, + @ApiModelProperty(name = "notify-detail-url") + @JsonProperty("notify-detail-url") + val notifyDetail: Boolean? +) : Notices { + + constructor(subscription: Subscription, ifField: String?) : this( + type = subscription.types.map { toNotifyType(it) }.toMutableList().apply { sort() }.also { + if (subscription.wechatGroupFlag) it.add(NotifyType.RTX_GROUP.yamlText) + }, + receivers = subscription.users.ifBlank { null }?.split(",")?.toSet()?.toList(), + groups = subscription.groups.ifEmpty { null }?.sorted(), + content = subscription.content.ifEmpty { null }, + ifField = ifField, + chatId = subscription.wechatGroup.ifBlank { null }?.split(",")?.toSet()?.toList(), + notifyMarkdown = subscription.wechatGroupMarkdownFlag.nullIfDefault(false), + notifyDetail = subscription.detailFlag.nullIfDefault(false) + ) + + companion object { + fun toPipelineSubscriptionType(type: String) = when (type) { + NotifyType.EMAIL.yamlText -> PipelineSubscriptionType.EMAIL + NotifyType.RTX_CUSTOM.yamlText -> PipelineSubscriptionType.RTX + NotifyType.SMS.yamlText -> PipelineSubscriptionType.SMS + else -> PipelineSubscriptionType.RTX + } + + fun toNotifyType(type: PipelineSubscriptionType) = when (type) { + PipelineSubscriptionType.EMAIL -> NotifyType.EMAIL.yamlText + PipelineSubscriptionType.RTX -> NotifyType.RTX_CUSTOM.yamlText + PipelineSubscriptionType.SMS -> NotifyType.SMS.yamlText + else -> NotifyType.RTX_GROUP.yamlText + } + } + + override fun toSubscription() = Subscription( + types = type.map { toPipelineSubscriptionType(it) }.toSet(), + groups = groups?.toSet() ?: emptySet(), + users = receivers?.joinToString(",") ?: "", + wechatGroupFlag = type.contains(NotifyType.RTX_GROUP.yamlText), + wechatGroup = chatId?.joinToString(",") ?: "", + wechatGroupMarkdownFlag = notifyMarkdown ?: false, + detailFlag = notifyDetail ?: false, + content = content ?: "" + ) + + override fun checkNotifyForSuccess(): Boolean { + return ifField == null || ifField == IfType.SUCCESS.name || ifField == IfType.ALWAYS.name + } + + override fun checkNotifyForFail(): Boolean { + return ifField == null || ifField == IfType.FAILURE.name || ifField == IfType.ALWAYS.name + } +} + +enum class NotifyType(val yamlText: String) { + // 企业微信客服 + SMS("sms"), + + RTX_CUSTOM("wework-message"), + + // 邮件 + EMAIL("email"), + + // 企业微信群 + RTX_GROUP("wework-chat"); +} + +/** + * model Stream 质量红线通知 + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +class GateNotices( + val type: String, + val receivers: Set? +) : Notices diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreScriptBuildYaml.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreScriptBuildYaml.kt new file mode 100644 index 00000000000..a577a85dab7 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreScriptBuildYaml.kt @@ -0,0 +1,81 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.process.yaml.pojo.YamlVersion +import com.tencent.devops.process.yaml.v3.models.job.PreJob +import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOn +import com.tencent.devops.process.yaml.v3.models.stage.PreStage +import com.tencent.devops.process.yaml.v3.models.step.PreStep + +/** + * PreScriptBuildYamlI 是PreScriptBuildYaml的拓展,方便再既不修改data class的特性情况下,其他类可以在继承新增字段 + * 注:PreScriptBuildYaml 新增的字段需要在这里新增 + */ +interface PreScriptBuildYamlI : YamlVersion { + var version: String? + var name: String? + var label: List? + var variables: Map? + var stages: List? + var jobs: Map? + var steps: List? + var extends: Extends? + var resources: Resources? + var finally: Map? + val concurrency: Concurrency? +} + +/** + * model + * + * WARN: 请谨慎修改这个类 , 不要随意添加或者删除变量 , 否则可能导致依赖yaml的功能(stream,prebuild等)异常 + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class PreScriptBuildYaml( + override var version: String?, + override var name: String?, + override var label: List? = null, + @JsonProperty("on") + var triggerOn: PreTriggerOn?, + override var variables: Map? = null, + override var stages: List? = null, + override var jobs: Map? = null, + override var steps: List? = null, + override var extends: Extends? = null, + override var resources: Resources?, + var notices: List?, + override var finally: Map? = null, + override val concurrency: Concurrency? = null +) : PreScriptBuildYamlI { + override fun yamlVersion() = YamlVersion.Version.V2_0 +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreScriptBuildYamlV3.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreScriptBuildYamlV3.kt index a2fd2f23469..eda16dddce4 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreScriptBuildYamlV3.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreScriptBuildYamlV3.kt @@ -31,15 +31,15 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty import com.tencent.devops.process.yaml.pojo.YamlVersion -import com.tencent.devops.process.yaml.v2.models.Concurrency -import com.tencent.devops.process.yaml.v2.models.Extends -import com.tencent.devops.process.yaml.v2.models.PacNotices -import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYamlI -import com.tencent.devops.process.yaml.v2.models.Resources -import com.tencent.devops.process.yaml.v2.models.Variable -import com.tencent.devops.process.yaml.v2.models.job.PreJob -import com.tencent.devops.process.yaml.v2.models.stage.PreStage -import com.tencent.devops.process.yaml.v2.models.step.PreStep +import com.tencent.devops.process.yaml.v3.models.Concurrency +import com.tencent.devops.process.yaml.v3.models.Extends +import com.tencent.devops.process.yaml.v3.models.PacNotices +import com.tencent.devops.process.yaml.v3.models.PreScriptBuildYamlI +import com.tencent.devops.process.yaml.v3.models.Resources +import com.tencent.devops.process.yaml.v3.models.Variable +import com.tencent.devops.process.yaml.v3.models.job.PreJob +import com.tencent.devops.process.yaml.v3.models.stage.PreStage +import com.tencent.devops.process.yaml.v3.models.step.PreStep import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 /** diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYaml.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYaml.kt new file mode 100644 index 00000000000..d8128f7e15a --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYaml.kt @@ -0,0 +1,162 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +import com.fasterxml.jackson.annotation.JsonIgnore +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.fasterxml.jackson.annotation.JsonSubTypes +import com.fasterxml.jackson.annotation.JsonTypeInfo +import com.tencent.devops.common.api.enums.ScmType +import com.tencent.devops.process.yaml.pojo.YamlVersion +import com.tencent.devops.process.yaml.v3.models.job.Job +import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOn +import com.tencent.devops.process.yaml.v3.models.on.TriggerOn +import com.tencent.devops.process.yaml.v3.models.stage.Stage +import com.tencent.devops.process.yaml.v3.utils.ScriptYmlUtils +import com.tencent.devops.process.yaml.v3.models.PreTemplateScriptBuildYamlV3 +import com.tencent.devops.process.yaml.v3.models.TriggerType + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.EXISTING_PROPERTY, + property = "version", + defaultImpl = PreTemplateScriptBuildYaml::class +) +@JsonSubTypes( + JsonSubTypes.Type(value = PreTemplateScriptBuildYamlV3::class, name = YamlVersion.Version.V3), + JsonSubTypes.Type(value = PreTemplateScriptBuildYaml::class, name = YamlVersion.Version.V2) +) +interface IPreTemplateScriptBuildYaml : YamlVersion { + val version: String? + val name: String? + val label: List? + val notices: List? + val concurrency: Concurrency? + + fun replaceTemplate(f: (param: ITemplateFilter) -> PreScriptBuildYamlI) + + fun formatVariables(): Map + + fun formatTriggerOn(default: ScmType): List> + + fun formatStages(): List + + fun formatFinallyStage(): List + + fun formatResources(): Resources? +} + +/* +* ITemplateFilter 为模板替换所需材料 +*/ +interface ITemplateFilter : YamlVersion { + val variables: Map? + val stages: List>? + val jobs: Map? + val steps: List>? + val extends: Extends? + val resources: Resources? + var finally: Map? + + fun initPreScriptBuildYamlI(): PreScriptBuildYamlI +} + +/** + * model + * + * WARN: 请谨慎修改这个类 , 不要随意添加或者删除变量 , 否则可能导致依赖yaml的功能(gitci,prebuild等)异常 + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class PreTemplateScriptBuildYaml( + override val version: String?, + override val name: String?, + override val label: List? = null, + @JsonProperty("on") + val triggerOn: PreTriggerOn?, + override val variables: Map?, + override val stages: List>?, + override val jobs: Map? = null, + override val steps: List>? = null, + override val extends: Extends?, + override val resources: Resources?, + override var finally: Map?, + override val notices: List?, + override val concurrency: Concurrency? = null +) : IPreTemplateScriptBuildYaml, ITemplateFilter { + override fun yamlVersion() = YamlVersion.Version.V2_0 + + override fun initPreScriptBuildYamlI(): PreScriptBuildYamlI { + return PreScriptBuildYaml( + version = version, + name = name, + label = label, + triggerOn = triggerOn, + resources = resources, + notices = notices, + concurrency = concurrency + ) + } + + @JsonIgnore + lateinit var preYaml: PreScriptBuildYaml + + override fun replaceTemplate(f: (param: ITemplateFilter) -> PreScriptBuildYamlI) { + preYaml = f(this) as PreScriptBuildYaml + } + + override fun formatVariables(): Map { + checkInitialized() + return preYaml.variables ?: emptyMap() + } + + override fun formatTriggerOn(default: ScmType): List> { + return listOf(TriggerType.parse(default) to ScriptYmlUtils.formatTriggerOn(triggerOn)) + } + + override fun formatStages(): List { + checkInitialized() + return ScriptYmlUtils.formatStage(preYaml) + } + + override fun formatFinallyStage(): List { + checkInitialized() + return ScriptYmlUtils.preJobs2Jobs(preYaml.finally) + } + + override fun formatResources(): Resources? { + checkInitialized() + return preYaml.resources + } + + private fun checkInitialized() { + if (!this::preYaml.isInitialized) throw RuntimeException("need replaceTemplate before") + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYamlV3.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYamlV3.kt index e5a90e8ccd2..423be5d7b04 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYamlV3.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/PreTemplateScriptBuildYamlV3.kt @@ -35,19 +35,19 @@ import com.fasterxml.jackson.core.type.TypeReference import com.tencent.devops.common.api.enums.ScmType import com.tencent.devops.common.api.util.JsonUtil import com.tencent.devops.process.yaml.pojo.YamlVersion -import com.tencent.devops.process.yaml.v2.models.Concurrency -import com.tencent.devops.process.yaml.v2.models.Extends -import com.tencent.devops.process.yaml.v2.models.IPreTemplateScriptBuildYaml -import com.tencent.devops.process.yaml.v2.models.ITemplateFilter -import com.tencent.devops.process.yaml.v2.models.PacNotices -import com.tencent.devops.process.yaml.v2.models.PreScriptBuildYamlI -import com.tencent.devops.process.yaml.v2.models.Resources -import com.tencent.devops.process.yaml.v2.models.Variable -import com.tencent.devops.process.yaml.v2.models.YamlTransferData -import com.tencent.devops.process.yaml.v2.models.job.Job -import com.tencent.devops.process.yaml.v2.models.on.TriggerOn -import com.tencent.devops.process.yaml.v2.models.stage.Stage -import com.tencent.devops.process.yaml.v2.utils.ScriptYmlUtils +import com.tencent.devops.process.yaml.v3.models.Concurrency +import com.tencent.devops.process.yaml.v3.models.Extends +import com.tencent.devops.process.yaml.v3.models.IPreTemplateScriptBuildYaml +import com.tencent.devops.process.yaml.v3.models.ITemplateFilter +import com.tencent.devops.process.yaml.v3.models.PacNotices +import com.tencent.devops.process.yaml.v3.models.PreScriptBuildYamlI +import com.tencent.devops.process.yaml.v3.models.Resources +import com.tencent.devops.process.yaml.v3.models.Variable +import com.tencent.devops.process.yaml.v3.models.YamlTransferData +import com.tencent.devops.process.yaml.v3.models.job.Job +import com.tencent.devops.process.yaml.v3.models.on.TriggerOn +import com.tencent.devops.process.yaml.v3.models.stage.Stage +import com.tencent.devops.process.yaml.v3.utils.ScriptYmlUtils import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 @JsonInclude(JsonInclude.Include.NON_NULL) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/RepositoryHook.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/RepositoryHook.kt new file mode 100644 index 00000000000..5362275100a --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/RepositoryHook.kt @@ -0,0 +1,80 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.process.yaml.v3.models.on.DeleteRule +import com.tencent.devops.process.yaml.v3.models.on.IssueRule +import com.tencent.devops.process.yaml.v3.models.on.NoteRule +import com.tencent.devops.process.yaml.v3.models.on.ReviewRule +import com.tencent.devops.process.yaml.v3.models.on.SchedulesRule + +/** + * model + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class PreRepositoryHook( + val name: String? = null, + + val credentials: Any? = null, + + val events: RepositoryHookEvents? = null, + @JsonProperty("repos_ignore") + val reposIgnore: List = emptyList(), + @JsonProperty("repos_ignore_condition") + val reposIgnoreCondition: List = emptyList() +) + +data class RepositoryHook( + val name: String? = null, + + val credentialsForTicketId: String? = null, + + val credentialsForUserName: String? = null, + + val credentialsForPassword: String? = null, + + val credentialsForToken: String? = null, + val reposIgnore: List = emptyList(), + val reposIgnoreCondition: List = emptyList() + +) + +data class RepositoryHookEvents( + val push: Any? = null, + val tag: Any? = null, + val mr: Any? = null, + val schedules: SchedulesRule? = null, + val delete: DeleteRule? = null, + val issue: IssueRule? = null, + val review: ReviewRule? = null, + val note: NoteRule? = null +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Resources.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Resources.kt new file mode 100644 index 00000000000..26563d8e965 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Resources.kt @@ -0,0 +1,64 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import io.swagger.annotations.ApiModelProperty + +/** + * model + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class Resources( + val repositories: List?, + val pools: List? +) + +data class Repositories( + val repository: String, + val name: String, + val ref: String?, + val credentials: ResCredentials? +) + +data class ResCredentials( + @ApiModelProperty(name = "personal-access-token") + @JsonProperty("personal-access-token") + val personalAccessToken: String? +) + +data class ResourcesPools( + val from: String?, + val name: String? +) + +// 确定pool作为map的唯一性,修改pool对象时同步修改 +fun ResourcesPools.format() = "${this.from}+${this.name}" diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/ScriptBuildYaml.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/ScriptBuildYaml.kt new file mode 100644 index 00000000000..65872f42f7f --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/ScriptBuildYaml.kt @@ -0,0 +1,60 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.process.yaml.pojo.YamlVersion +import com.tencent.devops.process.yaml.v3.models.job.Job +import com.tencent.devops.process.yaml.v3.models.on.TriggerOn +import com.tencent.devops.process.yaml.v3.models.stage.Stage + +/** + * model + * + * WARN: 请谨慎修改这个类 , 不要随意添加或者删除变量 , 否则可能导致依赖yaml的功能(gitci,prebuild等)异常 + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class ScriptBuildYaml( + val version: String?, + val name: String?, + val label: List?, + @JsonProperty("on") + val triggerOn: TriggerOn?, + val variables: Map?, + val stages: List, + val extends: Extends?, + val resource: Resources?, + val notices: List?, + var finally: List?, + val concurrency: Concurrency? +) : YamlVersion { + override fun yamlVersion() = YamlVersion.Version.V2_0 +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/ScriptBuildYamlV3.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/ScriptBuildYamlV3.kt index b47ce07f1ad..ab713b8e67a 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/ScriptBuildYamlV3.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/ScriptBuildYamlV3.kt @@ -30,14 +30,14 @@ package com.tencent.devops.process.yaml.v3.models import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.tencent.devops.process.yaml.pojo.YamlVersion -import com.tencent.devops.process.yaml.v2.models.Concurrency -import com.tencent.devops.process.yaml.v2.models.Extends -import com.tencent.devops.process.yaml.v2.models.GitNotices -import com.tencent.devops.process.yaml.v2.models.Resources -import com.tencent.devops.process.yaml.v2.models.Variable -import com.tencent.devops.process.yaml.v2.models.job.Job -import com.tencent.devops.process.yaml.v2.models.on.TriggerOn -import com.tencent.devops.process.yaml.v2.models.stage.Stage +import com.tencent.devops.process.yaml.v3.models.Concurrency +import com.tencent.devops.process.yaml.v3.models.Extends +import com.tencent.devops.process.yaml.v3.models.GitNotices +import com.tencent.devops.process.yaml.v3.models.Resources +import com.tencent.devops.process.yaml.v3.models.Variable +import com.tencent.devops.process.yaml.v3.models.job.Job +import com.tencent.devops.process.yaml.v3.models.on.TriggerOn +import com.tencent.devops.process.yaml.v3.models.stage.Stage /** * model diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Template.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Template.kt new file mode 100644 index 00000000000..67778a0f9f5 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Template.kt @@ -0,0 +1,34 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +data class Template( + val template: String, + val ref: String?, + val parameters: Map? +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Variable.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Variable.kt new file mode 100644 index 00000000000..2aff45ed90a --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/Variable.kt @@ -0,0 +1,207 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.common.pipeline.enums.BuildFormPropertyType +import com.tencent.devops.common.pipeline.pojo.BuildContainerType +import io.swagger.annotations.ApiModelProperty + +// @JsonDeserialize(using = IVariableDeserializer::class) +interface IVariable +// +// class IVariableDeserializer : StdDeserializer(IVariable::class.java) { +// override fun deserialize(p: JsonParser, ctxt: DeserializationContext): IVariable { +// val node: JsonNode = p.codec.readTree(p) +// return when (node) { +// is ObjectNode -> Variable( +// value = node.get(Variable::value.name)?.asText(), +// readonly = node.get(Variable::readonly.name)?.asBoolean(), +// allowModifyAtStartup = node.get(Variable::allowModifyAtStartup.name)?.asBoolean(), +// props = JsonUtil.toOrNull( +// node.get(Variable::props.name)?.toString(), object : TypeReference() {}), +// ) +// is ArrayNode -> TemplateVariable(JsonUtil.to(node.toString(), object : TypeReference>() {})) +// is TextNode -> ShortVariable(node.toString()) +// else -> throw Exception("") +// } +// } +// } +// +// class IVariableSerializer : StdSerializer(IVariable::class.java) { +// override fun serialize(value: IVariable, gen: JsonGenerator, provider: SerializerProvider) { +// when (value) { +// is ShortVariable -> gen.writeString(value.value) +// is Variable -> gen.writeObject(value.toMap()) +// is TemplateVariable -> gen.writeObject(value.toList()) +// } +// } +// } + +/** + * Variable model + * @param allowModifyAtStartup 手动触发/openapi触发时生效 + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class Variable( + val value: String?, + val readonly: Boolean? = false, + @JsonProperty("allow-modify-at-startup") + val allowModifyAtStartup: Boolean? = false, + @JsonProperty("value-not-empty") + val valueNotEmpty: Boolean? = false, + val props: VariableProps? = null +) : IVariable + +data class ShortVariable(val value: String) : IVariable + +data class TemplateVariable(private val list: List) : List by list, IVariable + +/** + * Variable 属性变量 + * @param label 可选, 预定义下拉可选值的字段 + * @param type 类型 + * @param options 下拉列表可选值,和 datasource 二选一 + * @param datasource 下拉列表数据源,和 values 二选一 + * @param multiple 是否允许多选,缺省时为 false(type=selector时生效) + * @param description 可选,描述 + * @param required 可选,是否必填 + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class VariableProps( + val label: String? = null, + val type: String, + val options: List? = null, + val datasource: VariableDatasource? = null, + val description: String? = null, + val multiple: Boolean? = null, + val required: Boolean? = null, + val repoHashId: String? = null, + val scmType: String? = null, + val containerType: BuildContainerType? = null, + @ApiModelProperty("自定义仓库通配符", required = false) + val glob: String? = null, + @ApiModelProperty("文件元数据", required = false) + val properties: Map? = null, + val payload: Any? = null, +) + +/** + * Variable 属性中的选项对象 + * @param id 预定义下拉可选值的字段 + * @param label 可选, 选项说明 + * @param description 可选, 选项描述 + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class VariablePropOption( + val id: Any, + val label: String? = null, + val description: String? = null +) + +/** + * Variable Url子属性 + * @param url 请求数据的地址 + * @param dataPath 可选,选项列表数据所在的、API返回体json中的路径,没有此字段则默认为data, 示例:data.detail.list。配合url使用 + * @param paramId 可选,url返回规范中,用于下拉列表选项key的字段名,配合url使用 + * @param paramName 可选,url返回规范中,用于下拉列表选项label的字段名,配合url使用 + * @param hasAddItem 可选,是否有新增按钮 + * @param itemText 可选,新增按钮文字描述 + * @param itemTargetUrl 可选,点击新增按钮的跳转地址 + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class VariableDatasource( + val url: String, + @JsonProperty("data-path") + val dataPath: String? = null, + @JsonProperty("param-id") + val paramId: String? = null, + @JsonProperty("param-name") + val paramName: String? = null, + @JsonProperty("has-add-item") + val hasAddItem: Boolean? = true, + @JsonProperty("item-text") + val itemText: String? = null, + @JsonProperty("item-target-url") + val itemTargetUrl: String? = null +) + +enum class VariablePropType(val value: String) { + VUEX_INPUT("vuex-input"), + VUEX_TEXTAREA("vuex-textarea"), + SELECTOR("selector"), + CHECKBOX("checkbox"), + BOOLEAN("boolean"), + TIME_PICKER("time-picker"), + COMPANY_STAFF_INPUT("company-staff-input"), + GIT_REF("git_ref"), + CODE_LIB("code_lib"), + CONTAINER_TYPE("container_type"), + ARTIFACTORY("artifactory"), + SUB_PIPELINE("sub_pipeline"), + CUSTOM_FILE("custom_file"), + TIPS("tips"); + + + fun toBuildFormPropertyType() = when (this) { + VUEX_INPUT -> BuildFormPropertyType.STRING + VUEX_TEXTAREA -> BuildFormPropertyType.TEXTAREA + SELECTOR -> BuildFormPropertyType.ENUM + CHECKBOX -> BuildFormPropertyType.MULTIPLE + BOOLEAN -> BuildFormPropertyType.BOOLEAN + GIT_REF -> BuildFormPropertyType.GIT_REF + CODE_LIB -> BuildFormPropertyType.CODE_LIB + CONTAINER_TYPE -> BuildFormPropertyType.CONTAINER_TYPE + ARTIFACTORY -> BuildFormPropertyType.ARTIFACTORY + SUB_PIPELINE -> BuildFormPropertyType.SUB_PIPELINE + CUSTOM_FILE -> BuildFormPropertyType.CUSTOM_FILE + else -> BuildFormPropertyType.STRING + } + + companion object { + fun findType(value: String?): VariablePropType? { + if (value.isNullOrBlank()) { + return null + } + + values().forEach { + if (it.value == value) { + return it + } + } + + return null + } + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/YamlMetaData.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/YamlMetaData.kt new file mode 100644 index 00000000000..003b409026d --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/YamlMetaData.kt @@ -0,0 +1,51 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +/** + * 当前Yaml对象的元数据,用来添加一些额外的信息字段 + * 仅内部逻辑使用,不对外 + */ +interface YamlMetaData { + val yamlMetaData: MetaData? +} + +data class MetaData( + var templateInfo: TemplateInfo? +) + +/** + * 当前Yaml对象是否来自模板引用 + */ +data class TemplateInfo( + // 是否为远程模板 + val remote: Boolean, + val remoteTemplateProjectId: String? = null +) + +const val YAME_META_DATA_JSON_FILTER = "yamlMetaData" diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/YamlTransferData.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/YamlTransferData.kt new file mode 100644 index 00000000000..1ef5c3bb035 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/YamlTransferData.kt @@ -0,0 +1,68 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +import com.tencent.devops.common.api.util.UUIDUtil +import com.tencent.devops.process.yaml.v3.enums.TemplateType +import com.tencent.devops.process.yaml.v3.exception.YamlFormatException + +/** + * 从preYaml转向Yaml产生的内部使用而不暴露的中间数据 + * 如:Yaml对象的模板信息,用来分享凭证 + */ +data class YamlTransferData( + val templateData: TemplateData = TemplateData() +) + +data class TemplateData( + val templateId: String = "t-${UUIDUtil.generate()}", + // Map + val transferDataMap: MutableMap = mutableMapOf() +) + +data class TransferTemplateData( + val objectId: String, + val templateType: TemplateType, + val remoteProjectId: String +) + +fun YamlTransferData.add(objectId: String, templateType: TemplateType, remoteProjectId: String?) { + if (remoteProjectId == null) { + return + } + + if (templateData.transferDataMap[objectId] != null) { + throw YamlFormatException("step or job id $objectId is not unique") + } + + templateData.transferDataMap[objectId] = TransferTemplateData( + objectId = objectId, + templateType = templateType, + remoteProjectId = remoteProjectId + ) +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/YmlName.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/YmlName.kt new file mode 100644 index 00000000000..6b4d90ebff7 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/YmlName.kt @@ -0,0 +1,37 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class YmlName( + val name: String? +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/YmlVersion.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/YmlVersion.kt new file mode 100644 index 00000000000..96e408d89e9 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/YmlVersion.kt @@ -0,0 +1,37 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class YmlVersion( + val version: String? +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/export/ExportPreScriptBuildYaml.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/export/ExportPreScriptBuildYaml.kt new file mode 100644 index 00000000000..513de4a123b --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/export/ExportPreScriptBuildYaml.kt @@ -0,0 +1,60 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.export + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.tencent.devops.process.yaml.v3.models.Extends +import com.tencent.devops.process.yaml.v3.models.GitNotices +import com.tencent.devops.process.yaml.v3.models.Resources +import com.tencent.devops.process.yaml.v3.models.job.PreJob +import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOn +import com.tencent.devops.process.yaml.v3.models.stage.PreStage +import com.tencent.devops.process.yaml.v3.models.step.PreStep + +/** + * model + * + * WARN: 该类需要与 PreScriptBuildYaml.kt 保持同步修改 + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class ExportPreScriptBuildYaml( + var version: String?, + var name: String?, + var label: List? = null, + var triggerOn: PreTriggerOn?, + var variables: Map? = null, + var stages: List? = null, + var jobs: Map? = null, + var steps: List? = null, + var extends: Extends? = null, + var resources: Resources?, + var notices: List?, + var finally: Map? = null +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/gate/ContinueOnFail.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/gate/ContinueOnFail.kt new file mode 100644 index 00000000000..fa0094d20b0 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/gate/ContinueOnFail.kt @@ -0,0 +1,32 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.gate + +data class ContinueOnFail( + val gatekeepers: List +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/image/Credential.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/image/Credential.kt new file mode 100644 index 00000000000..4bf7147be8a --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/image/Credential.kt @@ -0,0 +1,39 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.image + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class Credential( + val user: String?, + val password: String?, + val credentialId: String? = null +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/image/Pool.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/image/Pool.kt new file mode 100644 index 00000000000..3b8a45edeb6 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/image/Pool.kt @@ -0,0 +1,66 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.image + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.tencent.devops.common.pipeline.enums.VMBaseOS +import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentDockerInfo +import com.tencent.devops.common.pipeline.type.docker.ImageType + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class Pool( + val container: String? = null, + val credentialId: String? = null, + val third: Boolean? = null, + val performanceConfigId: String? = "0", + val env: Map? = mapOf(), + val type: PoolType? = null, + val agentName: String? = null, + val agentId: String? = null, + val envName: String? = null, + val envProjectId: String? = null, + val envId: String? = null, + val os: VMBaseOS? = null, + val workspace: String? = null, + val buildType: BuildType? = BuildType.DEVCLOUD, + val dockerInfo: ThirdPartyAgentDockerInfo? = null, + val image: PoolImage? = null +) + +data class PoolImage( + val imageCode: String, + val imageVersion: String, + val imageType: ImageType? = ImageType.THIRD +) + +enum class BuildType { + DOCKER_VM, + DEVCLOUD +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/image/PoolType.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/image/PoolType.kt new file mode 100644 index 00000000000..43ed890cff7 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/image/PoolType.kt @@ -0,0 +1,201 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.image + +import com.tencent.devops.common.api.exception.OperationException +import com.tencent.devops.common.pipeline.type.DispatchType +import com.tencent.devops.common.pipeline.type.agent.AgentType +import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentDockerInfo +import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentEnvDispatchType +import com.tencent.devops.common.pipeline.type.agent.ThirdPartyAgentIDDispatchType +import com.tencent.devops.common.pipeline.type.docker.DockerDispatchType +import com.tencent.devops.common.pipeline.type.docker.ImageType +import com.tencent.devops.process.yaml.v3.models.job.Container2 +import com.tencent.devops.process.yaml.v3.models.job.Container3 +import com.tencent.devops.process.yaml.v3.models.job.Credentials +import com.tencent.devops.process.yaml.v3.models.job.JobRunsOnPoolType +import com.tencent.devops.process.yaml.v3.models.job.JobRunsOnType +import com.tencent.devops.process.yaml.v3.models.job.RunsOn +import org.slf4j.Logger +import org.slf4j.LoggerFactory + +@Suppress("ALL") +enum class PoolType { + DockerOnVm { + override fun transfer(pool: Pool): DispatchType { + return DockerDispatchType( + dockerBuildVersion = pool.container ?: pool.image?.imageCode, + imageType = pool.image?.imageType ?: ImageType.THIRD, + credentialId = pool.credentialId, + imageVersion = pool.image?.imageVersion, + imageCode = pool.image?.imageCode + ) + } + + override fun validatePool(pool: Pool) { + if (null == pool.container) { + throw OperationException("当pool.type=$this, container参数不能为空") + } + } + + override fun transfer(dispatcher: DispatchType): RunsOn? { + if (dispatcher is DockerDispatchType) { + return RunsOn( + selfHosted = null, + poolName = JobRunsOnType.DOCKER.type, + container = when (dispatcher.imageType) { + ImageType.BKSTORE, ImageType.THIRD -> Container2( + image = "${dispatcher.dockerBuildVersion}:${dispatcher.imageVersion}", + credentials = dispatcher.credentialId + ) + else -> null + } + ) + } + return null + } + }, + + SelfHosted { + override fun transfer(pool: Pool): DispatchType { + if (!pool.envName.isNullOrBlank()) { + return ThirdPartyAgentEnvDispatchType( + envProjectId = pool.envProjectId, + envName = pool.envName, + workspace = pool.workspace, + agentType = AgentType.NAME, + dockerInfo = pool.dockerInfo + ) + } else if (!pool.envId.isNullOrBlank()) { + return ThirdPartyAgentEnvDispatchType( + envProjectId = pool.envProjectId, + envName = pool.envId, + workspace = pool.workspace, + agentType = AgentType.ID, + dockerInfo = pool.dockerInfo + ) + } else if (!pool.agentId.isNullOrBlank()) { + return ThirdPartyAgentIDDispatchType( + displayName = pool.agentId, + workspace = pool.workspace, + agentType = AgentType.ID, + dockerInfo = pool.dockerInfo + ) + } else { + return ThirdPartyAgentIDDispatchType( + displayName = pool.agentName!!, + workspace = pool.workspace, + agentType = AgentType.NAME, + dockerInfo = pool.dockerInfo + ) + } + } + + override fun transfer(dispatcher: DispatchType): RunsOn? { + if (dispatcher is ThirdPartyAgentEnvDispatchType) { + return RunsOn( + selfHosted = true, + poolName = dispatcher.envName, + poolType = if (dispatcher.agentType == AgentType.NAME) { + JobRunsOnPoolType.ENV_NAME.name + } else { + JobRunsOnPoolType.ENV_ID.name + }, + workspace = dispatcher.workspace, + container = makeContainer(dispatcher.dockerInfo) + ) + } + if (dispatcher is ThirdPartyAgentIDDispatchType) { + return RunsOn( + selfHosted = true, + poolName = dispatcher.displayName, + poolType = if (dispatcher.agentType == AgentType.NAME) { + JobRunsOnPoolType.AGENT_NAME.name + } else { + JobRunsOnPoolType.AGENT_ID.name + }, + workspace = dispatcher.workspace, + container = makeContainer(dispatcher.dockerInfo) + ) + } + return null + } + + private fun makeContainer(dockerInfo: ThirdPartyAgentDockerInfo?): Container3? { + if (dockerInfo == null) return null + return Container3( + image = dockerInfo.image, + imageType = null, + credentials = with(dockerInfo.credential) { + when { + this == null -> null + credentialId != null -> dockerInfo.credential?.credentialId?.ifBlank { null } + user != null && password != null -> Credentials(user!!, password!!) + else -> null + } + }, + options = dockerInfo.options, + imagePullPolicy = dockerInfo.imagePullPolicy + ) + } + + override fun validatePool(pool: Pool) { + if (null == pool.agentName && null == pool.agentId && null == pool.envId && null == pool.envName) { + throw OperationException("当pool.type=$this, agentName/agentId/envId/envName参数不能全部为空") + } + } + } + + ; + + /** + * 校验pool + */ + protected abstract fun validatePool(pool: Pool) + + /** + * 转换pool + */ + protected abstract fun transfer(pool: Pool): DispatchType + + /** + * 转换runsOn + */ + protected abstract fun transfer(dispatcher: DispatchType): RunsOn? + + fun toRunsOn(dispatcher: DispatchType): RunsOn? { + return this.transfer(dispatcher) + } + + fun toDispatchType(pool: Pool): DispatchType { + this.validatePool(pool) + return this.transfer(pool) + } + + protected val logger: Logger = LoggerFactory.getLogger(PoolType::class.java) +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/job/Job.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/job/Job.kt new file mode 100644 index 00000000000..46a720637fc --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/job/Job.kt @@ -0,0 +1,171 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.job + +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.common.pipeline.type.agent.DockerOptions +import com.tencent.devops.common.pipeline.type.docker.ImageType +import com.tencent.devops.process.yaml.v3.models.step.Step +import io.swagger.annotations.ApiModelProperty + +/** + * WARN: 请谨慎修改这个类 , 不要随意添加或者删除变量 , 否则可能导致依赖yaml的功能(gitci,prebuild等)异常 + */ +data class Job( + // val job: JobDetail, + val id: String? = "", + val name: String?, + @JsonProperty("mutex") + val mutex: Mutex? = null, + @JsonProperty("runs-on") + @ApiModelProperty(name = "runs-on") + val runsOn: RunsOn = RunsOn(), + // val container: Container?, + val services: List? = null, + @ApiModelProperty(name = "if") + @JsonProperty("if") + val ifField: String? = null, + val steps: List?, + @ApiModelProperty(name = "if-modify") + @JsonProperty("if-modify") + val ifModify: List? = null, + @ApiModelProperty(name = "timeout-minutes") + @JsonProperty("timeout-minutes") + val timeoutMinutes: Int? = 480, + val env: Map? = emptyMap(), + @ApiModelProperty(name = "continue-on-error") + @JsonProperty("continue-on-error") + val continueOnError: Boolean? = false, + val strategy: Strategy? = null, + @ApiModelProperty(name = "depend-on") + @JsonProperty("depend-on") + val dependOn: List? = emptyList() +) + +data class Container( + val image: String, + val imageType: String? = ImageType.THIRD.name, + val credentials: Credentials? = null, + val options: DockerOptions? = null, + @JsonProperty("image-pull-policy") + val imagePullPolicy: String? = null +) + +data class Container2( + val image: String, + val imageType: String? = ImageType.THIRD.name, + val credentials: String? = null, + val options: DockerOptions? = null, + @JsonProperty("image-pull-policy") + val imagePullPolicy: String? = null +) + +data class Container3( + val image: String, + val imageType: String? = ImageType.THIRD.name, + val credentials: Any? = null, + val options: DockerOptions? = null, + @JsonProperty("image-pull-policy") + val imagePullPolicy: String? = null +) + +enum class ImagePullPolicyEnum(val type: String) { + IfNotPresent("if-not-present"), + Always("always") +} + +data class Credentials( + val username: String, + val password: String +) + +data class Service( + val serviceId: String? = "", + val image: String, + val with: ServiceWith +) + +data class ServiceWith( + val password: String? = "" +) + +data class Strategy( + val matrix: Any, + @ApiModelProperty(name = "fast-kill") + @JsonProperty("fast-kill") + val fastKill: Boolean? = null, + @ApiModelProperty(name = "max-parallel") + @JsonProperty("max-parallel") + val maxParallel: Int? = null +) + +data class RunsOn( + @ApiModelProperty(name = "self-hosted") + @JsonProperty("self-hosted") + val selfHosted: Boolean? = false, + @ApiModelProperty(name = "pool-name") + @JsonProperty("pool-name") + var poolName: String = JobRunsOnType.DOCKER.type, + @JsonProperty("pool-type") + val poolType: String? = JobRunsOnPoolType.ENV_NAME.name, + val container: Any? = null, + @ApiModelProperty(name = "agent-selector") + @JsonProperty("agent-selector") + var agentSelector: List? = null, + val workspace: String? = null, + val xcode: String? = null, + @ApiModelProperty(name = "queue-timeout-minutes") + @JsonProperty("queue-timeout-minutes") + var queueTimeoutMinutes: Int? = null, + var needs: Map? = null +) + +enum class JobRunsOnType(val type: String) { + DOCKER("docker"), + AGENT_LESS("agentless"), + DEV_CLOUD("docker-on-devcloud"), + BCS("docker-on-bcs"), + LOCAL("local") +} + +enum class JobRunsOnPoolType { + ENV_NAME, + ENV_ID, + AGENT_ID, + AGENT_NAME +} + +data class Mutex( + val label: String, + @JsonProperty("queue-length") + val queueLength: Int? = 0, + @JsonProperty("timeout-minutes") + val timeoutMinutes: Int? = 10, + @JsonProperty("queue-enable") + val queueEnable: Boolean? = false +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/job/PreJob.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/job/PreJob.kt new file mode 100644 index 00000000000..9b458e87422 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/job/PreJob.kt @@ -0,0 +1,73 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.job + +import com.fasterxml.jackson.annotation.JsonFilter +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.process.yaml.v3.models.MetaData +import com.tencent.devops.process.yaml.v3.models.YAME_META_DATA_JSON_FILTER +import com.tencent.devops.process.yaml.v3.models.YamlMetaData +import com.tencent.devops.process.yaml.v3.models.step.PreStep +import io.swagger.annotations.ApiModelProperty + +interface IPreJob + +/** + * WARN: 请谨慎修改这个类 , 不要随意添加或者删除变量 , 否则可能导致依赖yaml的功能(gitci,prebuild等)异常 + */ +@JsonFilter(YAME_META_DATA_JSON_FILTER) +data class PreJob( + // val job: JobDetail, + val name: String?, + @JsonProperty("mutex") + val mutex: Mutex? = null, + @ApiModelProperty(name = "runs-on") + @JsonProperty("runs-on") + val runsOn: Any?, + val container: Container?, + val services: Map? = null, + @ApiModelProperty(name = "if") + @JsonProperty("if") + val ifField: String? = null, + @ApiModelProperty(name = "if-modify") + @JsonProperty("if-modify") + val ifModify: List? = null, + val steps: List?, + @ApiModelProperty(name = "timeout-minutes") + @JsonProperty("timeout-minutes") + val timeoutMinutes: Int? = null, + val env: Map? = emptyMap(), + @ApiModelProperty(name = "continue-on-error") + @JsonProperty("continue-on-error") + val continueOnError: Boolean? = null, + val strategy: Strategy? = null, + @ApiModelProperty(name = "depend-on") + @JsonProperty("depend-on") + val dependOn: List? = null, + override val yamlMetaData: MetaData? = null +) : YamlMetaData, IPreJob diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/DeleteRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/DeleteRule.kt new file mode 100644 index 00000000000..c76ad35b8c9 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/DeleteRule.kt @@ -0,0 +1,56 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.on + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.tencent.devops.process.yaml.v3.enums.StreamObjectKind + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class DeleteRule( + val types: List +) { + companion object { + val typeSet = setOf("branch", "tag") + } +} + +fun DeleteRule.check(): Boolean { + return (types.toSet() subtract DeleteRule.typeSet).isEmpty() +} + +fun DeleteRule.getTypesObjectKind(): List { + return types.map { + when (it) { + "branch" -> StreamObjectKind.PUSH + "tag" -> StreamObjectKind.TAG_PUSH + else -> StreamObjectKind.PUSH + } + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/EnableType.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/EnableType.kt new file mode 100644 index 00000000000..e83e7eab4ac --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/EnableType.kt @@ -0,0 +1,33 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.on + +enum class EnableType(val value: String) { + TRUE("enabled"), + FALSE("disabled") +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/IssueRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/IssueRule.kt new file mode 100644 index 00000000000..31998c72ac8 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/IssueRule.kt @@ -0,0 +1,38 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.on + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class IssueRule( + val enable: Boolean? = true, + val action: List? = null +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ManualRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/ManualRule.kt similarity index 97% rename from src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ManualRule.kt rename to src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/ManualRule.kt index f964fa95a8e..4ef810afc2a 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v2/models/on/ManualRule.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/ManualRule.kt @@ -25,7 +25,7 @@ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.tencent.devops.process.yaml.v2.models.on +package com.tencent.devops.process.yaml.v3.models.on import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/MatchRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/MatchRule.kt new file mode 100644 index 00000000000..25804196c78 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/MatchRule.kt @@ -0,0 +1,41 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.on + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude + +/** + * model + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class MatchRule( + val include: List?, + val exclude: List? +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/MrRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/MrRule.kt new file mode 100644 index 00000000000..10eb3841d4f --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/MrRule.kt @@ -0,0 +1,81 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.on + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import io.swagger.annotations.ApiModelProperty + +/** + * model + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class MrRule( + val enable: Boolean? = true, + @ApiModelProperty(name = "source-branches") + @JsonProperty("source-branches") + val sourceBranches: List? = null, + + @ApiModelProperty(name = "source-branches-ignore") + @JsonProperty("source-branches-ignore") + val sourceBranchesIgnore: List? = null, + + @ApiModelProperty(name = "target-branches") + @JsonProperty("target-branches") + val targetBranches: List? = null, + + @ApiModelProperty(name = "target-branches-ignore") + @JsonProperty("target-branches-ignore") + val targetBranchesIgnore: List? = null, + + val paths: List? = null, + + @ApiModelProperty(name = "paths-ignore") + @JsonProperty("paths-ignore") + val pathsIgnore: List? = null, + + val action: List? = null, + + val users: List? = null, + + @ApiModelProperty(name = "users-ignore") + @JsonProperty("users-ignore") + val usersIgnore: List? = null, + + val block: Boolean? = null, + + val webhookQueue: Boolean? = null, + + val enableCheck: Boolean? = null, + + @ApiModelProperty(name = "path-filter-type") + @JsonProperty("path-filter-type") + val pathFilterType: String? = null +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/NoteRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/NoteRule.kt new file mode 100644 index 00000000000..30bbb58bf99 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/NoteRule.kt @@ -0,0 +1,39 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.on + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +class NoteRule( + val enable: Boolean? = true, + val types: List? = null, + val comment: List? = null +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PreTriggerOnV3.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PreTriggerOnV3.kt index 71bf2052cc2..aaff793326f 100644 --- a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PreTriggerOnV3.kt +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PreTriggerOnV3.kt @@ -31,11 +31,11 @@ import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonInclude import com.fasterxml.jackson.annotation.JsonProperty import com.tencent.devops.process.yaml.pojo.YamlVersion -import com.tencent.devops.process.yaml.v2.models.on.DeleteRule -import com.tencent.devops.process.yaml.v2.models.on.IPreTriggerOn -import com.tencent.devops.process.yaml.v2.models.on.IssueRule -import com.tencent.devops.process.yaml.v2.models.on.NoteRule -import com.tencent.devops.process.yaml.v2.models.on.ReviewRule +import com.tencent.devops.process.yaml.v3.models.on.DeleteRule +import com.tencent.devops.process.yaml.v3.models.on.IPreTriggerOn +import com.tencent.devops.process.yaml.v3.models.on.IssueRule +import com.tencent.devops.process.yaml.v3.models.on.NoteRule +import com.tencent.devops.process.yaml.v3.models.on.ReviewRule import io.swagger.annotations.ApiModelProperty @JsonInclude(JsonInclude.Include.NON_NULL) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PushRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PushRule.kt new file mode 100644 index 00000000000..8049d65b703 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/PushRule.kt @@ -0,0 +1,65 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.on + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import io.swagger.annotations.ApiModelProperty + +/** + * model + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class PushRule( + val enable: Boolean? = true, + val branches: List? = listOf("*"), + + @ApiModelProperty(name = "branches-ignore") + @JsonProperty("branches-ignore") + val branchesIgnore: List? = null, + + val paths: List? = null, + + @ApiModelProperty(name = "paths-ignore") + @JsonProperty("paths-ignore") + val pathsIgnore: List? = null, + + val users: List? = null, + + @ApiModelProperty(name = "users-ignore") + @JsonProperty("users-ignore") + val usersIgnore: List? = null, + + val action: List? = null, + + @ApiModelProperty(name = "path-filter-type") + @JsonProperty("path-filter-type") + val pathFilterType: String? = null +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/ReviewRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/ReviewRule.kt new file mode 100644 index 00000000000..5dc172fe49e --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/ReviewRule.kt @@ -0,0 +1,39 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.on + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class ReviewRule( + val enable: Boolean? = true, + val types: List? = null, + val states: List? = null +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/SchedulesRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/SchedulesRule.kt new file mode 100644 index 00000000000..d166070e2dd --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/SchedulesRule.kt @@ -0,0 +1,52 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.on + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import io.swagger.annotations.ApiModelProperty + +/** + * model + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class SchedulesRule( + val enable: Boolean? = true, + val cron: String? = null, + + @ApiModelProperty(name = "advance-cron") + @JsonProperty("advance-cron") + val advanceCron: List? = null, + + + val branches: List? = null, + + val always: Boolean? = false +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/TagRule.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/TagRule.kt new file mode 100644 index 00000000000..ba06c523de1 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/TagRule.kt @@ -0,0 +1,57 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.on + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import io.swagger.annotations.ApiModelProperty + +/** + * model + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class TagRule( + val enable: Boolean? = true, + val tags: List? = null, + + @ApiModelProperty(name = "tags-ignore") + @JsonProperty("tags-ignore") + val tagsIgnore: List? = null, + + @ApiModelProperty(name = "from-branches") + @JsonProperty("from-branches") + val fromBranches: List? = null, + + val users: List? = null, + + @ApiModelProperty(name = "users-ignore") + @JsonProperty("users-ignore") + val usersIgnore: List? = null +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/TriggerOn.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/TriggerOn.kt new file mode 100644 index 00000000000..1d77346b36b --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/on/TriggerOn.kt @@ -0,0 +1,143 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.on + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.DEFAULT_MANUAL_RULE +import com.tencent.devops.process.yaml.modelTransfer.VariableDefault.nullIfDefault +import com.tencent.devops.process.yaml.pojo.YamlVersion +import com.tencent.devops.process.yaml.v3.models.RepositoryHook +import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 +import io.swagger.annotations.ApiModelProperty + +/** + * model + */ +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class TriggerOn( + var push: PushRule? = null, + var tag: TagRule? = null, + var mr: MrRule? = null, + var schedules: List? = null, + var delete: DeleteRule? = null, + var issue: IssueRule? = null, + var review: ReviewRule? = null, + var note: NoteRule? = null, + @ApiModelProperty(name = "repo_hook") + @JsonProperty("repo_hook") + val repoHook: RepositoryHook? = null, + var manual: ManualRule? = null, + var remote: String? = null, + val openapi: String? = null, + var repoName: String? = null, + var triggerName: String? = null, + @JsonProperty("repoId") + @ApiModelProperty(name = "repoId") + var repoHashId: String? = null, + var credentials: String? = null +) { + fun toPre(version: YamlVersion.Version) = when (version) { + YamlVersion.Version.V2_0 -> toPreV2() + YamlVersion.Version.V3_0 -> toPreV3() + } + + private fun toPreV2() = PreTriggerOn( + push = push, + tag = tag, + mr = mr, + schedules = schedules?.firstOrNull(), + delete = delete, + issue = issue, + review = review, + note = note, + // todo + repoHook = null, + manual = manual?.let { EnableType.TRUE.value } ?: EnableType.FALSE.value, + openapi = openapi, + remote = remote + ) + + private fun toPreV3() = PreTriggerOnV3( + repoName = repoName, + repoHashId = repoHashId, + type = null, + credentials = credentials, + push = push, + tag = tag, + mr = mr, + schedules = if (schedules?.size == 1) schedules!!.first() else schedules, + delete = delete, + issue = issue, + review = review, + note = note, + // todo + repoHook = null, + manual = (manual ?: EnableType.FALSE.value).nullIfDefault(DEFAULT_MANUAL_RULE), + openapi = openapi, + remote = remote + ) +} + +interface IPreTriggerOn : YamlVersion { + val push: Any? + val tag: Any? + val mr: Any? + val schedules: Any? + val delete: DeleteRule? + val issue: IssueRule? + val review: ReviewRule? + val note: NoteRule? + val repoHook: List? + val manual: Any? + val openapi: String? + val remote: String? +} + +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class PreTriggerOn( + override val push: Any?, + override val tag: Any?, + override val mr: Any?, + override val schedules: Any?, + override val delete: DeleteRule?, + override val issue: IssueRule? = null, + override val review: ReviewRule? = null, + override val note: NoteRule? = null, + @ApiModelProperty(name = "repo_hook") + @JsonProperty("repo_hook") + override val repoHook: List? = null, + override val manual: Any? = null, + override val openapi: String? = null, + override val remote: String? = null +) : IPreTriggerOn { + override fun yamlVersion() = YamlVersion.Version.V2_0 +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/stage/PreStage.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/stage/PreStage.kt new file mode 100644 index 00000000000..709b5b76716 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/stage/PreStage.kt @@ -0,0 +1,59 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.stage + +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.process.yaml.v3.models.job.PreJob +import com.tencent.devops.process.yaml.v3.stageCheck.PreStageCheck +import io.swagger.annotations.ApiModelProperty + +interface IPreStage + +/** + * WARN: 请谨慎修改这个类 , 不要随意添加或者删除变量 , 否则可能导致依赖yaml的功能(gitci,prebuild等)异常 + */ +data class PreStage( + val name: String?, + val label: Any? = null, + @ApiModelProperty(name = "if") + @JsonProperty("if") + val ifField: String? = null, + @ApiModelProperty(name = "if-modify") + @JsonProperty("if-modify") + val ifModify: List? = null, + @ApiModelProperty(name = "fast-kill") + @JsonProperty("fast-kill") + val fastKill: Boolean? = false, + val jobs: Map?, + @ApiModelProperty(name = "check-in") + @JsonProperty("check-in") + val checkIn: PreStageCheck?, + @ApiModelProperty(name = "check-out") + @JsonProperty("check-out") + val checkOut: PreStageCheck? +) : IPreStage diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/stage/Stage.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/stage/Stage.kt new file mode 100644 index 00000000000..6e3e4ca77d3 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/stage/Stage.kt @@ -0,0 +1,59 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.stage + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.process.yaml.v3.models.job.Job +import com.tencent.devops.process.yaml.v3.stageCheck.StageCheck +import io.swagger.annotations.ApiModelProperty + +/** + * WARN: 请谨慎修改这个类 , 不要随意添加或者删除变量 , 否则可能导致依赖yaml的功能(gitci)异常 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +data class Stage( + val name: String?, + val label: List = emptyList(), + @ApiModelProperty(name = "if") + @JsonProperty("if") + val ifField: String? = null, + @ApiModelProperty(name = "fast-kill") + @JsonProperty("fast-kill") + val fastKill: Boolean? = false, + val jobs: List, + @ApiModelProperty(name = "if-modify") + @JsonProperty("if-modify") + val ifModify: List? = null, + @ApiModelProperty(name = "check-in") + @JsonProperty("check-in") + val checkIn: StageCheck?, + @ApiModelProperty(name = "check-out") + @JsonProperty("check-out") + val checkOut: StageCheck? +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/stage/StageLabel.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/stage/StageLabel.kt new file mode 100644 index 00000000000..4116beb3259 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/stage/StageLabel.kt @@ -0,0 +1,47 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.stage + +enum class StageLabel( + val value: String, + val id: String +) { + BUILD("Build", "28ee946a59f64949a74f3dee40a1bda4"), + APPROVE("Approve", "5168be68b9764edb91aa5b866e51a1a8"), + DEPLOY("Deploy", "53b4d3f38e3e425cb1aaa97aa1b37857"), + TEST("Test", "d0a06f6986fa4670af65ccad7bb49d3a"); + + companion object { + fun parseById(id: String): StageLabel { + values().forEach { + if (it.id == id) return it + } + return BUILD + } + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/step/PreStep.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/step/PreStep.kt new file mode 100644 index 00000000000..b00b05ab1f4 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/step/PreStep.kt @@ -0,0 +1,72 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.step + +import com.fasterxml.jackson.annotation.JsonFilter +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.process.yaml.v3.models.MetaData +import com.tencent.devops.process.yaml.v3.models.YAME_META_DATA_JSON_FILTER +import com.tencent.devops.process.yaml.v3.models.YamlMetaData +import io.swagger.annotations.ApiModelProperty + +interface IPreStep + +/** + * 为了方便产生中间变量的过度类和Step一模一样 + */ +@JsonFilter(YAME_META_DATA_JSON_FILTER) +data class PreStep( + var enable: Boolean? = null, + val checkout: String? = null, + val name: String?, + val id: String?, + @ApiModelProperty(name = "if") + @JsonProperty("if") + val ifFiled: String?, + @ApiModelProperty(name = "if-modify") + @JsonProperty("if-modify") + val ifModify: List? = null, + val uses: String?, + val with: Map?, + @ApiModelProperty(name = "timeout-minutes") + @JsonProperty("timeout-minutes") + var timeoutMinutes: Int? = null, + @ApiModelProperty(name = "continue-on-error") + @JsonProperty("continue-on-error") + var continueOnError: Boolean? = null, + @ApiModelProperty(name = "retry-times") + @JsonProperty("retry-times") + var retryTimes: Int? = null, + var env: Map? = emptyMap(), + val run: String? = null, + val shell: String? = null, + @ApiModelProperty(name = "manual-retry") + @JsonProperty("manual-retry") + var manualRetry: Boolean? = null, + override val yamlMetaData: MetaData? = null +) : YamlMetaData, IPreStep diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/step/Step.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/step/Step.kt new file mode 100644 index 00000000000..42cc79ea1c7 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/models/step/Step.kt @@ -0,0 +1,60 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.models.step + +import com.fasterxml.jackson.annotation.JsonIgnore +import com.fasterxml.jackson.annotation.JsonProperty +import io.swagger.annotations.ApiModelProperty + +data class Step( + val enable: Boolean? = null, + val name: String?, + val id: String?, + @JsonProperty("if") + val ifFiled: String?, + @JsonProperty("if-modify") + val ifModify: List? = null, + val uses: String?, + val with: Map?, + @JsonProperty("timeout-minutes") + val timeoutMinutes: Int? = 480, + @JsonProperty("continue-on-error") + val continueOnError: Boolean?, + @JsonProperty("retry-times") + val retryTimes: Int?, + val env: Map? = emptyMap(), + val run: String?, + @ApiModelProperty("run 插件的附加参数") + val runAdditionalOptions: Map?, + val checkout: String?, + @JsonProperty("manual-retry") + val manualRetry: Boolean? = null, + // 在系统内唯一标识step唯一性,不参与yaml打印 + @JsonIgnore + val taskId: String? = null +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parameter/Parameters.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parameter/Parameters.kt new file mode 100644 index 00000000000..e4d80988f7c --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parameter/Parameters.kt @@ -0,0 +1,49 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.parameter + +data class Parameters( + val name: String, + val type: String, + val default: Any?, + val values: List? +) + +enum class ParametersType(val value: String) { + STRING("string"), + NUMBER("number"), + BOOLEAN("boolean"), + ARRAY("array") +// OBJECT("object"), +// TASK("task"), +// TASKLIST("taskList"), +// JOB("job"), +// JOBLIST("jobList"), +// STAGE("stage"), +// STAGELIST("stageList") +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parameter/ParametersTemplate.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parameter/ParametersTemplate.kt new file mode 100644 index 00000000000..ba73aca48dd --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parameter/ParametersTemplate.kt @@ -0,0 +1,40 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.parameter + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties + +@JsonIgnoreProperties(ignoreUnknown = true) +data class PreParametersTemplate( + val parameters: List>? +) + +@JsonIgnoreProperties(ignoreUnknown = true) +data class ParametersTemplateNull( + val parameters: List? +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/Constants.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/Constants.kt new file mode 100644 index 00000000000..9510a30858c --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/Constants.kt @@ -0,0 +1,83 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.parsers.template + +object Constants { + const val templateDirectory = ".ci/templates/" + + // 引用模板的关键字 + const val TEMPLATE_KEY = "template" + const val REF = "ref" + + // 模板变量关键字 + const val PARAMETERS_KEY = "parameters" + + // 对象类型模板Job,Variable的模板路径关键字 + const val OBJECT_TEMPLATE_PATH = "name" + + // 分隔远程库和文件关键字 + const val FILE_REPO_SPLIT = "@" + + // 模板最多引用数和最大深度 + const val MAX_TEMPLATE_NUMB = 10 + const val MAX_TEMPLATE_DEEP = 5 + + // 质量红线数量和红线中的规则数量 + const val STAGE_CHECK_GATE_NUMB = 10 + const val STAGE_CHECK_GATE_RULE_NUMB = 100 + + // 异常模板 + const val TEMPLATE_ID_DUPLICATE = "Format error: ID [%s] in template [%s] and template [%s] are duplicated" + const val TEMPLATE_ROOT_ID_DUPLICATE = "[%s] Format error: IDs [%s] are duplicated" + const val TRANS_AS_ERROR = "[%s]Keyword [%s] format error" + const val REPO_NOT_FOUND_ERROR = + "[%s]The referenced repository [%s] should first be declared by the resources keyword" + const val REPO_CYCLE_ERROR = "Repository: Cyclic dependency" + const val TEMPLATE_CYCLE_ERROR = "There is a [%s] circular dependency in template [%s] and template [%s]" + + // const val TEMPLATE_NUMB_BEYOND = +// "[%s]The number of referenced template files exceeds the threshold [$MAX_TEMPLATE_NUMB] " +// const val TEMPLATE_DEEP_BEYOND = "[%s]The template nesting depth exceeds the threshold [$MAX_TEMPLATE_DEEP]" +// const val TEMPLATE_FORMAT_ERROR = "[%s]Template YAML does not meet the specification" + const val YAML_FORMAT_ERROR = "[%s] Format error: %s" + const val ATTR_MISSING_ERROR = "[%s]Required attributes [%s] are missing" + + // const val TEMPLATE_KEYWORDS_ERROR = "[%s]Template YAML does not meet the specification. " + +// "The %s template can only contain parameters, resources and %s keywords" +// const val EXTENDS_TEMPLATE_EXTENDS_ERROR = "[%s]The extends keyword cannot be nested" +// const val EXTENDS_TEMPLATE_ON_ERROR = "[%s]Triggers are not supported in the template" + const val VALUE_NOT_IN_ENUM = "[%s to %s][%s=%s]Parameter error, the expected value is [%s]" + const val PARAMETER_FORMAT_ERROR = "[%s]Parameter format error [%s]" + const val EXPRESSION_EVALUATE_ERROR = "[%s]Expression [%s] evaluate error [%s]" + + // const val FINALLY_FORMAT_ERROR = "final stage not support stage's template" + const val STAGE_CHECK_GATE_NUMB_BEYOND = + "[%s][%s]The number of gates reaches the limit: no more than $STAGE_CHECK_GATE_NUMB. " + const val STAGE_CHECK_GATE_RULE_NUMB_BEYOND = + "[%s][%s][%s]The number of rules reaches the limit: no more than $STAGE_CHECK_GATE_RULE_NUMB. " +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/ParametersExpressionParse.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/ParametersExpressionParse.kt new file mode 100644 index 00000000000..52f76101e13 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/ParametersExpressionParse.kt @@ -0,0 +1,554 @@ +package com.tencent.devops.process.yaml.v3.parsers.template + +import com.fasterxml.jackson.databind.JsonNode +import com.tencent.devops.common.api.util.JsonUtil +import com.tencent.devops.common.expression.ExecutionContext +import com.tencent.devops.common.expression.ExpressionParser +import com.tencent.devops.common.expression.SubNameValueEvaluateInfo +import com.tencent.devops.common.expression.SubNameValueEvaluateResult +import com.tencent.devops.common.expression.SubNameValueResultType +import com.tencent.devops.common.expression.context.ArrayContextData +import com.tencent.devops.common.expression.context.BooleanContextData +import com.tencent.devops.common.expression.context.ContextValueNode +import com.tencent.devops.common.expression.context.DictionaryContextData +import com.tencent.devops.common.expression.context.ExpressionContextData +import com.tencent.devops.common.expression.context.NumberContextData +import com.tencent.devops.common.expression.context.PipelineContextData +import com.tencent.devops.common.expression.context.StringContextData +import com.tencent.devops.common.expression.expression.FunctionInfo +import com.tencent.devops.common.expression.expression.sdk.NamedValueInfo +import com.tencent.devops.common.expression.expression.specialFuctions.hashFiles.HashFilesFunction +import com.tencent.devops.process.yaml.pojo.TemplatePath +import com.tencent.devops.process.yaml.v3.exception.YamlFormatException +import com.tencent.devops.process.yaml.v3.exception.YamlTemplateException +import com.tencent.devops.process.yaml.v3.parameter.Parameters +import com.tencent.devops.process.yaml.v3.parameter.ParametersType +import com.tencent.devops.process.yaml.v3.parsers.template.models.ExpressionBlock +import org.apache.commons.text.StringEscapeUtils +import org.apache.tools.ant.filters.StringInputStream +import java.io.BufferedReader +import java.io.IOException +import java.io.InputStreamReader + +/** + * 模板参数表达式解析相关 + */ +@Suppress("ALL") +object ParametersExpressionParse { + /** + * 为模板中的变量赋值 + * @param fromPath 来自哪个文件 + * @param path 读取的哪个模板文件 + * @param template 被读取的模板文件内容 + * @param templateParameters 被读取的模板文件自带的参数 + * @param parameters 引用模板文件时传入的参数 + */ + fun parseTemplateParameters( + fromPath: TemplatePath, + path: TemplatePath, + template: String, + templateParameters: MutableList?, + parameters: Map? + ): String { + if (templateParameters.isNullOrEmpty()) { + return template + } + + // 模板替换 先替换调用模板传入的参数,再替换模板的默认参数 + templateParameters.forEachIndexed { index, param -> + if (param.name.contains(".")) { + throw error( + Constants.PARAMETER_FORMAT_ERROR.format(path.toString(), "parameter name ${param.name} not allow contains '.'") + ) + } + + if (parameters == null) { + return@forEachIndexed + } + + val valueName = param.name + val newValue = parameters[param.name] + if (!parameters.keys.contains(valueName)) { + return@forEachIndexed + } + + if (!param.values.isNullOrEmpty() && !param.values.contains(newValue)) { + throw error( + Constants.VALUE_NOT_IN_ENUM.format( + fromPath.toString(), + path.toString(), + valueName, + newValue, + param.values.joinToString(",") + ) + ) + } else { + templateParameters[index] = param.copy(default = newValue) + } + } + + // 拼接表达式变量 + val expNameValues = mutableListOf().apply { + add(NamedValueInfo("parameters", ContextValueNode())) + } + val expContext = ExecutionContext(expressionValues = DictionaryContextData()) + val parameterContext = DictionaryContextData() + expContext.expressionValues.add("parameters", parameterContext) + templateParameters.filter { it.default != null }.forEach { param -> + when (param.type.toLowerCase()) { + ParametersType.ARRAY.value -> { + if (param.default !is Iterable<*>) { + throw error( + Constants.PARAMETER_FORMAT_ERROR.format( + path.toString(), "parameter ${param.name} type is ${param.type} but value not" + ) + ) + } + val arr = fromJsonToArrayContext(path, param.name, param.default) + parameterContext.add(param.name, arr) + } + + ParametersType.BOOLEAN.value, ParametersType.NUMBER.value -> { + parameterContext.add(param.name, nativeTypeToContext(param.default!!)) + } + + ParametersType.STRING.value -> { + val value = param.default!!.toString() + // 针对插入表达式单独处理 + if (value.trim().startsWith("\${{") && value.trim().endsWith("}}")) { + parameterContext.add(param.name, ExpressionContextData(value.trim())) + } else { + parameterContext.add(param.name, nativeTypeToContext(param.default)) + } + } + + else -> throw error( + Constants.PARAMETER_FORMAT_ERROR.format( + path.toString(), "parameter ${param.name} type ${param.type} not support" + ) + ) + } + } + + return parseParameterValue(path.toString(), template, expNameValues, expContext) + } + + // 因为array的里面可能嵌套array所以先转成json再转成array + fun fromJsonToArrayContext(path: TemplatePath, parameterName: String, value: Iterable<*>): ArrayContextData { + val jsonTree = try { + JsonUtil.getObjectMapper().readTree(JsonUtil.toJson(value)) + } catch (e: Throwable) { + throw error( + Constants.PARAMETER_FORMAT_ERROR.format( + path.toString(), "array parameter $parameterName value [$value] can't to json." + ) + ) + } + if (!jsonTree.isArray) { + throw error( + Constants.PARAMETER_FORMAT_ERROR.format( + path.toString(), "array parameter $parameterName value [$value] json type [${jsonTree.nodeType}] not array." + ) + ) + } + return initByJsonTree(jsonTree, null, null) as ArrayContextData + } + + fun parseParameterValue( + path: String, + value: String, + nameValues: List, + context: ExecutionContext + ): String { + val strReader = InputStreamReader(StringInputStream(value)) + val bufferReader = BufferedReader(strReader) + val newValue = StringBuilder() + try { + var line = bufferReader.readLine() + while (line != null) { + // 跳过空行和注释行,如果一行除空格外最左是 # 那一定是注释 + if (line.isBlank() || line.trimStart().startsWith("#")) { + newValue.append(line).append("\n") + line = bufferReader.readLine() + continue + } + + val lineString = line.trim().replace("\\s".toRegex(), "") + // if 表达式替换 + if (lineString.startsWith("if:") || lineString.startsWith("-if:")) { + val ifPrefix = line.substring(0 until line.indexOfFirst { it == ':' } + 1) + + var condition = line.removePrefix(ifPrefix).trim().removeSurrounding("\"") + // if如果没有需要预先添加一个双括号,方便后面的替换 + condition = "\${{$condition}}" + + val blocks = findExpressions(condition) + + val newLine = parseExpression( + line = condition, + blocks = blocks, + path = path, + needBrackets = false, + nameValues = nameValues, + context = context + ) + newLine.removePrefix("\${{") + newLine.removeSuffix("}}") + + newValue.append("$ifPrefix \"${newLine}\"").append("\n") + line = bufferReader.readLine() + continue + } + + val condition = line + val blocks = findExpressions(condition) + if (blocks.isEmpty()) { + newValue.append(line).append("\n") + line = bufferReader.readLine() + continue + } + + val newLine = parseExpression( + line = condition, + blocks = blocks, + path = path, + needBrackets = true, + nameValues = nameValues, + context = context + ) + newValue.append(newLine).append("\n") + line = bufferReader.readLine() + } + } finally { + try { + strReader.close() + bufferReader.close() + } catch (ignore: IOException) { + } + } + + return newValue.toString() + } + + /** + * 寻找语句中包含 ${{}}的表达式的位置,返回成对的位置坐标,并根据优先级排序 + * 优先级算法目前暂定为 从里到外,从左到右 + * @param levelMax 返回的最大层数,从深到浅。默认为2层 + * 例如: 替换顺序如数字所示 ${{ 4 ${{ 2 ${{ 1 }} }} ${{ 3 }} }} + * @return [ 层数次序 [ 括号 ] ] [[1], [2, 3], [4]]]] + */ + fun findExpressions(condition: String, levelMax: Int = 2): List> { + val stack = ArrayDeque() + var index = 0 + val chars = condition.toCharArray() + val levelMap = mutableMapOf>() + while (index < chars.size) { + if (index + 2 < chars.size && chars[index] == '$' && chars[index + 1] == '{' && chars[index + 2] == '{' + ) { + stack.addLast(index) + index += 3 + continue + } + + if (index + 1 < chars.size && chars[index] == '}' && chars[index + 1] == '}' + ) { + val start = stack.removeLastOrNull() + if (start != null) { + // 栈里剩下几个前括号,这个完整括号的优先级就是多少 + val level = stack.size + 1 + if (levelMap.containsKey(level)) { + levelMap[level]!!.add(ExpressionBlock(start, index + 1)) + } else { + levelMap[level] = mutableListOf(ExpressionBlock(start, index + 1)) + } + } + index += 2 + continue + } + + index++ + } + + if (levelMap.isEmpty()) { + return listOf() + } + + val result = mutableListOf>() + var max = 0 + var listIndex = 0 + run end@{ + levelMap.keys.sortedDescending().forEach result@{ level -> + val blocks = levelMap[level] ?: return@result + blocks.sortBy { it.startIndex } + blocks.forEach { block -> + if (result.size < listIndex + 1) { + result.add(mutableListOf(block)) + } else { + result[listIndex].add(block) + } + } + listIndex++ + max++ + if (max == levelMax) { + return@end + } + } + } + return result + } + + /** + * 解析表达式,根据 findExpressions 寻找的括号优先级进行解析 + */ + fun parseExpression( + line: String, + blocks: List>, + path: String, + needBrackets: Boolean, + nameValues: List, + context: ExecutionContext + ): String { + var lineChars = line.toList() + blocks.forEachIndexed { blockLevel, blocksInLevel -> + blocksInLevel.forEachIndexed { blockI, block -> + // 表达式因为含有 ${{ }} 所以起始向后推3位,末尾往前推两位 + val expression = lineChars.joinToString("").substring(block.startIndex + 3, block.endIndex - 1) + + val result = expressionEvaluate( + path = path, + expression = expression, + needBrackets = needBrackets, + nameValues = nameValues, + context = context + ) + + // 格式化返回值 + val (res, needFormatArr) = formatResult( + blockLevel = blockLevel, + blocks = blocks, + block = block, + lineChars = lineChars, + evaluateResult = result + ) + + // 去掉前后的可能的引号 + if (needFormatArr) { + if (block.startIndex - 1 >= 0 && lineChars[block.startIndex - 1] == '"') { + block.startIndex = block.startIndex - 1 + } + if (block.endIndex + 1 < lineChars.size && lineChars[block.endIndex + 1] == '"') { + block.endIndex = block.endIndex + 1 + } + } + + // 将替换后的表达式嵌入原本的line + val startSub = if (block.startIndex - 1 < 0) { + listOf() + } else { + lineChars.slice(0 until block.startIndex) + } + val endSub = if (block.endIndex + 1 >= lineChars.size) { + listOf() + } else { + lineChars.slice(block.endIndex + 1 until lineChars.size) + } + lineChars = startSub + res + endSub + + // 将替换后的字符查传递给后边的括号位数 + val diffNum = res.size - (block.endIndex - block.startIndex + 1) + blocks.forEachIndexed { i, bl -> + bl.forEachIndexed level@{ j, b -> + if (i <= blockLevel && j <= blockI) { + return@level + } + if (blocks[i][j].startIndex > block.endIndex) { + blocks[i][j].startIndex += diffNum + } + if (blocks[i][j].endIndex > block.endIndex) { + blocks[i][j].endIndex += diffNum + } + } + } + } + } + + return lineChars.joinToString("") + } + + private val functionList = listOf( + FunctionInfo( + HashFilesFunction.name, + 1, + Byte.MAX_VALUE.toInt(), + HashFilesFunction() + ) + ) + + fun expressionEvaluate( + path: String, + expression: String, + needBrackets: Boolean, + nameValues: List, + context: ExecutionContext + ): SubNameValueEvaluateResult { + val subInfo = SubNameValueEvaluateInfo() + val (value, isComplete, type) = try { + ExpressionParser.createSubNameValueEvaluateTree( + expression, null, nameValues, functionList, subInfo + )?.subNameValueEvaluate(null, context, null, subInfo, null) + ?: throw YamlTemplateException("create evaluate tree is null") + } catch (e: Throwable) { + throw error(Constants.EXPRESSION_EVALUATE_ERROR.format(path, expression, e.message)) + } + if (isComplete) { + return SubNameValueEvaluateResult(value.trim(), true, type) + } + if (needBrackets) { + return SubNameValueEvaluateResult("\${{ ${value.trim()} }}", false, type) + } + return SubNameValueEvaluateResult(value.trim(), false, type) + } + + /** + * 格式化表达式计算的返回值 + * @return <格式化结果, 是否需要格式化列表> + */ + private fun formatResult( + blockLevel: Int, + blocks: List>, + block: ExpressionBlock, + lineChars: List, + evaluateResult: SubNameValueEvaluateResult + ): Pair, Boolean> { + if (!evaluateResult.isComplete) { + return Pair(evaluateResult.value.toList(), false) + } + + // ScriptUtils.formatYaml会将所有的带上 "" 但换时数组不需要"" 所以为数组去掉可能的额外的"" + // 需要去掉额外""的情况只可能出现只替换了一次列表的情景,即作为参数 var_a: "{{ parameters.xxx }}" + // 需要将给表达式的转义 \" 转回 " + if (evaluateResult.type == SubNameValueResultType.ARRAY) { + return Pair(evaluateResult.value.replace("\\\"", "\"").toList(), (blocks.size == 1)) + } + + // 对于还有下一层的表达式,其替换出来的string需要加上 '' 方便后续第二层使用 + // 例外: 当string前或后存在 . 时,说明是用来做索引,不加 '' + var result = evaluateResult.value + if ((blockLevel + 1 < blocks.size && evaluateResult.type == SubNameValueResultType.STRING) && + !( + (block.startIndex - 1 >= 0 && lineChars[block.startIndex - 1] == '.') || + (block.endIndex + 1 < lineChars.size && lineChars[block.endIndex + 1] == '.') + ) + ) { + result = "'$result'" + } + + // 对于字符传可能用的非转义的 \n \s 改为转义后的 + result = StringEscapeUtils.escapeJava(result) + + return Pair(result.toList(), false) + } + + private fun initByJsonTree(node: JsonNode, context: PipelineContextData?, nodeName: String?): PipelineContextData { + if (node.isValueNode) { + return context.addNode(node, nodeName) + } + + var ctx: PipelineContextData? = context + + if (node.isObject) { + val fields = node.fields() + ctx = context ?: DictionaryContextData() + if (!fields.hasNext()) { + return ctx + } + val newContext = when { + context == null -> { + ctx + } + + ctx is ArrayContextData -> { + val c = DictionaryContextData() + ctx.add(c) + c + } + + ctx is DictionaryContextData -> { + val c = DictionaryContextData() + ctx.add(nodeName!!, c) + c + } + + else -> return ctx + } + while (fields.hasNext()) { + val entry = fields.next() + initByJsonTree(entry.value, newContext, entry.key) + } + } + + if (node.isArray) { + val iter = node.iterator() + ctx = context ?: ArrayContextData() + if (!iter.hasNext()) { + return ctx + } + val newContext = when { + context == null -> { + ctx + } + + ctx is ArrayContextData -> { + val c = ArrayContextData() + ctx.add(c) + c + } + + ctx is DictionaryContextData -> { + val c = ArrayContextData() + ctx.add(nodeName!!, c) + c + } + + else -> return ctx + } + while (iter.hasNext()) { + val entry = iter.next() + initByJsonTree(entry, newContext, null) + } + } + + return ctx ?: StringContextData(node.toString()) + } + + private fun PipelineContextData?.addNode(node: JsonNode, nodeName: String?): PipelineContextData { + val value = when { + node.isBoolean -> BooleanContextData(node.booleanValue()) + node.isNumber -> NumberContextData(node.doubleValue()) + node.isNull -> StringContextData("") + node.isTextual -> StringContextData(node.textValue()) + else -> StringContextData(node.toString()) + } + if (this == null) { + return value + } + if (this is ArrayContextData) { + this.add(value) + } + if (this is DictionaryContextData) { + this.add(nodeName!!, value) + } + return this + } + + private fun nativeTypeToContext(value: Any): PipelineContextData { + return when (value) { + is Char, is String -> StringContextData(value.toString()) + is Number -> NumberContextData(value.toDouble()) + is Boolean -> BooleanContextData(value) + else -> StringContextData(value.toString()) + } + } + + private fun error(content: String) = YamlFormatException(content) +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/TemplateGraph.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/TemplateGraph.kt new file mode 100644 index 00000000000..82be504903f --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/TemplateGraph.kt @@ -0,0 +1,90 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.parsers.template + +import com.tencent.devops.process.yaml.v3.enums.TemplateType +import com.tencent.devops.process.yaml.v3.models.Repositories +import com.tencent.devops.process.yaml.v3.parsers.template.models.Graph + +class TemplateGraph( + private var repoTemplateGraph: Graph = Graph(), + private var varTemplateGraph: Graph = Graph(), + private var stageTemplateGraph: Graph = Graph(), + private var jobTemplateGraph: Graph = Graph(), + private var stepTemplateGraph: Graph = Graph() +) { + // 将路径加入图中并且做循环嵌套检测 + fun saveAndCheckCyclicTemplate( + fromPath: String, + toPath: String, + templateType: TemplateType + ) { + when (templateType) { + TemplateType.VARIABLE -> { + varTemplateGraph.addEdge(fromPath, toPath) + if (varTemplateGraph.hasCyclic()) { + error(Constants.TEMPLATE_CYCLE_ERROR.format(toPath, fromPath, TemplateType.VARIABLE.text)) + } + } + TemplateType.STAGE -> { + stageTemplateGraph.addEdge(fromPath, toPath) + if (stageTemplateGraph.hasCyclic()) { + error(Constants.TEMPLATE_CYCLE_ERROR.format(toPath, fromPath, TemplateType.STAGE.text)) + } + } + TemplateType.JOB -> { + jobTemplateGraph.addEdge(fromPath, toPath) + if (jobTemplateGraph.hasCyclic()) { + error(Constants.TEMPLATE_CYCLE_ERROR.format(toPath, fromPath, TemplateType.JOB.text)) + } + } + TemplateType.STEP -> { + stepTemplateGraph.addEdge(fromPath, toPath) + if (stepTemplateGraph.hasCyclic()) { + error(Constants.TEMPLATE_CYCLE_ERROR.format(toPath, fromPath, TemplateType.STEP.text)) + } + } + else -> { + return + } + } + } + + // 对远程库的循环依赖做检测 + fun saveAndCheckCyclicRepo( + fromPath: String, + repo: Repositories?, + toRepo: Repositories + ) { + // 判断是否有库之间的循环依赖 + repoTemplateGraph.addEdge(repo?.name ?: fromPath, toRepo.name) + if (repoTemplateGraph.hasCyclic()) { + error(Constants.REPO_CYCLE_ERROR) + } + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/TemplateLibrary.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/TemplateLibrary.kt new file mode 100644 index 00000000000..baaf2c22513 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/TemplateLibrary.kt @@ -0,0 +1,83 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.parsers.template + +import com.tencent.devops.process.yaml.pojo.TemplatePath +import com.tencent.devops.process.yaml.v3.enums.TemplateType +import com.tencent.devops.process.yaml.v3.models.Repositories +import com.tencent.devops.process.yaml.v3.parsers.template.models.GetTemplateParam + +data class TemplateLibrary( + val extraParameters: T, + // 获取模板文件函数,将模板替换过程与获取文件解耦,方便测试或链接其他代码库 + val getTemplateMethod: ( + param: GetTemplateParam + ) -> String, + // 存储当前库的模板信息,减少重复获取 key: templatePath value: template + var templates: MutableMap = mutableMapOf() +) + +// 从模板库中获得数据,如果有直接取出,没有则根据保存的库信息从远程仓库拉取,再没有则报错 +fun TemplateLibrary.getTemplate( + path: TemplatePath, + templateType: TemplateType?, + nowRepo: Repositories?, + toRepo: Repositories? +): String { + if (templates[path.toString()] != null) { + return templates[path.toString()]!! + } + // 没有库信息说明是触发库 + val template = if (toRepo == null) { + getTemplateMethod( + GetTemplateParam( + path = path, + templateType = templateType, + nowRepoId = nowRepo?.repository, + targetRepo = null, + extraParameters = extraParameters + ) + ) + } else { + getTemplateMethod( + GetTemplateParam( + path = path, + templateType = templateType, + nowRepoId = nowRepo?.repository, + targetRepo = toRepo, + extraParameters = extraParameters + ) + ) + } + setTemplate(path, template) + return templates[path.toString()]!! +} + +fun TemplateLibrary.setTemplate(path: TemplatePath, template: String) { + templates[path.toString()] = template +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/TemplateYamlMapper.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/TemplateYamlMapper.kt new file mode 100644 index 00000000000..21b492b0776 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/TemplateYamlMapper.kt @@ -0,0 +1,66 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.parsers.template + +import com.fasterxml.jackson.core.type.TypeReference +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.databind.ser.impl.SimpleBeanPropertyFilter +import com.fasterxml.jackson.databind.ser.impl.SimpleFilterProvider +import com.fasterxml.jackson.dataformat.yaml.YAMLFactory +import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator +import com.fasterxml.jackson.module.kotlin.registerKotlinModule +import com.tencent.devops.common.api.util.ReflectUtil +import com.tencent.devops.common.api.util.YamlUtil +import com.tencent.devops.process.yaml.v3.models.YAME_META_DATA_JSON_FILTER + +/** + * 部分yaml转换过程与公共的存在区别,template转换时需要保留meta信息字段 + */ +object TemplateYamlMapper { + private val objectMapper = ObjectMapper( + YAMLFactory().disable(YAMLGenerator.Feature.SPLIT_LINES) + ).registerKotlinModule().setFilterProvider( + SimpleFilterProvider().addFilter( + YAME_META_DATA_JSON_FILTER, SimpleBeanPropertyFilter.serializeAll() + ) + ) + + fun getObjectMapper() = objectMapper + + fun toYaml(bean: Any): String { + if (ReflectUtil.isNativeType(bean) || bean is String) { + return bean.toString() + } + return getObjectMapper().writeValueAsString(bean)!! + } + + fun to(yamlStr: String): T { + val obj = YamlUtil.loadYamlRetryOnAccident(yamlStr) + return getObjectMapper().readValue(obj, object : TypeReference() {}) + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/TemplateYamlUtil.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/TemplateYamlUtil.kt new file mode 100644 index 00000000000..8fb292fe5f9 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/TemplateYamlUtil.kt @@ -0,0 +1,163 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.parsers.template + +import com.tencent.devops.process.yaml.pojo.TemplatePath +import com.tencent.devops.process.yaml.v3.enums.TemplateType +import com.tencent.devops.process.yaml.v3.exception.YamlFormatException +import com.tencent.devops.process.yaml.v3.models.Repositories +import com.tencent.devops.process.yaml.v3.parameter.Parameters +import com.tencent.devops.process.yaml.v3.parameter.ParametersType +import com.tencent.devops.process.yaml.v3.parsers.template.models.NoReplaceTemplate +import com.tencent.devops.process.yaml.v3.utils.ScriptYmlUtils +import org.slf4j.LoggerFactory + +@Suppress("ALL") +object TemplateYamlUtil { + + private val logger = LoggerFactory.getLogger(TemplateYamlUtil::class.java) + + // 检查是否具有重复的ID,job,variable中使用 + fun checkDuplicateKey( + filePath: TemplatePath, + keys: Set, + newKeys: Set, + toPath: TemplatePath? = null + ): Boolean { + val interSet = newKeys intersect keys + return if (interSet.isEmpty() || (interSet.size == 1 && interSet.last() == Constants.TEMPLATE_KEY)) { + true + } else { + if (toPath == null) { + throw error( + Constants.TEMPLATE_ROOT_ID_DUPLICATE.format( + filePath.toString(), + interSet.filter { it != Constants.TEMPLATE_KEY } + ) + ) + } else { + throw error( + Constants.TEMPLATE_ID_DUPLICATE.format( + interSet.filter { it != Constants.TEMPLATE_KEY }, + filePath.toString(), + toPath.toString() + ) + ) + } + } + } + + // 校验当前模板的远程库信息,每个文件只可以使用当前文件下引用的远程库 + fun checkAndGetRepo( + fromPath: TemplatePath, + repoName: String, + templateType: TemplateType, + templateLib: TemplateLibrary, + nowRepo: Repositories?, + toRepo: Repositories? + ): Repositories { + val repos = YamlObjects.getObjectFromYaml( + path = fromPath, + template = templateLib.getTemplate( + path = fromPath, + templateType = templateType, + nowRepo = nowRepo, + toRepo = toRepo + ) + ).resources?.repositories + + repos?.forEach { + if (it.name == repoName) { + return it + } + } + + throw YamlFormatException(Constants.REPO_NOT_FOUND_ERROR.format(fromPath, repoName)) + } + + private fun error(content: String) = YamlFormatException(content) + + /** + * 为模板中的变量赋值(旧版本只是为了兼容,非必要不要使用) + * @param fromPath 来自哪个文件 + * @param path 读取的哪个模板文件 + * @param template 被读取的模板文件内容 + * @param templateParameters 被读取的模板文件自带的参数 + * @param parameters 引用模板文件时传入的参数 + */ + @Deprecated("旧版本,只是为了兼容,非必要不要使用") + fun parseTemplateParametersOld( + fromPath: TemplatePath, + path: TemplatePath, + template: String, + templateParameters: MutableList?, + parameters: Map? + ): String { + if (!templateParameters.isNullOrEmpty()) { + templateParameters.forEachIndexed { index, param -> + if (parameters != null) { + val valueName = param.name + + val newValue = parameters[param.name] + if (parameters.keys.contains(valueName)) { + if (!param.values.isNullOrEmpty() && !param.values!!.contains(newValue)) { + throw error( + Constants.VALUE_NOT_IN_ENUM.format( + fromPath.toString(), + path.toString(), + valueName, + newValue.toString(), + param.values.joinToString(",") + ) + ) + } else { + templateParameters[index] = param.copy(default = newValue) + } + } + } + } + } else { + return template + } + // 模板替换 先替换调用模板传入的参数,再替换模板的默认参数 + val parametersListMap = templateParameters.filter { + it.default != null && it.type == ParametersType.ARRAY.value + }.associate { + "parameters.${it.name}" to it.default + } + val parametersStringMap = templateParameters.filter { it.default != null }.associate { + "parameters.${it.name}" to if (it.default == null) { + null + } else { + it.default.toString() + } + } + val replacedList = ScriptYmlUtils.parseParameterValue(template, parametersListMap, ParametersType.ARRAY) + return ScriptYmlUtils.parseParameterValue(replacedList, parametersStringMap, ParametersType.STRING) + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/YamlObjects.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/YamlObjects.kt new file mode 100644 index 00000000000..ec8da4bb2e4 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/YamlObjects.kt @@ -0,0 +1,592 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.parsers.template + +import com.fasterxml.jackson.core.type.TypeReference +import com.tencent.devops.common.api.constant.CommonMessageCode.ERROR_YAML_FORMAT_EXCEPTION_NEED_PARAM +import com.tencent.devops.common.api.pojo.OS +import com.tencent.devops.common.api.util.JsonUtil +import com.tencent.devops.common.pipeline.pojo.BuildContainerType +import com.tencent.devops.common.pipeline.type.BuildType +import com.tencent.devops.common.pipeline.type.agent.DockerOptions +import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.process.yaml.pojo.TemplatePath +import com.tencent.devops.process.yaml.v3.enums.TemplateType +import com.tencent.devops.process.yaml.v3.exception.YamlFormatException +import com.tencent.devops.process.yaml.v3.models.GitNotices +import com.tencent.devops.process.yaml.v3.models.MetaData +import com.tencent.devops.process.yaml.v3.models.PacNotices +import com.tencent.devops.process.yaml.v3.models.ResourcesPools +import com.tencent.devops.process.yaml.v3.models.TemplateInfo +import com.tencent.devops.process.yaml.v3.models.Variable +import com.tencent.devops.process.yaml.v3.models.VariableDatasource +import com.tencent.devops.process.yaml.v3.models.VariablePropOption +import com.tencent.devops.process.yaml.v3.models.VariablePropType +import com.tencent.devops.process.yaml.v3.models.VariableProps +import com.tencent.devops.process.yaml.v3.models.job.Container +import com.tencent.devops.process.yaml.v3.models.job.Credentials +import com.tencent.devops.process.yaml.v3.models.job.Mutex +import com.tencent.devops.process.yaml.v3.models.job.PreJob +import com.tencent.devops.process.yaml.v3.models.job.Service +import com.tencent.devops.process.yaml.v3.models.job.ServiceWith +import com.tencent.devops.process.yaml.v3.models.job.Strategy +import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 +import com.tencent.devops.process.yaml.v3.models.stage.PreStage +import com.tencent.devops.process.yaml.v3.models.step.PreStep +import com.tencent.devops.process.yaml.v3.parameter.Parameters +import com.tencent.devops.process.yaml.v3.parsers.template.models.TemplateDeepTreeNode +import com.tencent.devops.process.yaml.v3.utils.StreamEnvUtils + +object YamlObjects { + + fun getTriggerOnV3(triggerOn: Map): PreTriggerOnV3 { + return JsonUtil.anyTo(triggerOn, object : TypeReference() {}) + } + + fun getVariable(fromPath: TemplatePath, key: String, variable: Map): Variable { + val va = Variable( + value = variable["value"]?.toString(), + readonly = getNullValue("readonly", variable)?.toBoolean(), + allowModifyAtStartup = getNullValue("allow-modify-at-startup", variable)?.toBoolean(), + props = if (variable["props"] == null) { + null + } else { + getVarProps(fromPath, variable["props"]!!) + } + ) + + // 只有列表需要判断 + if ((va.props?.type == VariablePropType.SELECTOR.value && va.props.datasource == null) || + va.props?.type == VariablePropType.CHECKBOX.value + ) { + if (!va.value.isNullOrBlank() && va.props.options.isNullOrEmpty()) { + throw YamlFormatException( + "$fromPath variable $key format error: value ${va.value} not in variable options" + ) + } + val expectValues = + va.value?.split(",")?.asSequence()?.filter { it.isNotBlank() }?.map { it.trim() }?.toSet() + val resultValues = va.props.options?.map { it.id.toString() }?.toSet() ?: emptySet() + // 说明默认值没有匹配到选项值,报错 + if (expectValues?.subtract(resultValues)?.isEmpty() == false) { + throw YamlFormatException( + "$fromPath variable $key format error: value ${va.value} not in variable options" + ) + } + } + + // 校验bool + if (va.props?.type == VariablePropType.BOOLEAN.value && (va.value != "true" && va.value != "false")) { + throw YamlFormatException( + "$fromPath variable $key format error: bool value ${va.value} not true / false" + ) + } + + return va + } + + private fun getVarProps(fromPath: TemplatePath, props: Any): VariableProps { + val propsMap = transValue>(fromPath, "props", props) + val po = VariableProps( + label = getNullValue("label", propsMap), + type = getNotNullValue("type", "props", propsMap), + options = getVarPropOptions(fromPath, propsMap["options"]), + datasource = getVarPropDataSource(fromPath, propsMap["datasource"]), + description = getNullValue("description", propsMap), + multiple = getNullValue("multiple", propsMap)?.toBoolean(), + required = getNullValue("required", propsMap)?.toBoolean(), + repoHashId = getNullValue("repoHashId", propsMap), + scmType = getNullValue("scmType", propsMap), + containerType = getVarPropContainerType(fromPath, propsMap["containerType"]), + glob = getNullValue("glob", propsMap), + properties = transNullValue>( + file = fromPath, + type = "properties", + key = "properties", + map = propsMap + ), + payload = propsMap["glob"] + ) + + if (!po.options.isNullOrEmpty() && po.datasource != null) { + throw YamlFormatException("$fromPath variable format error: options and datasource cannot coexist") + } + + return po + } + + private fun getVarPropOptions(fromPath: TemplatePath, options: Any?): List? { + if (options == null) { + return null + } + + val optionsMap = transValue>>(fromPath, "options", options) + + return optionsMap.map { option -> + VariablePropOption( + id = getNotNullValueAny("id", "option", option), + label = getNullValue("label", option), + description = getNullValue("description", option) + ) + } + } + + private fun getVarPropDataSource(fromPath: TemplatePath, datasource: Any?): VariableDatasource? { + if (datasource == null) { + return null + } + + val datasourceMap = transValue>(fromPath, "datasource", datasource) + + return VariableDatasource( + url = getNotNullValue("url", "datasource", datasourceMap), + dataPath = getNullValue("data-path", datasourceMap), + paramId = getNullValue("param-id", datasourceMap), + paramName = getNullValue("param-name", datasourceMap), + hasAddItem = getNullValue("has-add-item", datasourceMap)?.toBoolean(), + itemText = getNullValue("item-text", datasourceMap), + itemTargetUrl = getNullValue("item-target-url", datasourceMap) + ) + } + + private fun getVarPropContainerType(fromPath: TemplatePath, containerType: Any?): BuildContainerType? { + if (containerType == null) { + return null + } + + val map = transValue>(fromPath, "containerType", containerType) + + return BuildContainerType( + buildType = BuildType.valueOf(getNotNullValue("buildType", "containerType", map)), + os = OS.valueOf(getNotNullValue("os", "containerType", map)) + ) + } + + fun getStep(fromPath: TemplatePath, step: Map, repo: TemplateInfo?): PreStep { + val preStep = PreStep( + enable = getNullValue("enable", step)?.toBoolean(), + name = step["name"]?.toString(), + id = step["id"]?.toString(), + ifFiled = step["if"]?.toString(), + ifModify = if (step["if-modify"] is List<*>) { + val ifModifyList = step["if-modify"] as List<*> + ifModifyList.map { it.toString() }.toList() + } else null, + uses = step["uses"]?.toString(), + with = if (step["with"] == null) { + null + } else { + transValue>(fromPath, "with", step["with"]) + }, + timeoutMinutes = getNullValue("timeout-minutes", step)?.toInt(), + continueOnError = getNullValue("continue-on-error", step)?.toBoolean(), + retryTimes = getNullValue("retry-times", step)?.toInt(), + env = if (step["env"] == null) { + null + } else { + transValue>(fromPath, "env", step["env"]) + }, + run = step["run"]?.toString(), + shell = step["shell"]?.toString(), + checkout = step["checkout"]?.toString(), + manualRetry = getNullValue("manual-retry", step)?.toBoolean(), + yamlMetaData = if (step["yamlMetaData"] == null) { + MetaData(templateInfo = repo) + } else { + getYamlMetaData(fromPath, step["yamlMetaData"]!!) + } + ) + + if (preStep.uses == null && preStep.run == null && preStep.checkout == null) { + throw YamlFormatException( + I18nUtil.getCodeLanMessage( + messageCode = ERROR_YAML_FORMAT_EXCEPTION_NEED_PARAM, + params = arrayOf(fromPath.toString()) + ) + ) + } + + // 检测step env合法性 + StreamEnvUtils.checkEnv(preStep.env, fromPath) + return preStep + } + + fun getResourceExclusiveDeclaration(fromPath: TemplatePath, resource: Any): Mutex { + val resourceMap = transValue>(fromPath, "mutex", resource) + return Mutex( + label = getNotNullValue(key = "label", mapName = "mutex", map = resourceMap), + queueLength = resourceMap["queue-length"]?.toString()?.toInt(), + timeoutMinutes = resourceMap["timeout-minutes"]?.toString()?.toInt() + ) + } + + fun getService(fromPath: TemplatePath, service: Any): Map { + val serviceMap = transValue>(fromPath, "services", service) + val newServiceMap = mutableMapOf() + serviceMap.forEach { (key, value) -> + val newValue = transValue>(fromPath, "services", value) + val with = transValue>(fromPath, "with", newValue["with"]) + newServiceMap.putAll( + mapOf( + key to Service( + image = getNotNullValue(key = "image", mapName = "Container", map = newValue), + with = ServiceWith( + password = getNotNullValue(key = "password", mapName = "with", map = with) + ) + ) + ) + ) + } + return newServiceMap + } + + fun getContainer(fromPath: TemplatePath, container: Any): Container { + val containerMap = transValue>(fromPath, "container", container) + return Container( + image = getNotNullValue(key = "image", mapName = "Container", map = containerMap), + credentials = if (containerMap["credentials"] == null) { + null + } else { + val credentialsMap = + transValue>(fromPath, "credentials", containerMap["credentials"]) + Credentials( + username = credentialsMap["username"]!!, + password = credentialsMap["password"]!! + ) + }, + options = if (containerMap["options"] == null) { + null + } else { + val optionsMap = + transValue>(fromPath, "options", containerMap["options"]) + DockerOptions( + gpus = getNullValue("gpus", optionsMap), + volumes = if (optionsMap["volumes"] == null) { + null + } else { + transValue>(fromPath, "volumes", optionsMap["volumes"]) + }, + mounts = if (optionsMap["mounts"] == null) { + null + } else { + transValue>(fromPath, "mounts", optionsMap["mounts"]) + } + ) + }, + imagePullPolicy = getNullValue(key = "image-pull-policy", map = containerMap) + ) + } + + fun getStrategy(fromPath: TemplatePath, strategy: Any?): Strategy? { + val strategyMap = transValue>(fromPath, "strategy", strategy) + val matrix = strategyMap["matrix"] ?: return null + return Strategy( + matrix = matrix, + fastKill = getNullValue("fast-kill", strategyMap)?.toBoolean(), + maxParallel = getNullValue("max-parallel", strategyMap)?.toInt() + ) + } + + fun getNoticeV2(fromPath: TemplatePath, notice: Map): GitNotices { + return GitNotices( + type = notice["type"].toString(), + title = notice["title"]?.toString(), + ifField = notice["if"]?.toString(), + content = notice["content"]?.toString(), + receivers = if (notice["receivers"] == null) { + null + } else { + transValue>(fromPath, "receivers", notice["receivers"]).toSet() + }, + ccs = if (notice["ccs"] == null) { + null + } else { + transValue>(fromPath, "ccs", notice["ccs"]).toSet() + }, + chatId = if (notice["chat-id"] == null) { + null + } else { + transValue>(fromPath, "chat-id", notice["chat-id"]).toSet() + } + ) + } + + fun getNoticeV3(fromPath: TemplatePath, notice: Map): PacNotices { + return PacNotices( + type = if (notice["receivers"] == null) { + emptyList() + } else { + transValue(fromPath, "type", notice["type"]) + }, + receivers = if (notice["receivers"] == null) { + null + } else { + transValue>(fromPath, "receivers", notice["receivers"]) + }, + groups = if (notice["groups"] == null) { + null + } else { + transValue>(fromPath, "groups", notice["groups"]) + }, + content = notice["content"]?.toString(), + ifField = notice["if"]?.toString(), + chatId = if (notice["chat-id"] == null) { + null + } else { + transValue>(fromPath, "chat-id", notice["chat-id"]) + }, + notifyMarkdown = if (notice["notify-markdown"] == null) { + null + } else { + transValue(fromPath, "notify-markdown", notice["notify-markdown"]) + }, + notifyDetail = if (notice["notify-detail-url"] == null) { + null + } else { + transValue(fromPath, "notify-detail-url", notice["notify-detail-url"]) + } + ) + } + + fun getYamlMetaData(fromPath: TemplatePath, yamlMetaData: Any): MetaData { + val metaData = transValue>(fromPath, "yamlMetaData", yamlMetaData) + if (metaData["templateInfo"] == null) { + return MetaData(templateInfo = null) + } + val templateInfo = transValue>(fromPath, "templateInfo", metaData["templateInfo"]!!) + return MetaData( + templateInfo = TemplateInfo( + remote = getNotNullValue("remote", "templateInfo", templateInfo).toBoolean(), + remoteTemplateProjectId = getNullValue("remoteTemplateProjectId", templateInfo) + ) + ) + } + + fun getParameter(fromPath: TemplatePath, param: Map): Parameters { + return Parameters( + name = getNotNullValue(key = "name", mapName = TemplateType.PARAMETERS.text, map = param), + type = getNotNullValue(key = "type", mapName = TemplateType.PARAMETERS.text, map = param), + default = param["default"], + values = if (param["values"] == null) { + null + } else { + transValue>(fromPath, "values", param["values"]) + } + ) + } + + fun getResourcePools(fromPath: TemplatePath, resources: Any): List { + val resourcesD = transValue>(fromPath, "resources", resources) + if (resourcesD["pools"] == null) { + return emptyList() + } + val poolList = transValue>>(fromPath, "pools", resourcesD["pools"]) + return poolList.map { poolD -> + ResourcesPools( + from = poolD["from"]?.toString(), + name = poolD["name"]?.toString() + ) + } + } + + inline fun getObjectFromYaml(path: TemplatePath, template: String): T { + return try { + TemplateYamlMapper.getObjectMapper().readValue(template, object : TypeReference() {}) + } catch (e: Exception) { + throw YamlFormatException(Constants.YAML_FORMAT_ERROR.format("${path.path} ${path.ref ?: ""}", e.message)) + } + } + + inline fun transValue(file: TemplatePath, type: String, value: Any?): T { + if (value == null) { + throw YamlFormatException(Constants.TRANS_AS_ERROR.format(file.toString(), type)) + } + return try { + value as T + } catch (e: Exception) { + throw YamlFormatException(Constants.TRANS_AS_ERROR.format(file.toString(), type)) + } + } + + inline fun transNullValue(file: TemplatePath, type: String, key: String, map: Map): T? { + return if (map[key] == null) { + null + } else { + return try { + map[key] as T + } catch (e: Exception) { + throw YamlFormatException(Constants.TRANS_AS_ERROR.format(file.toString(), type)) + } + } + } + + fun getNullValue(key: String, map: Map): String? { + return if (map[key] == null) { + null + } else { + map[key].toString() + } + } + + private fun getNotNullValue(key: String, mapName: String, map: Map): String { + return if (map[key] == null) { + throw YamlFormatException(Constants.ATTR_MISSING_ERROR.format(key, mapName)) + } else { + map[key].toString() + } + } + + private fun getNotNullValueAny(key: String, mapName: String, map: Map): Any { + return if (map[key] == null) { + throw YamlFormatException(Constants.ATTR_MISSING_ERROR.format(key, mapName)) + } else { + map[key]!! + } + } +} + +fun YamlTemplate.getStage( + fromPath: TemplatePath, + stage: Map, + deepTree: TemplateDeepTreeNode +): PreStage { + return PreStage( + name = stage["name"]?.toString(), + label = stage["label"], + ifField = stage["if"]?.toString(), + ifModify = if (stage["if-modify"] is List<*>) { + val ifModifyList = stage["if-modify"] as List<*> + ifModifyList.map { it.toString() }.toList() + } else null, + fastKill = YamlObjects.getNullValue("fast-kill", stage)?.toBoolean(), + jobs = if (stage["jobs"] == null) { + null + } else { + val jobs = YamlObjects.transValue>(fromPath, TemplateType.JOB.text, stage["jobs"]) + val map = mutableMapOf() + jobs.forEach { (key, value) -> + // 检查根文件处jobId重复 + val newJob = this.replaceJobTemplate(mapOf(key to value), filePath, deepTree) + if (key == Constants.TEMPLATE_KEY) { + TemplateYamlUtil.checkDuplicateKey(filePath = filePath, keys = jobs.keys, newKeys = newJob.keys) + } + map.putAll(newJob) + } + map + }, + checkIn = if (stage["check-in"] != null) { + this.replaceStageCheckTemplate( + stageName = stage["name"]?.toString() ?: "", + check = YamlObjects.transValue>(fromPath, TemplateType.GATE.text, stage["check-in"]), + fromPath = filePath, + deepTree = deepTree + ) + } else { + null + }, + checkOut = if (stage["check-out"] != null) { + this.replaceStageCheckTemplate( + stageName = stage["name"]?.toString() ?: "", + check = YamlObjects.transValue>(fromPath, TemplateType.GATE.text, stage["check-out"]), + fromPath = filePath, + deepTree = deepTree + ) + } else { + null + } + ) +} + +// 构造对象,因为未保存远程库的template信息,所以在递归回溯时无法通过yaml文件直接生成,故手动构造 +fun YamlTemplate.getJob(fromPath: TemplatePath, job: Map, deepTree: TemplateDeepTreeNode): PreJob { + val preJob = PreJob( + name = job["name"]?.toString(), + runsOn = job["runs-on"], + mutex = if (job["mutex"] == null) { + null + } else { + YamlObjects.getResourceExclusiveDeclaration(fromPath, job["mutex"]!!) + }, + container = if (job["container"] == null) { + null + } else { + YamlObjects.getContainer(fromPath, job["container"]!!) + }, + services = if (job["services"] == null) { + null + } else { + YamlObjects.getService(fromPath, job["services"]!!) + }, + ifField = job["if"]?.toString(), + ifModify = if (job["if-modify"] is List<*>) { + val ifModifyList = job["if-modify"] as List<*> + ifModifyList.map { it.toString() }.toList() + } else null, + steps = if (job["steps"] == null) { + null + } else { + val steps = YamlObjects.transValue>>(fromPath, TemplateType.STEP.text, job["steps"]) + val list = mutableListOf() + steps.forEach { + list.addAll(this.replaceStepTemplate(listOf(it), filePath, deepTree)) + } + list + }, + timeoutMinutes = YamlObjects.getNullValue("timeout-minutes", job)?.toInt(), + env = if (job["env"] == null) { + null + } else { + YamlObjects.transValue>(fromPath, "env", job["env"]) + }, + continueOnError = YamlObjects.getNullValue("continue-on-error", job)?.toBoolean(), + strategy = if (job["strategy"] == null) { + null + } else { + YamlObjects.getStrategy(fromPath, job["strategy"]) + }, + dependOn = if (job["depend-on"] == null) { + null + } else { + YamlObjects.transValue>(fromPath, "depend-on", job["depend-on"]) + }, + yamlMetaData = if (job["yamlMetaData"] == null) { + MetaData( + templateInfo = TemplateInfo( + remote = repo != null, + remoteTemplateProjectId = repo?.repository + ) + ) + } else { + YamlObjects.getYamlMetaData(fromPath, job["yamlMetaData"]!!) + } + ) + + // 检测job env合法性 + StreamEnvUtils.checkEnv(preJob.env, fromPath) + return preJob +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/YamlTemplate.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/YamlTemplate.kt new file mode 100644 index 00000000000..391e48b74db --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/YamlTemplate.kt @@ -0,0 +1,800 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.parsers.template + +import com.fasterxml.jackson.core.JsonProcessingException +import com.fasterxml.jackson.core.type.TypeReference +import com.tencent.devops.common.api.constant.CommonMessageCode.ERROR_YAML_FORMAT_EXCEPTION_LENGTH_LIMIT_EXCEEDED +import com.tencent.devops.common.api.util.JsonUtil +import com.tencent.devops.common.web.utils.I18nUtil +import com.tencent.devops.process.yaml.pojo.TemplatePath +import com.tencent.devops.process.yaml.pojo.YamlVersion +import com.tencent.devops.process.yaml.v3.enums.TemplateType +import com.tencent.devops.process.yaml.v3.exception.YamlFormatException +import com.tencent.devops.process.yaml.v3.models.Extends +import com.tencent.devops.process.yaml.v3.models.GitNotices +import com.tencent.devops.process.yaml.v3.models.ITemplateFilter +import com.tencent.devops.process.yaml.v3.models.PacNotices +import com.tencent.devops.process.yaml.v3.models.PreScriptBuildYaml +import com.tencent.devops.process.yaml.v3.models.PreScriptBuildYamlI +import com.tencent.devops.process.yaml.v3.models.PreTemplateScriptBuildYaml +import com.tencent.devops.process.yaml.v3.models.Repositories +import com.tencent.devops.process.yaml.v3.models.ResourcesPools +import com.tencent.devops.process.yaml.v3.models.TemplateInfo +import com.tencent.devops.process.yaml.v3.models.Variable +import com.tencent.devops.process.yaml.v3.models.format +import com.tencent.devops.process.yaml.v3.models.job.PreJob +import com.tencent.devops.process.yaml.v3.models.stage.PreStage +import com.tencent.devops.process.yaml.v3.models.step.PreStep +import com.tencent.devops.process.yaml.v3.parameter.Parameters +import com.tencent.devops.process.yaml.v3.parameter.ParametersTemplateNull +import com.tencent.devops.process.yaml.v3.parameter.PreParametersTemplate +import com.tencent.devops.process.yaml.v3.parsers.template.models.GetTemplateParam +import com.tencent.devops.process.yaml.v3.parsers.template.models.NoReplaceTemplate +import com.tencent.devops.process.yaml.v3.parsers.template.models.TemplateDeepTreeNode +import com.tencent.devops.process.yaml.v3.stageCheck.Gate +import com.tencent.devops.process.yaml.v3.stageCheck.GateTemplate +import com.tencent.devops.process.yaml.v3.stageCheck.PreStageCheck +import com.tencent.devops.process.yaml.v3.stageCheck.PreTemplateStageCheck +import com.tencent.devops.process.yaml.v3.models.PreScriptBuildYamlV3 +import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOnV3 + +@Suppress("ALL") +class YamlTemplate( + val extraParameters: T, + + // 当前文件 + var filePath: TemplatePath, + // 文件对象 + var yamlObject: ITemplateFilter?, + // 当前库信息 + val nowRepo: Repositories?, + // 目标库信息(发起库没有库信息) + val repo: Repositories?, + + // 额外所有引用的resource-pool,这样不会干扰替换逻辑 + val resourcePoolMapExt: MutableMap? = null, + + // 模板替换配置,针对某些替换功能提供可配置项 + val conf: YamlTemplateConf = YamlTemplateConf(), + + // 来自文件 + private val fileFromPath: TemplatePath? = null, + + // 远程模板类型(用来校验远程打平的模板的格式) + private val resTemplateType: TemplateType? = null, + + // 校验模板深度和广度树 + private val rootDeepTree: TemplateDeepTreeNode = TemplateDeepTreeNode( + path = filePath, + parent = null, + children = mutableListOf() + ), + + // 获取模板文件函数,将模板替换过程与获取文件解耦,方便测试或链接其他代码库 + val getTemplateMethod: ( + param: GetTemplateParam + ) -> String +) { + // 存储当前库的模板信息,减少重复获取 key: templatePath value: template + private val templateLib = TemplateLibrary(extraParameters, getTemplateMethod) + + // 添加图防止模版的循环嵌套 + private val templateGraph = TemplateGraph() + + @Throws( + YamlFormatException::class, + JsonProcessingException::class, + StackOverflowError::class + ) + fun replace( + parameters: Map? = null + ): PreScriptBuildYamlI { + // 针对远程库进行打平替换时,根文件没有被替换Parameters + val newYamlObject = if (repo != null) { + val template = parseTemplateParameters( + fromPath = fileFromPath ?: TemplatePath(""), + path = filePath, + template = templateLib.getTemplate( + path = filePath, + templateType = resTemplateType, + nowRepo = nowRepo, + toRepo = repo + ), + parameters = parameters, + deepTree = rootDeepTree + ) + // 将根文件也保存在模板库中方便取出 + templateLib.setTemplate(filePath, template) + YamlObjects.getObjectFromYaml(filePath, template) + } else { + templateLib.setTemplate(filePath, TemplateYamlMapper.toYaml(yamlObject!!)) + yamlObject + } ?: throw RuntimeException("yamlObject cannot be null") + + val preYamlObject = newYamlObject.initPreScriptBuildYamlI() + + if (newYamlObject.extends != null) { + replaceExtends(newYamlObject.extends!!, preYamlObject, rootDeepTree) + } + if (newYamlObject.variables != null) { + replaceVariables(newYamlObject.variables!!, preYamlObject, rootDeepTree) + } + if (newYamlObject.stages != null) { + replaceStages(newYamlObject.stages!!, preYamlObject, rootDeepTree) + } + if (newYamlObject.jobs != null) { + replaceJobs(newYamlObject.jobs!!, preYamlObject, rootDeepTree) + } + if (newYamlObject.steps != null) { + replaceSteps(newYamlObject.steps!!, preYamlObject, rootDeepTree) + } + if (newYamlObject.finally != null) { + replaceFinally(newYamlObject.finally!!, preYamlObject, rootDeepTree) + } + + return preYamlObject + } + + private fun replaceExtends( + extend: Extends, + preYamlObject: PreScriptBuildYamlI, + deepTree: TemplateDeepTreeNode + ) { + val toPath = TemplatePath(extend.template, extend.ref) + val parameters = extend.parameters + // 根据远程模板获取 + val templateObject = replaceResAndParam(TemplateType.EXTEND, toPath, parameters, filePath, deepTree) + // 获取extends模板后filePath就为被替换的文件了 + this.filePath = toPath + // 需要替换模板的的递归替换 + if (templateObject[TemplateType.TRIGGER_ON.content] != null) { + replaceTriggerOn( + triggerOn = YamlObjects.transValue( + file = filePath, + type = TemplateType.TRIGGER_ON.text, + value = templateObject[TemplateType.TRIGGER_ON.content] + ), + preYamlObject = preYamlObject, + deepTree = deepTree + ) + } + + if (templateObject[TemplateType.VARIABLE.content] != null) { + replaceVariables( + variables = YamlObjects.transValue( + file = filePath, + type = TemplateType.VARIABLE.text, + value = templateObject[TemplateType.VARIABLE.content] + ), + preYamlObject = preYamlObject, + deepTree = deepTree + ) + } + if (templateObject[TemplateType.STAGE.content] != null) { + replaceStages( + YamlObjects.transValue(filePath, TemplateType.STAGE.text, templateObject[TemplateType.STAGE.content]), + preYamlObject, + deepTree + ) + } + if (templateObject[TemplateType.JOB.content] != null) { + replaceJobs( + YamlObjects.transValue(filePath, TemplateType.JOB.text, templateObject[TemplateType.JOB.content]), + preYamlObject, + deepTree + ) + } + if (templateObject[TemplateType.STEP.content] != null) { + replaceSteps( + YamlObjects.transValue(filePath, TemplateType.STEP.text, templateObject[TemplateType.STEP.content]), + preYamlObject, + deepTree + ) + } + if (templateObject[TemplateType.FINALLY.content] != null) { + replaceFinally( + finally = YamlObjects.transValue( + file = filePath, + type = TemplateType.FINALLY.text, + value = templateObject[TemplateType.FINALLY.content] + ), + preYamlObject = preYamlObject, + deepTree = deepTree + ) + } + // notices只用做一次模板替换没有嵌套模板 + if (templateObject["notices"] != null && preYamlObject is PreScriptBuildYaml) { + val notices = mutableListOf() + val temNotices = + YamlObjects.transValue>>(filePath, "notices", templateObject["notices"]) + temNotices.forEach { + notices.add(YamlObjects.getNoticeV2(filePath, it)) + } + preYamlObject.notices = notices + } + + // notices只用做一次模板替换没有嵌套模板 + if (templateObject["notices"] != null && preYamlObject is PreScriptBuildYamlV3) { + val notices = mutableListOf() + val temNotices = + YamlObjects.transValue>>(filePath, "notices", templateObject["notices"]) + temNotices.forEach { + notices.add(YamlObjects.getNoticeV3(filePath, it)) + } + preYamlObject.notices = notices + } + + // 将不用替换的直接传入 + val newYaml = + YamlObjects.getObjectFromYaml(toPath, TemplateYamlMapper.toYaml(templateObject)) + preYamlObject.label = newYaml.label + preYamlObject.resources = newYaml.resources + // 用户没写就用模板的名字 + if (preYamlObject.name.isNullOrBlank()) { + preYamlObject.name = newYaml.name + } + } + + private fun replaceTriggerOn( + triggerOn: Any, + preYamlObject: PreScriptBuildYamlI, + deepTree: TemplateDeepTreeNode + ) { + if (preYamlObject.yamlVersion() != YamlVersion.Version.V3_0) return + val triggerOnV3s = when (triggerOn) { + // 简写方式 + is Map<*, *> -> listOf(JsonUtil.anyTo(triggerOn, object : TypeReference() {})) + is List<*> -> JsonUtil.anyTo(triggerOn, object : TypeReference>() {}) + else -> null + } + (preYamlObject as PreScriptBuildYamlV3).triggerOn = triggerOnV3s + } + + private fun replaceVariables( + variables: Map, + preYamlObject: PreScriptBuildYamlI, + deepTree: TemplateDeepTreeNode + ) { + val variableMap = mutableMapOf() + variables.forEach { (key, value) -> + val newVariable = replaceVariableTemplate(mapOf(key to value), filePath, deepTree) + if (key == Constants.TEMPLATE_KEY) { + // 通过取交集判断除template关键字之外的ID是否重复 + TemplateYamlUtil.checkDuplicateKey( + filePath = filePath, + keys = variables.keys, + newKeys = newVariable.keys + ) + } + variableMap.putAll(newVariable) + } + preYamlObject.variables = variableMap + } + + private fun replaceStages( + stages: List>, + preYamlObject: PreScriptBuildYamlI, + deepTree: TemplateDeepTreeNode + ) { + val stageList = mutableListOf() + stages.forEach { stage -> + stageList.addAll(replaceStageTemplate(listOf(stage), filePath, deepTree)) + } + preYamlObject.stages = stageList + } + + private fun replaceJobs( + jobs: Map, + preYamlObject: PreScriptBuildYamlI, + deepTree: TemplateDeepTreeNode + ) { + val jobMap = mutableMapOf() + jobs.forEach { (key, value) -> + // 检查根文件处job_id重复 + val newJob = replaceJobTemplate(mapOf(key to value), filePath, deepTree) + if (key == Constants.TEMPLATE_KEY) { + TemplateYamlUtil.checkDuplicateKey(filePath = filePath, keys = jobs.keys, newKeys = newJob.keys) + } + jobMap.putAll(newJob) + } + preYamlObject.jobs = jobMap + } + + private fun replaceSteps( + steps: List>, + preYamlObject: PreScriptBuildYamlI, + deepTree: TemplateDeepTreeNode + ) { + val stepList = mutableListOf() + steps.forEach { step -> + stepList.addAll(replaceStepTemplate(listOf(step), filePath, deepTree)) + } + preYamlObject.steps = stepList + } + + private fun replaceFinally( + finally: Map, + preYamlObject: PreScriptBuildYamlI, + deepTree: TemplateDeepTreeNode + ) { + // finally: 与jobs: 的结构相同 + val finallyMap = mutableMapOf() + finally.forEach { (key, value) -> + // 检查根文件处job_id重复 + val newFinally = replaceJobTemplate(mapOf(key to value), filePath, deepTree) + if (key == Constants.TEMPLATE_KEY) { + TemplateYamlUtil.checkDuplicateKey(filePath = filePath, keys = finally.keys, newKeys = newFinally.keys) + } + finallyMap.putAll(newFinally) + } + preYamlObject.finally = finallyMap + } + + // 进行模板替换 + private fun replaceVariableTemplate( + variables: Map, + fromPath: TemplatePath, + deepTree: TemplateDeepTreeNode + ): Map { + val variableMap = mutableMapOf() + variables.forEach { (key, value) -> + // 如果是模板文件则进行模板替换 + if (key == Constants.TEMPLATE_KEY) { + val toPathList = + YamlObjects.transValue>>(fromPath, TemplateType.VARIABLE.text, value) + toPathList.forEach { item -> + val toPath = TemplatePath( + item[Constants.OBJECT_TEMPLATE_PATH].toString(), item[Constants.REF]?.toString() + ) + // 保存并检查是否存在循环引用模板 + templateGraph.saveAndCheckCyclicTemplate( + fromPath.toString(), toPath.toString(), TemplateType.VARIABLE + ) + // 获取需要替换的变量 + val parameters = YamlObjects.transNullValue>( + file = fromPath, + type = Constants.PARAMETERS_KEY, + key = Constants.PARAMETERS_KEY, + map = item + ) + // 对模板文件进行远程库和参数替换,并实例化 + val templateObject = replaceResAndParam( + TemplateType.VARIABLE, toPath, parameters, fromPath, + deepTree + ) + // 判断实例化后的模板文件中是否引用了模板文件,如果有,则递归替换 + val newVar = replaceVariableTemplate( + variables = YamlObjects.transValue( + toPath, TemplateType.VARIABLE.text, templateObject[TemplateType.VARIABLE.content] + ), + fromPath = toPath, + deepTree = deepTree.add(toPath) + ) + // 检测variable是否存在重复的key + TemplateYamlUtil.checkDuplicateKey( + filePath = filePath, + keys = variableMap.keys, + newKeys = newVar.keys, + toPath = toPath + ) + variableMap.putAll(newVar) + } + } else { + // 不是模板文件则直接实例化 + if (value !is Map<*, *>) { + variableMap[key] = Variable(value.toString(), false) + } else { + variableMap[key] = YamlObjects.getVariable( + fromPath = fromPath, + key = key, + variable = YamlObjects.transValue(fromPath, TemplateType.VARIABLE.text, value) + ) + } + } + } + return variableMap + } + + private fun replaceStageTemplate( + stages: List>, + fromPath: TemplatePath, + deepTree: TemplateDeepTreeNode + ): List { + val stageList = mutableListOf() + stages.forEach { stage -> + if (Constants.TEMPLATE_KEY in stage.keys) { + val toPath = TemplatePath( + stage[Constants.TEMPLATE_KEY].toString(), stage[Constants.REF]?.toString() + ) + templateGraph.saveAndCheckCyclicTemplate(fromPath.toString(), toPath.toString(), TemplateType.STAGE) + + val parameters = YamlObjects.transNullValue>( + file = fromPath, + type = Constants.PARAMETERS_KEY, + key = Constants.PARAMETERS_KEY, + map = stage + ) + // 对模板文件进行远程库和参数替换,并实例化 + val templateObject = replaceResAndParam(TemplateType.STAGE, toPath, parameters, fromPath, deepTree) + stageList.addAll( + replaceStageTemplate( + stages = YamlObjects.transValue( + toPath, + TemplateType.STAGE.text, + templateObject[TemplateType.STAGE.content] + ), + fromPath = toPath, + deepTree = deepTree.add(toPath) + ) + ) + } else { + stageList.add(getStage(fromPath, stage, deepTree)) + } + } + return stageList + } + + fun replaceJobTemplate( + jobs: Map, + fromPath: TemplatePath, + deepTree: TemplateDeepTreeNode + ): Map { + val jobMap = mutableMapOf() + jobs.forEach { (key, value) -> + if (key == Constants.TEMPLATE_KEY) { + val toPathList = YamlObjects.transValue>>(fromPath, TemplateType.JOB.text, value) + toPathList.forEach { item -> + val toPath = TemplatePath( + item[Constants.OBJECT_TEMPLATE_PATH].toString(), item[Constants.REF]?.toString() + ) + templateGraph.saveAndCheckCyclicTemplate(fromPath.toString(), toPath.toString(), TemplateType.JOB) + + val parameters = YamlObjects.transNullValue>( + file = fromPath, + type = Constants.PARAMETERS_KEY, + key = Constants.PARAMETERS_KEY, + map = item + ) + + // 对模板文件进行远程库和参数替换,并实例化 + val templateObject = replaceResAndParam(TemplateType.JOB, toPath, parameters, fromPath, deepTree) + + val newJob = replaceJobTemplate( + jobs = YamlObjects.transValue( + toPath, TemplateType.JOB.text, templateObject[TemplateType.JOB.content] + ), + fromPath = toPath, + deepTree = deepTree.add(toPath) + ) + // 检测job是否存在重复的key + TemplateYamlUtil.checkDuplicateKey( + filePath = filePath, + keys = jobMap.keys, + newKeys = newJob.keys, + toPath = toPath + ) + jobMap.putAll(newJob) + } + } else { + // 校验id不能超过64,因为id可能为数字无法在schema支持,放到后台 + if (key.length > 64) { + throw YamlFormatException( + I18nUtil.getCodeLanMessage( + messageCode = ERROR_YAML_FORMAT_EXCEPTION_LENGTH_LIMIT_EXCEEDED, + params = arrayOf(fromPath.toString(), key) + ) + ) + } + jobMap[key] = getJob(fromPath, YamlObjects.transValue(fromPath, TemplateType.JOB.text, value), deepTree) + } + } + return jobMap + } + + fun replaceStepTemplate( + steps: List>, + fromPath: TemplatePath, + deepTree: TemplateDeepTreeNode + ): List { + val stepList = mutableListOf() + steps.forEach { step -> + if (Constants.TEMPLATE_KEY in step.keys) { + val toPath = TemplatePath( + step[Constants.TEMPLATE_KEY].toString(), step[Constants.REF]?.toString() + ) + + templateGraph.saveAndCheckCyclicTemplate(fromPath.toString(), toPath.toString(), TemplateType.STEP) + + val parameters = YamlObjects.transNullValue>( + file = fromPath, + type = Constants.PARAMETERS_KEY, + key = Constants.PARAMETERS_KEY, + map = step + ) + + // 对模板文件进行远程库和参数替换,并实例化 + val templateObject = replaceResAndParam(TemplateType.STEP, toPath, parameters, fromPath, deepTree) + + stepList.addAll( + replaceStepTemplate( + steps = YamlObjects.transValue( + toPath, + TemplateType.STEP.text, + templateObject[TemplateType.STEP.content] + ), + fromPath = toPath, + deepTree = deepTree.add(toPath) + ) + ) + } else { + stepList.add( + YamlObjects.getStep( + fromPath, + step, + TemplateInfo( + remote = repo != null, + remoteTemplateProjectId = repo?.repository + ) + ) + ) + } + } + return stepList + } + + // 替换Stage准入准出信息 + fun replaceStageCheckTemplate( + stageName: String, + check: Map?, + fromPath: TemplatePath, + deepTree: TemplateDeepTreeNode + ): PreStageCheck? { + if (check == null) { + return null + } + val gateList = mutableListOf() + + if (check["gates"] != null) { + val gates = YamlObjects.transValue>>(fromPath, TemplateType.GATE.text, check["gates"]) + var isTemplate = false + gates.forEach { gate -> + if (Constants.TEMPLATE_KEY in gate.keys) { + isTemplate = true + } + } + if (!isTemplate) { + return YamlObjects.getObjectFromYaml(fromPath, TemplateYamlMapper.toYaml(check)) + } + } + + val checkObject = + YamlObjects.getObjectFromYaml(fromPath, TemplateYamlMapper.toYaml(check)) + + checkObject.gates?.forEach { gate -> + val toPath = TemplatePath(gate.template, gate.ref) + val templateObject = replaceResAndParam( + templateType = TemplateType.GATE, + toPath = toPath, + parameters = gate.parameters, + fromPath = fromPath, + deepTree = deepTree + ) + val gateTemplate = + YamlObjects.getObjectFromYaml(toPath, TemplateYamlMapper.toYaml(templateObject)) + gateList.addAll( + gateTemplate.gates + ) + gateTemplate.gates.forEach { + if (it.rule.size > Constants.STAGE_CHECK_GATE_RULE_NUMB) { + error(Constants.STAGE_CHECK_GATE_RULE_NUMB_BEYOND.format(fromPath, stageName, it.name)) + } + } + if (gateList.size > Constants.STAGE_CHECK_GATE_NUMB) { + error(Constants.STAGE_CHECK_GATE_NUMB_BEYOND.format(fromPath, stageName)) + } + } + return PreStageCheck( + reviews = checkObject.reviews, + gates = gateList, + timeoutHours = checkObject.timeoutHours + ) + } + + // 替换远程库和参数信息 + private fun replaceResAndParam( + templateType: TemplateType, + toPath: TemplatePath, + parameters: Map?, + fromPath: TemplatePath, + deepTree: TemplateDeepTreeNode + ): Map { + // 判断是否为远程库,如果是远程库将其远程库文件打平进行替换 + var newTemplate = if (toPath.path.contains(Constants.FILE_REPO_SPLIT)) { + // 针对没有循环嵌套做特殊处理 + if (templateType == TemplateType.GATE || templateType == TemplateType.PARAMETERS) { + templateLib.getTemplate( + path = TemplatePath( + path = toPath.path.split(Constants.FILE_REPO_SPLIT).first(), + ref = toPath.ref + ), + nowRepo = repo, + toRepo = TemplateYamlUtil.checkAndGetRepo( + fromPath = fromPath, + repoName = toPath.path.split(Constants.FILE_REPO_SPLIT)[1], + templateType = templateType, + templateLib = templateLib, + nowRepo = nowRepo, + toRepo = repo + ), + templateType = templateType + ) + } else { + replaceResTemplateFile( + templateType = templateType, + toPath = toPath, + parameters = parameters, + toRepo = TemplateYamlUtil.checkAndGetRepo( + fromPath = fromPath, + repoName = toPath.path.split(Constants.FILE_REPO_SPLIT)[1], + templateType = templateType, + templateLib = templateLib, + nowRepo = nowRepo, + toRepo = repo + ), + deepTree = deepTree + ) + } + } else { + templateLib.getTemplate( + path = toPath, + templateType = templateType, + nowRepo = nowRepo, + toRepo = repo + ) + } + // 将需要替换的变量填入模板文件,参数模板不用替换 + if (templateType != TemplateType.PARAMETERS) { + newTemplate = parseTemplateParameters( + fromPath = fromPath, + path = toPath, + template = newTemplate, + parameters = parameters, + deepTree = deepTree + ) + } + // 将模板文件实例化 + val yamlObject = YamlObjects.getObjectFromYaml>(toPath, newTemplate) + // 将模板引用的pools加入 + if (yamlObject["resources"] != null) { + YamlObjects.getResourcePools(toPath, yamlObject["resources"]!!).forEach { pool -> + resourcePoolMapExt?.put(pool.format(), pool) + } + } + return yamlObject + } + + // 对远程仓库中的模板进行远程仓库替换 + private fun replaceResTemplateFile( + templateType: TemplateType, + toPath: TemplatePath, + parameters: Map?, + toRepo: Repositories, + deepTree: TemplateDeepTreeNode + ): String { + // 判断是否有库之间的循环依赖 + templateGraph.saveAndCheckCyclicRepo(fromPath = filePath.toString(), repo = repo, toRepo = toRepo) + + val resYamlObject = YamlTemplate( + yamlObject = null, + fileFromPath = filePath, + filePath = TemplatePath( + toPath.path.split(Constants.FILE_REPO_SPLIT)[0], toPath.path + ), + extraParameters = extraParameters, + nowRepo = repo, + repo = toRepo, + rootDeepTree = deepTree, + resTemplateType = templateType, + getTemplateMethod = getTemplateMethod, + resourcePoolMapExt = resourcePoolMapExt, + conf = conf + ).replace(parameters = parameters) + + // 将远程模板引用的pools加入 + if (resYamlObject.resources?.pools != null) { + resYamlObject.resources?.pools?.forEach { pool -> + resourcePoolMapExt?.put(pool.format(), pool) + } + } + // 替换后的远程模板去除不必要参数 + resYamlObject.resources = null + return TemplateYamlMapper.toYaml(resYamlObject) + } + + // 在parameters替换前做统一处理,例如替换模板 + private fun parseTemplateParameters( + fromPath: TemplatePath, + path: TemplatePath, + template: String, + parameters: Map?, + deepTree: TemplateDeepTreeNode + ): String { + // 后面的需要覆盖前面的,所以使用map + val templateMap = mutableMapOf() + + val preTemplateParam = + YamlObjects.getObjectFromYaml(path, template).parameters?.toMutableList() + + preTemplateParam?.forEach { preParam -> + if (Constants.TEMPLATE_KEY in preParam) { + val toPath = TemplatePath( + preParam[Constants.TEMPLATE_KEY].toString(), preParam[Constants.REF]?.toString() + ) + // 因为这里是替换模板的模板参数,所以frompath需要使用模板文件而不是来源文件 + val templateObject = replaceResAndParam( + templateType = TemplateType.PARAMETERS, + toPath = toPath, + parameters = null, + fromPath = path, + deepTree = deepTree + ) + val parametersTemplate = YamlObjects.getObjectFromYaml( + path = toPath, + template = TemplateYamlMapper.toYaml(templateObject) + ) + parametersTemplate.parameters?.let { p -> templateMap.putAll(p.associateBy { it.name }) } + } else { + val p = YamlObjects.getParameter(fromPath, preParam) + templateMap[p.name] = p + } + } + + return if (conf.useOldParametersExpression) { + TemplateYamlUtil.parseTemplateParametersOld( + fromPath = fromPath, + path = path, + template = template, + templateParameters = templateMap.values.toMutableList(), + parameters = parameters + ) + } else { + ParametersExpressionParse.parseTemplateParameters( + fromPath = fromPath, + path = path, + template = template, + templateParameters = templateMap.values.toMutableList(), + parameters = parameters + ) + } + } + + private fun error(content: String) { + throw YamlFormatException(content) + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/YamlTemplateConf.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/YamlTemplateConf.kt new file mode 100644 index 00000000000..7749b6f328e --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/YamlTemplateConf.kt @@ -0,0 +1,9 @@ +package com.tencent.devops.process.yaml.v3.parsers.template + +/** + * 模板替换的配置选项 + * @param useOldParametersExpression 是否使用旧版的表达式逻辑替换parameters + */ +data class YamlTemplateConf( + val useOldParametersExpression: Boolean = false +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/ExpressionBlock.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/ExpressionBlock.kt new file mode 100644 index 00000000000..85fa6ff5e0b --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/ExpressionBlock.kt @@ -0,0 +1,11 @@ +package com.tencent.devops.process.yaml.v3.parsers.template.models + +/** + * 表达式括号项 ${{ }} + * @param startIndex 括号开始位置即 $ 位置 + * @param endIndex 括号结束位置即最后一个 } 位置 + */ +data class ExpressionBlock( + var startIndex: Int, + var endIndex: Int +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/GetTemplateParam.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/GetTemplateParam.kt new file mode 100644 index 00000000000..a31cdd8e932 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/GetTemplateParam.kt @@ -0,0 +1,50 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.parsers.template.models + +import com.tencent.devops.process.yaml.pojo.TemplatePath +import com.tencent.devops.process.yaml.v3.enums.TemplateType +import com.tencent.devops.process.yaml.v3.models.Repositories + +/** + * 获取模板的参数接口, + * @param path yaml中的模板路径 + * @param templateType 模板类型 + * @param nowRepoId 当前正在替换的仓库id + * @param targetRepo 需要获取的yaml 中定义的远程模板库 + * @param extraParameters 额外参数,由各个服务具体定义 + */ +data class GetTemplateParam( + val path: TemplatePath, + val templateType: TemplateType?, + val nowRepoId: String?, + val targetRepo: Repositories?, + val extraParameters: T +) { + fun format() = "GetTemplateParam|$path|$templateType|$nowRepoId|$targetRepo|" +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/Graph.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/Graph.kt new file mode 100644 index 00000000000..ed76f817ade --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/Graph.kt @@ -0,0 +1,88 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.parsers.template.models + +class Graph( + private val adj: MutableMap> = mutableMapOf() +) { + + fun addEdge(fromPath: String, toPath: String) { + if (adj[fromPath] != null) { + adj[fromPath]!!.add(toPath) + } else { + adj[fromPath] = mutableListOf(toPath) + } + } + + fun hasCyclic(): Boolean { + val visited = adj.map { it.key to false }.toMap().toMutableMap() + val recStack = adj.map { it.key to false }.toMap().toMutableMap() + + for (i in adj.keys) { + if (hasCyclicUtil(i, visited, recStack)) { + return true + } + } + return false + } + + private fun hasCyclicUtil( + i: String, + visited: MutableMap, + recStack: MutableMap + ): Boolean { + + if (recStack[i] == null || visited[i] == null) { + return false + } + + if (recStack[i]!!) { + return true + } + + if (visited[i]!!) { + return false + } + + visited[i] = true + + recStack[i] = true + + val children = adj[i]!! + + for (c in children) { + if (hasCyclicUtil(c, visited, recStack)) { + return true + } + } + + recStack[i] = false + + return false + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/NoReplaceStagTemplate.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/NoReplaceStagTemplate.kt new file mode 100644 index 00000000000..d924f1e356c --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/NoReplaceStagTemplate.kt @@ -0,0 +1,48 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.parsers.template.models + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.fasterxml.jackson.annotation.JsonProperty +import io.swagger.annotations.ApiModelProperty + +// 不用被模板替换的Stage中的变量,直接通过Yaml生成Object +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class NoReplaceStagTemplate( + val name: String?, + val id: String?, + val label: String? = null, + @JsonProperty("if") + @ApiModelProperty(name = "if") + val ifField: String? = null, + @JsonProperty("fast-kill") + @ApiModelProperty(name = "fast-kill") + val fastKill: Boolean? = false +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/NoReplaceTemplate.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/NoReplaceTemplate.kt new file mode 100644 index 00000000000..c4527180fc7 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/NoReplaceTemplate.kt @@ -0,0 +1,46 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.parsers.template.models + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonInclude +import com.tencent.devops.process.yaml.v3.models.Extends +import com.tencent.devops.process.yaml.v3.models.Resources +import com.tencent.devops.process.yaml.v3.models.on.PreTriggerOn + +// 不用被模板替换的流水线变量,直接通过Yaml生成Object +@JsonInclude(JsonInclude.Include.NON_NULL) +@JsonIgnoreProperties(ignoreUnknown = true) +data class NoReplaceTemplate( + var version: String?, + var name: String?, + var label: List? = null, + var triggerOn: PreTriggerOn?, + var extends: Extends?, + var resources: Resources? +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/TemplateDeepTreeNode.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/TemplateDeepTreeNode.kt new file mode 100644 index 00000000000..6669126ebbf --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/TemplateDeepTreeNode.kt @@ -0,0 +1,102 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.parsers.template.models + +import com.tencent.devops.process.yaml.pojo.TemplatePath +import com.tencent.devops.process.yaml.v3.exception.YamlFormatException + +class TemplateDeepTreeNode( + val path: TemplatePath, + val parent: TemplateDeepTreeNode?, + val children: MutableList +) { + companion object { + // 模板最多引用数和最大深度 + const val MAX_TEMPLATE_NUMB = 10 + const val MAX_TEMPLATE_DEEP = 5 + + const val TEMPLATE_NUMB_BEYOND = + "[%s]The number of referenced template files exceeds the threshold [$MAX_TEMPLATE_NUMB] " + const val TEMPLATE_DEEP_BEYOND = + "[%s]The template nesting depth exceeds the threshold [$MAX_TEMPLATE_DEEP}]" + } + + fun add(nodePath: TemplatePath): TemplateDeepTreeNode { + val node = TemplateDeepTreeNode( + path = nodePath, + parent = this, + children = mutableListOf() + ) + children.add( + node + ) + if (node.getDeep() > MAX_TEMPLATE_DEEP) { + throw YamlFormatException(TEMPLATE_DEEP_BEYOND.format(getRoot().toStr("", true))) + } + if (node.getWidth() > MAX_TEMPLATE_NUMB) { + throw YamlFormatException(TEMPLATE_NUMB_BEYOND.format(getRoot().toStr("", true))) + } + return node + } + + fun toStr(prefix: String?, isTail: Boolean): String { + val str = StringBuilder() + str.append(prefix + (if (isTail) "└── " else "├── ") + path + "\n") + for (i in 0 until children.size - 1) { + str.append(children[i].toStr(prefix + if (isTail) " " else "│ " + "\n", false)) + } + if (children.size > 0) { + str.append( + children[children.size - 1].toStr(prefix + if (isTail) " " else "│ " + "\n", true) + ) + } + return str.toString() + } + + private fun getDeep(): Int { + var length = 1 + var itor = this + while (itor.parent != null) { + itor = itor.parent!! + length++ + } + return length + } + + private fun getWidth(): Int { + return children.size + } + + private fun getRoot(): TemplateDeepTreeNode { + var itor = this + while (itor.parent != null) { + itor = itor.parent!! + } + return itor + } +} diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/TemplateProjectData.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/TemplateProjectData.kt new file mode 100644 index 00000000000..918372880e0 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/parsers/template/models/TemplateProjectData.kt @@ -0,0 +1,44 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.parsers.template.models + +import com.tencent.devops.common.webhook.pojo.code.git.GitEvent + +data class TemplateProjectData( + val gitRequestEventId: Long, + // 发起者的库ID,用户名,分支 + val triggerProjectId: Long, + // sourceProjectId,在fork时是源库的ID + val sourceProjectId: Long, + val triggerUserId: String, + val triggerRef: String, + val triggerToken: String, + val forkGitToken: String?, + val changeSet: Set?, + val event: GitEvent? +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/Gate.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/Gate.kt new file mode 100644 index 00000000000..c076fb46733 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/Gate.kt @@ -0,0 +1,43 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.stageCheck + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.process.yaml.v3.models.GateNotices +import com.tencent.devops.process.yaml.v3.models.gate.ContinueOnFail + +@JsonIgnoreProperties(ignoreUnknown = true) +data class Gate( + val name: String, + val rule: List, + @JsonProperty("notify-on-fail") + val notifyOnFail: List, + @JsonProperty("continue-on-fail") + val continueOnFail: ContinueOnFail? +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/GateTemplate.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/GateTemplate.kt new file mode 100644 index 00000000000..a8f202c8d38 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/GateTemplate.kt @@ -0,0 +1,35 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.stageCheck + +import com.tencent.devops.process.yaml.v3.parameter.Parameters + +data class GateTemplate( + val gates: List, + val parameters: List? +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/PreStageCheck.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/PreStageCheck.kt new file mode 100644 index 00000000000..53874eaee8b --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/PreStageCheck.kt @@ -0,0 +1,39 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.stageCheck + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonProperty + +@JsonIgnoreProperties(ignoreUnknown = true) +data class PreStageCheck( + val reviews: PreStageReviews?, + val gates: List?, + @JsonProperty("timeout-hours") + val timeoutHours: Int? +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/PreStageReviews.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/PreStageReviews.kt new file mode 100644 index 00000000000..ef7d482c318 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/PreStageReviews.kt @@ -0,0 +1,43 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.stageCheck + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties + +@JsonIgnoreProperties(ignoreUnknown = true) +data class PreStageReviews( + val flows: List?, + val variables: Map?, + val description: String? +) + +@JsonIgnoreProperties(ignoreUnknown = true) +data class PreFlow( + val name: String, + val reviewers: Any +) diff --git a/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/PreTemplateStageCheck.kt b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/PreTemplateStageCheck.kt new file mode 100644 index 00000000000..92e4a9821a6 --- /dev/null +++ b/src/backend/ci/core/common/common-pipeline-yaml/src/main/kotlin/com/tencent/devops/process/yaml/v3/stageCheck/PreTemplateStageCheck.kt @@ -0,0 +1,40 @@ +/* + * Tencent is pleased to support the open source community by making BK-CI 蓝鲸持续集成平台 available. + * + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * BK-CI 蓝鲸持续集成平台 is licensed under the MIT license. + * + * A copy of the MIT License is included in this file. + * + * + * Terms of the MIT License: + * --------------------------------------------------- + * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated + * documentation files (the "Software"), to deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all copies or substantial portions of + * the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT + * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN + * NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package com.tencent.devops.process.yaml.v3.stageCheck + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonProperty +import com.tencent.devops.process.yaml.v3.models.Template + +@JsonIgnoreProperties(ignoreUnknown = true) +data class PreTemplateStageCheck( + val reviews: PreStageReviews?, + val gates: List