diff --git a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/StagePauseCheck.kt b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/StagePauseCheck.kt index a900e75efdd..d9ba48e1339 100644 --- a/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/StagePauseCheck.kt +++ b/src/backend/ci/core/common/common-pipeline/src/main/kotlin/com/tencent/devops/common/pipeline/pojo/StagePauseCheck.kt @@ -27,6 +27,7 @@ package com.tencent.devops.common.pipeline.pojo +import com.tencent.devops.common.api.util.EnvUtils import com.tencent.devops.common.api.util.UUIDUtil import com.tencent.devops.common.api.util.timestampmilli import com.tencent.devops.common.pipeline.enums.BuildStatus @@ -153,6 +154,21 @@ data class StagePauseCheck( } } + /** + * 进入审核流程前完成所有审核人变量替换 + */ + fun parseReviewVariables(variables: Map) { + reviewGroups?.forEach { group -> + if (group.status == null) { + val reviewers = group.reviewers.joinToString(",") + val realReviewers = EnvUtils.parseEnv(reviewers, variables) + .split(",").toList() + group.reviewers = realReviewers + } + } + reviewDesc = EnvUtils.parseEnv(reviewDesc, variables) + } + companion object { fun convertControlOption(stageControlOption: StageControlOption): StagePauseCheck { return StagePauseCheck( diff --git a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineStageService.kt b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineStageService.kt index fbe44d1285e..42408282ed7 100644 --- a/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineStageService.kt +++ b/src/backend/ci/core/process/biz-base/src/main/kotlin/com/tencent/devops/process/engine/service/PipelineStageService.kt @@ -27,6 +27,7 @@ package com.tencent.devops.process.engine.service +import com.tencent.devops.common.api.util.DateTimeUtil import com.tencent.devops.common.event.dispatcher.pipeline.PipelineEventDispatcher import com.tencent.devops.common.event.enums.ActionType import com.tencent.devops.common.pipeline.enums.BuildStatus @@ -40,14 +41,20 @@ import com.tencent.devops.process.engine.dao.PipelineBuildDao import com.tencent.devops.process.engine.dao.PipelineBuildStageDao import com.tencent.devops.process.engine.dao.PipelineBuildSummaryDao import com.tencent.devops.process.engine.pojo.PipelineBuildStage +import com.tencent.devops.process.engine.pojo.event.PipelineBuildNotifyEvent import com.tencent.devops.process.engine.pojo.event.PipelineBuildStageEvent import com.tencent.devops.process.engine.pojo.event.PipelineBuildWebSocketPushEvent import com.tencent.devops.process.engine.service.detail.StageBuildDetailService +import com.tencent.devops.process.pojo.PipelineNotifyTemplateEnum +import com.tencent.devops.process.service.BuildVariableService +import com.tencent.devops.process.utils.PIPELINE_BUILD_NUM +import com.tencent.devops.process.utils.PIPELINE_NAME import org.jooq.DSLContext import org.jooq.impl.DSL import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service +import java.util.* /** * 流水线Stage相关的服务 @@ -60,6 +67,7 @@ class PipelineStageService @Autowired constructor( private val pipelineBuildDao: PipelineBuildDao, private val pipelineBuildSummaryDao: PipelineBuildSummaryDao, private val pipelineBuildStageDao: PipelineBuildStageDao, + private val buildVariableService: BuildVariableService, private val stageBuildDetailService: StageBuildDetailService ) { companion object { @@ -226,7 +234,15 @@ class PipelineStageService @Autowired constructor( controlOption = controlOption, checkIn = checkIn, checkOut = checkOut ) + // 如果还有待审核的审核组,则直接通知并返回 if (checkIn?.groupToReview() != null) { + val variables = buildVariableService.getAllVariable(buildId) + pauseStageNotify( + userId = userId, + stage = buildStage, + pipelineName = variables[PIPELINE_NAME] ?: pipelineId, + buildNum = variables[PIPELINE_BUILD_NUM] ?: "1" + ) return true } val allStageStatus = stageBuildDetailService.stageStart( @@ -333,4 +349,35 @@ class PipelineStageService @Autowired constructor( } return pendingStage } + + fun pauseStageNotify( + userId: String, + stage: PipelineBuildStage, + pipelineName: String, + buildNum: String + ) { + val checkIn = stage.checkIn ?: return + val group = stage.checkIn?.groupToReview() ?: return + + pipelineEventDispatcher.dispatch( + PipelineBuildNotifyEvent( + notifyTemplateEnum = PipelineNotifyTemplateEnum.PIPELINE_MANUAL_REVIEW_STAGE_NOTIFY_TEMPLATE.name, + source = "s(${stage.stageId}) waiting for REVIEW", + projectId = stage.projectId, pipelineId = stage.pipelineId, + userId = userId, buildId = stage.buildId, + receivers = group.reviewers, + titleParams = mutableMapOf( + "projectName" to "need to add in notifyListener", + "pipelineName" to pipelineName, + "buildNum" to buildNum + ), + bodyParams = mutableMapOf( + "projectName" to "need to add in notifyListener", + "pipelineName" to pipelineName, + "dataTime" to DateTimeUtil.formatDate(Date(), "yyyy-MM-dd HH:mm:ss"), + "reviewDesc" to (checkIn.reviewDesc ?: "") + ) + ) + ) + } } diff --git a/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/command/stage/impl/CheckPauseReviewStageCmd.kt b/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/command/stage/impl/CheckPauseReviewStageCmd.kt index 05dafc7a57b..d57ab0f9859 100644 --- a/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/command/stage/impl/CheckPauseReviewStageCmd.kt +++ b/src/backend/ci/core/process/biz-engine/src/main/kotlin/com/tencent/devops/process/engine/control/command/stage/impl/CheckPauseReviewStageCmd.kt @@ -27,19 +27,15 @@ package com.tencent.devops.process.engine.control.command.stage.impl -import com.tencent.devops.common.api.util.DateTimeUtil -import com.tencent.devops.common.api.util.EnvUtils import com.tencent.devops.common.client.Client -import com.tencent.devops.common.event.dispatcher.pipeline.PipelineEventDispatcher import com.tencent.devops.common.pipeline.enums.BuildStatus import com.tencent.devops.process.engine.common.BS_MANUAL_START_STAGE import com.tencent.devops.process.engine.control.command.CmdFlowState import com.tencent.devops.process.engine.control.command.stage.StageCmd import com.tencent.devops.process.engine.control.command.stage.StageContext import com.tencent.devops.process.engine.pojo.PipelineBuildStage -import com.tencent.devops.process.engine.pojo.event.PipelineBuildNotifyEvent import com.tencent.devops.process.engine.pojo.event.PipelineBuildStageEvent -import com.tencent.devops.process.pojo.PipelineNotifyTemplateEnum +import com.tencent.devops.process.engine.service.PipelineStageService import com.tencent.devops.process.service.BuildVariableService import com.tencent.devops.process.utils.PIPELINE_BUILD_NUM import com.tencent.devops.process.utils.PIPELINE_NAME @@ -48,7 +44,6 @@ import com.tencent.devops.quality.api.v3.ServiceQualityRuleResource import com.tencent.devops.quality.api.v3.pojo.request.BuildCheckParamsV3 import org.slf4j.LoggerFactory import org.springframework.stereotype.Service -import java.util.Date /** * Stage暂停及审核事件的命令处理 @@ -56,7 +51,7 @@ import java.util.Date @Service class CheckPauseReviewStageCmd( private val buildVariableService: BuildVariableService, - private val pipelineEventDispatcher: PipelineEventDispatcher, + private val pipelineStageService: PipelineStageService, private val client: Client ) : StageCmd { @@ -94,7 +89,13 @@ class CheckPauseReviewStageCmd( if (needPause(event, stage)) { // #3742 进入暂停状态则刷新完状态后直接返回,等待手动触发 LOG.info("ENGINE|${event.buildId}|${event.source}|STAGE_PAUSE|${event.stageId}") - pauseStageNotify(commandContext) + stage.checkIn?.parseReviewVariables(commandContext.variables) + pipelineStageService.pauseStageNotify( + userId = event.userId, + stage = stage, + pipelineName = commandContext.variables[PIPELINE_NAME] ?: stage.pipelineId, + buildNum = commandContext.variables[PIPELINE_BUILD_NUM] ?: "1" + ) commandContext.buildStatus = BuildStatus.STAGE_SUCCESS commandContext.latestSummary = "s(${stage.stageId}) waiting for REVIEW" commandContext.cmdFlowState = CmdFlowState.FINALLY @@ -162,50 +163,6 @@ class CheckPauseReviewStageCmd( stage.controlOption?.stageControlOption?.triggered != true } - /** - * 发送通知 - */ - private fun pauseStageNotify(commandContext: StageContext) { - val stage = commandContext.stage - val checkIn = stage.checkIn ?: return - val group = stage.checkIn?.groupToReview() ?: return - val notifyUsers = mutableListOf() - - if (group.status == null) { - val reviewers = group.reviewers.joinToString(",") - val realReviewers = EnvUtils.parseEnv(reviewers, commandContext.variables) - .split(",").toList() - group.reviewers = realReviewers - notifyUsers.addAll(realReviewers) - } - - val pipelineName = commandContext.variables[PIPELINE_NAME] ?: stage.pipelineId - val buildNum = commandContext.variables[PIPELINE_BUILD_NUM] ?: "1" - var reviewDesc = checkIn.reviewDesc - reviewDesc = EnvUtils.parseEnv(reviewDesc, commandContext.variables) - checkIn.reviewDesc = reviewDesc // 替换变量 #3395 - - pipelineEventDispatcher.dispatch( - PipelineBuildNotifyEvent( - notifyTemplateEnum = PipelineNotifyTemplateEnum.PIPELINE_MANUAL_REVIEW_STAGE_NOTIFY_TEMPLATE.name, - source = commandContext.latestSummary, projectId = stage.projectId, pipelineId = stage.pipelineId, - userId = commandContext.event.userId, buildId = stage.buildId, - receivers = notifyUsers, - titleParams = mutableMapOf( - "projectName" to "need to add in notifyListener", - "pipelineName" to pipelineName, - "buildNum" to buildNum - ), - bodyParams = mutableMapOf( - "projectName" to "need to add in notifyListener", - "pipelineName" to pipelineName, - "dataTime" to DateTimeUtil.formatDate(Date(), "yyyy-MM-dd HH:mm:ss"), - "reviewDesc" to reviewDesc - ) - ) - ) - } - companion object { private val LOG = LoggerFactory.getLogger(CheckPauseReviewStageCmd::class.java) }