Skip to content

Commit

Permalink
Merge pull request #9864 from mingshewhe/feat_6074
Browse files Browse the repository at this point in the history
feat: 重构前端保存传入的无用数据 #6074
  • Loading branch information
bkci-bot authored Dec 26, 2023
2 parents b05c7d6 + a9fdb22 commit e4a01f9
Show file tree
Hide file tree
Showing 12 changed files with 210 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ 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.enums.RepositoryType
import com.tencent.devops.common.api.pojo.Result
import com.tencent.devops.common.pipeline.pojo.BuildFormValue
import com.tencent.devops.process.pojo.BuildFormRepositoryValue
Expand Down Expand Up @@ -115,4 +116,49 @@ interface UserBuildParametersResource {
@QueryParam("pageSize")
pageSize: Int?
): Result<List<BuildFormRepositoryValue>>

@ApiOperation("构建表单查询流水线列表")
@GET
@Path("/{projectId}/subPipeline")
fun listPermissionPipeline(
@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 = true, defaultValue = "")
@QueryParam("permission")
permission: com.tencent.devops.process.pojo.Permission,
@ApiParam("排除流水线ID", required = false, defaultValue = "")
@QueryParam("excludePipelineId")
excludePipelineId: String?,
@ApiParam("流水线名称", required = false)
@QueryParam("pipelineName")
pipelineName: String? = null,
@ApiParam("第几页", required = false, defaultValue = "1")
@QueryParam("page")
page: Int?,
@ApiParam("每页多少条", required = false, defaultValue = "20")
@QueryParam("pageSize")
pageSize: Int?
): Result<List<BuildFormValue>>

@ApiOperation("构建表单查询git分支")
@GET
@Path("/{projectId}/{repositoryId}/gitRefs")
fun listGitRefs(
@ApiParam("项目ID", required = true)
@PathParam("projectId")
projectId: String,
@ApiParam("repo hash id", required = true)
@PathParam("repositoryId")
repositoryId: String,
@ApiParam("代码库请求类型", required = false)
@QueryParam("repositoryType")
repositoryType: RepositoryType?,
@ApiParam("搜索条件", required = false)
@QueryParam("search")
search: String?
): Result<List<BuildFormValue>>
}
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,10 @@ interface UserScmResource {
@ApiOperation("列出仓库分支和tag集合")
@GET
@Path("/{projectId}/{repositoryId}/refs")
@Deprecated(
replaceWith = ReplaceWith("UserBuildParametersResource.listGitRefs"),
message = "流水线下拉参数,统一到UserBuildParametersResource维护"
)
fun listRefs(
@ApiParam("项目ID", required = true)
@PathParam("projectId")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ const val PIPELINE_BUILD_LAST_UPDATE = "BK_CI_BUILD_LAST_UPDATE" // "pipeline.bu
const val PIPELINE_BUILD_SVN_REVISION = "BK_CI_BUILD_SVN_REVISION" // "pipeline.build.svn.revision"
const val PIPELINE_BUILD_NUM_ALIAS = "BK_CI_BUILD_NUM_ALIAS"
const val PIPELINE_BUILD_URL = "BK_CI_BUILD_URL"
// 禁用定时触发器参数,当流水线配置这个参数,并且值为true,则禁用定时触发器
const val PIPELINE_TIMER_DISABLE = "BK_CI_TIMER_DISABLE"

const val GIT_MR_NUMBER = "BK_CI_GIT_MR_NUMBER" // git_mr_number
const val GITHUB_PR_NUMBER = "BK_CI_GITHUB_PR_NUMBER" // github_pr_number
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,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.engine.utils.PipelineUtils
import com.tencent.devops.process.plugin.load.ElementBizRegistrar
import com.tencent.devops.process.pojo.PipelineCollation
import com.tencent.devops.process.pojo.PipelineName
Expand Down Expand Up @@ -306,6 +307,9 @@ class PipelineRepositoryService constructor(
}
distIds.add(c.containerHashId!!)

// 清理无用的options
c.params = PipelineUtils.cleanOptions(c.params)

var taskSeq = 0
c.elements.forEach { e ->
if (e.id.isNullOrBlank() || distIds.contains(e.id)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ import com.tencent.devops.process.engine.service.record.PipelineBuildRecordServi
import com.tencent.devops.process.engine.service.record.TaskBuildRecordService
import com.tencent.devops.process.engine.service.rule.PipelineRuleService
import com.tencent.devops.process.engine.utils.ContainerUtils
import com.tencent.devops.process.engine.utils.PipelineUtils
import com.tencent.devops.process.pojo.BuildBasicInfo
import com.tencent.devops.process.pojo.BuildHistory
import com.tencent.devops.process.pojo.BuildId
Expand Down Expand Up @@ -735,6 +736,8 @@ class PipelineRuntimeService @Autowired constructor(
buildStatus = null,
taskBuildRecords = taskBuildRecords
)
// 清理options变量
container.params = PipelineUtils.cleanOptions(container.params)
return@nextContainer
} else if (container is NormalContainer) {
if (!ContainerUtils.isNormalContainerEnable(container)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import com.tencent.devops.common.api.exception.OperationException
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.common.pipeline.enums.BuildFormPropertyType
import com.tencent.devops.common.pipeline.pojo.BuildFormProperty
import com.tencent.devops.common.pipeline.pojo.BuildNo
import com.tencent.devops.common.pipeline.pojo.element.atom.ManualReviewParam
Expand Down Expand Up @@ -165,7 +166,7 @@ object PipelineUtils {
val triggerContainer = TriggerContainer(
name = templateTrigger.name,
elements = templateTrigger.elements,
params = instanceParam,
params = cleanOptions(instanceParam),
buildNo = buildNo,
containerId = templateTrigger.containerId,
containerHashId = templateTrigger.containerHashId
Expand All @@ -179,4 +180,29 @@ object PipelineUtils {
instanceFromTemplate = instanceFromTemplate
)
}

/**
* 清空options
*
* 当参数类型为GIT/SNV分支、代码库、子流水线时,流水线保存、模板保存和模板实例化时,需要清空options参数,减少model大小.
* options需在运行时实时计算
*/
fun cleanOptions(params: List<BuildFormProperty>): List<BuildFormProperty> {
val filterParams = mutableListOf<BuildFormProperty>()
params.forEach {
when (it.type) {
BuildFormPropertyType.SVN_TAG,
BuildFormPropertyType.GIT_REF,
BuildFormPropertyType.CODE_LIB,
BuildFormPropertyType.SUB_PIPELINE,
BuildFormPropertyType.CONTAINER_TYPE -> {
filterParams.add(it.copy(options = emptyList(), replaceKey = null, searchUrl = null))
}

else ->
filterParams.add(it)
}
}
return filterParams
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -610,21 +610,12 @@ class ServicePipelineResourceImpl @Autowired constructor(
pageSize: Int?
): Result<Page<Pipeline>> {
checkParam(userId, projectId)
val bkAuthPermission = when (permission) {
Permission.DEPLOY -> AuthPermission.DEPLOY
Permission.DOWNLOAD -> AuthPermission.DOWNLOAD
Permission.EDIT -> AuthPermission.EDIT
Permission.EXECUTE -> AuthPermission.EXECUTE
Permission.DELETE -> AuthPermission.DELETE
Permission.VIEW -> AuthPermission.VIEW
Permission.CREATE -> AuthPermission.CREATE
Permission.LIST -> AuthPermission.LIST
}
val result = pipelineListFacadeService.hasPermissionList(
userId = userId,
projectId = projectId,
authPermission = bkAuthPermission,
permission = permission,
excludePipelineId = excludePipelineId,
filterByPipelineName = null,
page = page,
pageSize = pageSize
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,19 @@

package com.tencent.devops.process.api

import com.tencent.devops.common.api.enums.RepositoryType
import com.tencent.devops.common.api.pojo.Result
import com.tencent.devops.common.api.util.MessageUtil
import com.tencent.devops.common.client.Client
import com.tencent.devops.common.pipeline.enums.StartType
import com.tencent.devops.common.pipeline.pojo.BuildFormValue
import com.tencent.devops.common.pipeline.utils.RepositoryConfigUtils
import com.tencent.devops.common.web.RestResource
import com.tencent.devops.common.web.utils.I18nUtil
import com.tencent.devops.process.api.user.UserBuildParametersResource
import com.tencent.devops.process.pojo.BuildFormRepositoryValue
import com.tencent.devops.process.service.PipelineListFacadeService
import com.tencent.devops.process.service.scm.ScmProxyService
import com.tencent.devops.process.utils.PIPELINE_BUILD_ID
import com.tencent.devops.process.utils.PIPELINE_BUILD_NUM
import com.tencent.devops.process.utils.PIPELINE_ELEMENT_ID
Expand All @@ -54,7 +58,9 @@ import org.springframework.beans.factory.annotation.Autowired
@Suppress("UNUSED")
@RestResource
class UserBuildParametersResourceImpl @Autowired constructor(
private val client: Client
private val client: Client,
private val pipelineListFacadeService: PipelineListFacadeService,
private val scmProxyService: ScmProxyService
) : UserBuildParametersResource {

companion object {
Expand Down Expand Up @@ -172,4 +178,52 @@ class UserBuildParametersResourceImpl @Autowired constructor(
).map { BuildFormRepositoryValue(id = it.repositoryHashId!!, name = it.aliasName) }
)
}

override fun listPermissionPipeline(
userId: String,
projectId: String,
permission: com.tencent.devops.process.pojo.Permission,
excludePipelineId: String?,
pipelineName: String?,
page: Int?,
pageSize: Int?
): Result<List<BuildFormValue>> {
val pipelineList = pipelineListFacadeService.hasPermissionList(
userId = userId,
projectId = projectId,
permission = permission,
excludePipelineId = excludePipelineId,
filterByPipelineName = pipelineName,
page = page,
pageSize = pageSize
).records
return Result(
pipelineList.map { BuildFormValue(it.pipelineName, it.pipelineName) }
)
}

override fun listGitRefs(
projectId: String,
repositoryId: String,
repositoryType: RepositoryType?,
search: String?
): Result<List<BuildFormValue>> {
val result = mutableListOf<String>()
val repositoryConfig = RepositoryConfigUtils.buildConfig(repositoryId, repositoryType)
val branches = scmProxyService.listBranches(
projectId = projectId,
repositoryConfig = repositoryConfig,
search = search
).data ?: listOf()
val tags = scmProxyService.listTags(
projectId = projectId,
repositoryConfig = repositoryConfig,
search = search
).data ?: listOf()
result.addAll(branches)
result.addAll(tags)
return Result(
result.map { BuildFormValue(it, it) }
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import com.tencent.devops.process.plugin.ElementBizPlugin
import com.tencent.devops.process.plugin.annotation.ElementBiz
import com.tencent.devops.process.plugin.trigger.service.PipelineTimerService
import com.tencent.devops.process.plugin.trigger.util.CronExpressionUtils
import com.tencent.devops.process.utils.PIPELINE_TIMER_DISABLE
import org.quartz.CronExpression
import org.slf4j.LoggerFactory

Expand Down Expand Up @@ -65,7 +66,12 @@ class TimerTriggerElementBizPlugin constructor(
val crontabExpressions = mutableSetOf<String>()
val params = (container as TriggerContainer).params.associate { it.id to it.defaultValue.toString() }
logger.info("[$pipelineId]|$userId| Timer trigger [${element.name}] enable=${element.isElementEnable()}")
if (element.isElementEnable()) {
/*
在模板实例化时,有的流水线需要开启定时任务,有的流水线不需要开启,支持通过流水线变量控制定时任务的开启
通过参数禁用定时任务,在流水线参数上配置BK_CI_TIMER_DISABLE,禁用定时触发器插件
*/
val isParamDisable = params[PIPELINE_TIMER_DISABLE]?.toBoolean() ?: false
if (element.isElementEnable() && !isParamDisable) {

val eConvertExpressions = element.convertExpressions(params = params)
if (eConvertExpressions.isEmpty()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,21 +130,35 @@ class ParamFacadeService @Autowired constructor(
codeService.getGitRefs(projectId, formProperty.repoHashId, search)
} catch (e: Exception) {
logger.warn("projectId:$projectId,repoHashId:${formProperty.repoHashId} add git refs error", e)
listOf<String>()
listOf()
}
val options = refs.map {
BuildFormValue(it, it)
}
val searchUrl = "/process/api/user/scm/$projectId/${formProperty.repoHashId}/refs?search={words}"
val searchUrl = "/process/api/user/buildParam/$projectId/${formProperty.repoHashId}/gitRefs?search={words}"
val replaceKey = "{words}"
return copyFormProperty(
property = formProperty,
options = options,
options = fixDefaultOptions(options = options, defaultValue = formProperty.defaultValue.toString()),
searchUrl = searchUrl,
replaceKey = replaceKey
)
}

/**
* 修复默认值不展示问题
*
* 当默认值不在options列表时,流水线执行时不会展示默认值
*/
private fun fixDefaultOptions(options: List<BuildFormValue>, defaultValue: String): List<BuildFormValue> {
if (defaultValue.isBlank() || options.map { it.key }.contains(defaultValue)) {
return options
}
val newOptions = options.toMutableList()
newOptions.add(BuildFormValue(defaultValue, defaultValue))
return newOptions
}

/**
* SVN_TAG类型参数添加SVN目录作为复选参数
*/
Expand Down Expand Up @@ -175,7 +189,7 @@ class ParamFacadeService @Autowired constructor(
aliasName: String? = null
): BuildFormProperty {

val aliasNames = if ((!userId.isNullOrBlank())) {
val options = if ((!userId.isNullOrBlank())) {
// 检查代码库的权限, 只返回用户有权限代码库
val hasPermissionCodelibs =
getPermissionCodelibList(userId, projectId, codelibFormProperty.scmType!!, aliasName)
Expand All @@ -192,7 +206,7 @@ class ParamFacadeService @Autowired constructor(
val replaceKey = "{words}"
return copyFormProperty(
property = codelibFormProperty,
options = aliasNames,
options = fixDefaultOptions(options = options, defaultValue = codelibFormProperty.defaultValue.toString()),
searchUrl = searchUrl,
replaceKey = replaceKey
)
Expand Down Expand Up @@ -274,10 +288,23 @@ class ParamFacadeService @Autowired constructor(
): BuildFormProperty {
try {
val hasPermissionPipelines = getHasPermissionPipelineList(userId, projectId)
val aliasName = hasPermissionPipelines
val options = hasPermissionPipelines
.filter { pipelineId == null || !it.pipelineId.contains(pipelineId) }
.map { BuildFormValue(it.pipelineName, it.pipelineName) }
return copyFormProperty(subPipelineFormProperty, aliasName)
val excludePipelineId = pipelineId ?: ""
val searchUrl = "/process/api/user/buildParam/$projectId/subPipeline?" +
"permission=${AuthPermission.EXECUTE.name}&excludePipelineId=$excludePipelineId" +
"&pipelineName={words}&page=1&pageSize=100"
val replaceKey = "{words}"
return copyFormProperty(
property = subPipelineFormProperty,
options = fixDefaultOptions(
options = options,
defaultValue = subPipelineFormProperty.defaultValue.toString()
),
searchUrl = searchUrl,
replaceKey = replaceKey
)
} catch (t: Throwable) {
logger.warn("[$userId|$projectId] Fail to filter the properties of subpipelines", t)
throw OperationException(
Expand Down Expand Up @@ -356,7 +383,13 @@ class ParamFacadeService @Autowired constructor(
// 获取项目下所有流水线,并过滤出有权限部分,有权限列表为空时返回项目所有流水线
watcher.start("s_r_summary")
val buildPipelineRecords =
pipelineRuntimeService.getBuildPipelineRecords(projectId, ChannelCode.BS, hasPermissionList)
pipelineRuntimeService.getBuildPipelineRecords(
projectId = projectId,
channelCode = ChannelCode.BS,
pipelineIds = hasPermissionList,
page = 1,
pageSize = 100
)
watcher.stop()

return buildPipelineRecords.map {
Expand Down
Loading

0 comments on commit e4a01f9

Please sign in to comment.