Skip to content

Commit

Permalink
feat:流水线变量语法支持两种风格 TencentBlueKing#10576
Browse files Browse the repository at this point in the history
  • Loading branch information
mingshewhe committed Aug 26, 2024
1 parent 75a9194 commit 1617e09
Show file tree
Hide file tree
Showing 12 changed files with 94 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ data class PipelineAsCodeSettings(
*/
fun resetDialect() {
projectDialect = null
if (inheritedDialect != true) {
if (inheritedDialect != false) {
pipelineDialect = null
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ package com.tencent.devops.common.pipeline
import com.tencent.devops.common.pipeline.pojo.PipelineModelAndSetting
import com.tencent.devops.common.pipeline.pojo.transfer.PreviewResponse
import io.swagger.v3.oas.annotations.media.Schema
import java.time.LocalDateTime

data class PipelineVersionWithModel(
@get:Schema(title = "版本号(流水线唯一递增)", required = true)
Expand All @@ -51,5 +52,9 @@ data class PipelineVersionWithModel(
@get:Schema(title = "是否支持YAML解析", required = true)
val yamlSupported: Boolean,
@get:Schema(title = "YAML解析异常信息")
val yamlInvalidMsg: String?
val yamlInvalidMsg: String?,
@get:Schema(title = "更新操作人", required = true)
val updater: String?,
@get:Schema(title = "版本修改时间", required = true)
val updateTime: LocalDateTime?
)
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ClassicPipelineDialect : IPipelineDialect {

override fun supportOverwriteReadOnlyVar() = true

override fun supportLongVar() = true
override fun supportLongVarValue() = true

override fun supportChineseVarName() = true

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class ConstrainedPipelineDialect : IPipelineDialect {

override fun supportOverwriteReadOnlyVar() = false

override fun supportLongVar() = false
override fun supportLongVarValue() = false

override fun supportChineseVarName() = false

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ interface IPipelineDialect {
/**
* 是否支持长变量
*/
fun supportLongVar(): Boolean
fun supportLongVarValue(): Boolean

/**
* 是否支持中文变量名
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,7 @@ object ProcessMessageCode {

const val ERROR_PIPELINE_CONDITION_EXPRESSION_TOO_LONG = "2101253" // 自定义条件表达式{0}的长度超过{1}位
const val ERROR_PIPELINE_BUILD_START_PARAM_NO_EMPTY = "2101254" // 构建启动参数如果必填,不能为空
const val ERROR_PIPELINE_VARIABLES_OUT_OF_LENGTH = "2101255" // 流水线启动参数{0}超出4000长度限制

const val BK_SUCCESSFULLY_DISTRIBUTED = "bkSuccessfullyDistributed" // 跨项目构件分发成功,共分发了{0}个文件
const val BK_SUCCESSFULLY_FAILED = "bkSuccessfullyFailed" // 跨项目构件分发失败,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
package com.tencent.devops.process.service

import com.tencent.devops.common.api.pojo.PipelineAsCodeSettings
import com.tencent.devops.common.pipeline.dialect.IPipelineDialect
import com.tencent.devops.common.pipeline.dialect.PipelineDialectEnums
import com.tencent.devops.process.dao.PipelineSettingDao
import org.jooq.DSLContext
import org.springframework.beans.factory.annotation.Autowired
Expand All @@ -47,18 +49,34 @@ class PipelineAsCodeService @Autowired constructor(
return getPipelineAsCodeSettings(projectId, pipelineId)?.enable
}

fun getPipelineAsCodeSettings(
projectId: String,
pipelineId: String
): PipelineAsCodeSettings? {
fun getPipelineAsCodeSettings(projectId: String, pipelineId: String): PipelineAsCodeSettings? {
val settings = pipelineSettingDao.getPipelineAsCodeSettings(
dslContext = dslContext, projectId = projectId, pipelineId = pipelineId
)
return if (settings?.inheritedDialect == true) {
return getPipelineAsCodeSettings(projectId = projectId, asCodeSettings = settings)
}

fun getPipelineAsCodeSettings(
projectId: String,
asCodeSettings: PipelineAsCodeSettings?
): PipelineAsCodeSettings? {
return if (asCodeSettings?.inheritedDialect != false) {
val projectDialect = projectCacheService.getProjectDialect(projectId)
settings.copy(projectDialect = projectDialect)
asCodeSettings?.copy(projectDialect = projectDialect)
} else {
settings
asCodeSettings
}
}

fun getPipelineDialect(
projectId: String,
asCodeSettings: PipelineAsCodeSettings?
): IPipelineDialect {
return PipelineDialectEnums.getDialect(
getPipelineAsCodeSettings(
projectId = projectId,
asCodeSettings = asCodeSettings
)
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import com.tencent.devops.process.engine.service.PipelineRepositoryService
import com.tencent.devops.process.engine.service.PipelineRuntimeService
import com.tencent.devops.process.pojo.BuildId
import com.tencent.devops.process.pojo.app.StartBuildContext
import com.tencent.devops.process.service.PipelineAsCodeService
import com.tencent.devops.process.service.ProjectCacheService
import com.tencent.devops.process.util.BuildMsgUtils
import com.tencent.devops.process.utils.BK_CI_MATERIAL_ID
Expand All @@ -80,6 +81,7 @@ import com.tencent.devops.process.utils.PIPELINE_START_USER_ID
import com.tencent.devops.process.utils.PIPELINE_START_USER_NAME
import com.tencent.devops.process.utils.PIPELINE_START_WEBHOOK_USER_ID
import com.tencent.devops.process.utils.PIPELINE_UPDATE_USER
import com.tencent.devops.process.utils.PIPELINE_VARIABLES_STRING_LENGTH_MAX
import com.tencent.devops.process.utils.PIPELINE_VERSION
import com.tencent.devops.process.utils.PROJECT_NAME
import com.tencent.devops.process.utils.PROJECT_NAME_CHINESE
Expand All @@ -98,7 +100,8 @@ class PipelineBuildService(
private val projectCacheService: ProjectCacheService,
private val pipelineUrlBean: PipelineUrlBean,
private val simpleRateLimiter: SimpleRateLimiter,
private val buildIdGenerator: BuildIdGenerator
private val buildIdGenerator: BuildIdGenerator,
private val pipelineAsCodeService: PipelineAsCodeService
) {
companion object {
private val NO_LIMIT_CHANNEL = listOf(ChannelCode.CODECC)
Expand Down Expand Up @@ -223,6 +226,8 @@ class PipelineBuildService(
versionName = versionName,
yamlVersion = yamlVersion
)
// 校验流水线启动变量长度
checkBuildVariablesLength(context = context)

val interceptResult = pipelineInterceptorChain.filter(
InterceptData(
Expand Down Expand Up @@ -386,4 +391,20 @@ class PipelineBuildService(
}
// return originStartParams
}

private fun checkBuildVariablesLength(context: StartBuildContext) {
val pipelineDialect = pipelineAsCodeService.getPipelineDialect(
projectId = context.projectId,
asCodeSettings = context.pipelineSetting?.pipelineAsCodeSettings
)
val longVarNames = context.pipelineParamMap.filter {
it.value.value.toString().length >= PIPELINE_VARIABLES_STRING_LENGTH_MAX
}.map { it.key }
if (!pipelineDialect.supportLongVarValue()) {
throw ErrorCodeException(
errorCode = ProcessMessageCode.ERROR_PIPELINE_VARIABLES_OUT_OF_LENGTH,
params = arrayOf(longVarNames.toString())
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -642,7 +642,9 @@ class PipelineVersionFacadeService @Autowired constructor(
baseVersion = resource.baseVersion,
baseVersionName = baseResource?.versionName,
yamlSupported = yamlSupported,
yamlInvalidMsg = msg
yamlInvalidMsg = msg,
updater = resource.updater,
updateTime = resource.updateTime
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,18 @@ package com.tencent.devops.worker.common.task
import com.tencent.devops.common.api.exception.TaskExecuteException
import com.tencent.devops.common.api.pojo.ErrorCode
import com.tencent.devops.common.api.pojo.ErrorType
import com.tencent.devops.common.pipeline.dialect.IPipelineDialect
import com.tencent.devops.common.pipeline.dialect.PipelineDialectEnums
import com.tencent.devops.common.pipeline.pojo.BuildParameters
import com.tencent.devops.process.pojo.BuildTask
import com.tencent.devops.process.pojo.BuildVariables
import com.tencent.devops.process.utils.PIPELINE_VARIABLES_STRING_LENGTH_MAX
import com.tencent.devops.worker.common.env.BuildEnv
import com.tencent.devops.worker.common.env.BuildType
import com.tencent.devops.worker.common.logger.LoggerService
import org.slf4j.LoggerFactory
import java.io.File
import java.util.stream.Collectors
import org.slf4j.LoggerFactory

@Suppress("NestedBlockDepth", "TooManyFunctions")
abstract class ITask {
Expand All @@ -57,6 +60,8 @@ abstract class ITask {

/* 存储常量的key */
private lateinit var constVar: List<String>
/* */
private lateinit var dialect: IPipelineDialect

fun run(
buildTask: BuildTask,
Expand All @@ -67,6 +72,7 @@ abstract class ITask {
.filter { it.readOnly == true }
.map { it.key }
.collect(Collectors.toList())
dialect = PipelineDialectEnums.getDialect(buildVariables.pipelineAsCodeSettings)
execute(buildTask, buildVariables, workspace)
}

Expand Down Expand Up @@ -95,23 +101,38 @@ abstract class ITask {
)

protected fun addEnv(env: Map<String, String>) {
if (this::constVar.isInitialized) {
var errFlag = false
env.forEach { (key, _) ->
if (key in constVar) {
LoggerService.addErrorLine("Variable $key is read-only and cannot be modified.")
errFlag = true
}
var errReadOnlyFlag = false
var errLongValueFlag = false
env.forEach { (key, value) ->
if (this::constVar.isInitialized && key in constVar) {
LoggerService.addErrorLine("Variable $key is read-only and cannot be modified.")
errReadOnlyFlag = true
}
if (errFlag) {
if (value.length >= PIPELINE_VARIABLES_STRING_LENGTH_MAX) {
LoggerService.addErrorLine("Variable $key value exceeds 4000 length limit.")
errLongValueFlag = true
}
}
if (errReadOnlyFlag) {
throw TaskExecuteException(
errorMsg = "[Finish task] status: false, errorType: ${ErrorType.USER.num}, " +
"errorCode: ${ErrorCode.USER_INPUT_INVAILD}, message: read-only cannot be modified.",
errorType = ErrorType.USER,
errorCode = ErrorCode.USER_INPUT_INVAILD
)
}
if (this::dialect.isInitialized) {
if (errLongValueFlag && !dialect.supportLongVarValue()) {
throw TaskExecuteException(
errorMsg = "[Finish task] status: false, errorType: ${ErrorType.USER.num}, " +
"errorCode: ${ErrorCode.USER_INPUT_INVAILD}, message: read-only cannot be modified.",
"errorCode: ${ErrorCode.USER_INPUT_INVAILD}," +
" message: variable value exceeds 4000 length limit.",
errorType = ErrorType.USER,
errorCode = ErrorCode.USER_INPUT_INVAILD
)
}
}

environment.putAll(env)
}

Expand Down
1 change: 1 addition & 0 deletions support-files/i18n/process/message_en_US.properties
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@
2101252=scheduled trigger branch [{0}] unknown error
2101253=Condition expression in [{0}] is longer than {1} digits
2101254=Parameter {0} is required and cannot be empty
2101255=pipeline build parameter {0} value exceeds 4000 length limit

ATOM_POST_EXECUTE_TIP=###Tip:this is the post-action hooked by [step{0}]{1}###
# 公共变量
Expand Down
1 change: 1 addition & 0 deletions support-files/i18n/process/message_zh_CN.properties
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@
2101252=定时触发分支[{0}]未知错误
2101253=[{0}]的条件表达式的长度超过{1}位
2101254=构建入参[{0}]必填,不能为空
2101255=流水线变量{0}值超出4000长度限制
ATOM_POST_EXECUTE_TIP=###Tip:this is the post-action hooked by [step{0}]{1}###
ci.build-no=构建号,开启推荐版本号时有效
Expand Down

0 comments on commit 1617e09

Please sign in to comment.