From 80f4989e6d3cba28378279ae31a72295cff6b6b5 Mon Sep 17 00:00:00 2001 From: mingshewhe Date: Tue, 11 Apr 2023 21:29:10 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20p4=E8=A7=A6=E5=8F=91=E5=99=A8=E4=B8=8D?= =?UTF-8?q?=E4=B8=BB=E5=8A=A8=E6=B3=A8=E5=86=8Ctrigger=E4=BA=8B=E4=BB=B6?= =?UTF-8?q?=20#8556?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tencent/devops/scm/code/p4/P4Server.kt | 2 +- .../webhook/pojo/code/p4/P4ChangeEvent.kt | 3 +++ .../webhook/pojo/code/p4/P4ShelveEvent.kt | 3 +++ .../code/handler/p4/P4ChangeTriggerHandler.kt | 20 ++++++++++++------- .../code/handler/p4/P4ShelveTriggerHandler.kt | 19 ++++++++++++------ .../common/webhook/util/WebhookUtils.kt | 14 +++++++++---- .../engine/service/PipelineWebhookService.kt | 2 +- .../5001_ci_store-init_dml_mysql.sql | 2 +- 8 files changed, 45 insertions(+), 20 deletions(-) diff --git a/src/backend/ci/core/common/common-scm/src/main/kotlin/com/tencent/devops/scm/code/p4/P4Server.kt b/src/backend/ci/core/common/common-scm/src/main/kotlin/com/tencent/devops/scm/code/p4/P4Server.kt index 205956df684..b17cc7c9133 100644 --- a/src/backend/ci/core/common/common-scm/src/main/kotlin/com/tencent/devops/scm/code/p4/P4Server.kt +++ b/src/backend/ci/core/common/common-scm/src/main/kotlin/com/tencent/devops/scm/code/p4/P4Server.kt @@ -72,7 +72,7 @@ class P4Server( } server.connect() server.userName = userName - server.login(password) + server.login(password, true) } }, retryTime = 3) } diff --git a/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/p4/P4ChangeEvent.kt b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/p4/P4ChangeEvent.kt index 138346ae466..62e1d6a780e 100644 --- a/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/p4/P4ChangeEvent.kt +++ b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/p4/P4ChangeEvent.kt @@ -29,6 +29,7 @@ package com.tencent.devops.common.webhook.pojo.code.p4 import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonProperty +import io.swagger.annotations.ApiModelProperty @JsonIgnoreProperties(ignoreUnknown = true) data class P4ChangeEvent( @@ -37,6 +38,8 @@ data class P4ChangeEvent( @JsonProperty("event_type") val eventType: String, val user: String? = null, + @ApiModelProperty("文件变更列表") + val files: List? = null, // 指定项目触发 override val projectId: String? = null ) : P4Event(projectId = projectId) { diff --git a/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/p4/P4ShelveEvent.kt b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/p4/P4ShelveEvent.kt index c053e320b56..4b34b0026fe 100644 --- a/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/p4/P4ShelveEvent.kt +++ b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/p4/P4ShelveEvent.kt @@ -29,6 +29,7 @@ package com.tencent.devops.common.webhook.pojo.code.p4 import com.fasterxml.jackson.annotation.JsonIgnoreProperties import com.fasterxml.jackson.annotation.JsonProperty +import io.swagger.annotations.ApiModelProperty @JsonIgnoreProperties(ignoreUnknown = true) data class P4ShelveEvent( @@ -37,6 +38,8 @@ data class P4ShelveEvent( @JsonProperty("event_type") val eventType: String, val user: String? = null, + @ApiModelProperty("文件变更列表") + val files: List? = null, // 指定项目触发 override val projectId: String? = null ) : P4Event(projectId = projectId) { diff --git a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/p4/P4ChangeTriggerHandler.kt b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/p4/P4ChangeTriggerHandler.kt index 0bb622f7205..438665bca6d 100644 --- a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/p4/P4ChangeTriggerHandler.kt +++ b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/p4/P4ChangeTriggerHandler.kt @@ -108,13 +108,19 @@ class P4ChangeTriggerHandler( if (includePaths.isNullOrBlank() && excludePaths.isNullOrBlank()) { return true } - val changeFiles = eventCacheService.getP4ChangelistFiles( - repo = repository, - projectId = projectId, - repositoryId = repositoryConfig.getURLEncodeRepositoryId(), - repositoryType = repositoryConfig.repositoryType, - change = event.change - ) + // 用户配置的脚本触发,变更文件由触发脚本解析 + val changeFiles = + if (WebhookUtils.isCustomP4TriggerVersion(webHookParams.version)) { + event.files ?: emptyList() + } else { + eventCacheService.getP4ChangelistFiles( + repo = repository, + projectId = projectId, + repositoryId = repositoryConfig.getURLEncodeRepositoryId(), + repositoryType = repositoryConfig.repositoryType, + change = event.change + ) + } return PathFilterFactory.newPathFilter( PathFilterConfig( pathFilterType = PathFilterType.RegexBasedFilter, diff --git a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/p4/P4ShelveTriggerHandler.kt b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/p4/P4ShelveTriggerHandler.kt index 75dbba642c6..46dbb9f5b03 100644 --- a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/p4/P4ShelveTriggerHandler.kt +++ b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/p4/P4ShelveTriggerHandler.kt @@ -106,12 +106,19 @@ class P4ShelveTriggerHandler( ) val pathFilter = object : WebhookFilter { override fun doFilter(response: WebhookFilterResponse): Boolean { - val changeFiles = client.get(ServiceP4Resource::class).getShelvedFiles( - projectId = projectId, - repositoryId = repositoryConfig.getURLEncodeRepositoryId(), - repositoryType = repositoryConfig.repositoryType, - change = event.change - ).data?.map { it.depotPathString } ?: emptyList() + if (includePaths.isNullOrBlank() && excludePaths.isNullOrBlank()) { + return true + } + val changeFiles = if (WebhookUtils.isCustomP4TriggerVersion(webHookParams.version)) { + event.files ?: emptyList() + } else { + client.get(ServiceP4Resource::class).getShelvedFiles( + projectId = projectId, + repositoryId = repositoryConfig.getURLEncodeRepositoryId(), + repositoryType = repositoryConfig.repositoryType, + change = event.change + ).data?.map { it.depotPathString } ?: emptyList() + } return PathFilterFactory.newPathFilter( PathFilterConfig( pathFilterType = PathFilterType.RegexBasedFilter, diff --git a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/util/WebhookUtils.kt b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/util/WebhookUtils.kt index 5d2adac4ed3..06458672a39 100644 --- a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/util/WebhookUtils.kt +++ b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/util/WebhookUtils.kt @@ -92,7 +92,7 @@ object WebhookUtils { private val separatorPattern = Pattern.compile("[,;]") private const val MAX_VARIABLE_COUNT = 32 // p4自定义触发器插件版本号 - const val P4_CUSTOM_TRIGGER_VERSION = 2 + const val CUSTOM_P4_TRIGGER_VERSION = 2 private val logger = LoggerFactory.getLogger(WebhookUtils::class.java) @@ -303,9 +303,11 @@ object WebhookUtils { ): WebhookFilter = object : WebhookFilter { override fun doFilter(response: WebhookFilterResponse): Boolean { - logger.info("$pipelineId|triggerOn:${webHookParams.version}|" + - "projectId:$projectId|eventProjectId:${event.projectId}|version filter") - return if (getMajorVersion(webHookParams.version) >= P4_CUSTOM_TRIGGER_VERSION) { + logger.info( + "$pipelineId|triggerOn:${webHookParams.version}|" + + "projectId:$projectId|eventProjectId:${event.projectId}|version filter" + ) + return if (isCustomP4TriggerVersion(webHookParams.version)) { // 2.0以后,由用户配置的触发器触发 // 2.0以后,触发的项目必须跟匹配的项目相同才能触发 event.isCustomTrigger() && projectId == event.projectId @@ -319,4 +321,8 @@ object WebhookUtils { fun getMajorVersion(version: String?): Int { return version?.split(".")?.get(0)?.toInt() ?: 1 } + + fun isCustomP4TriggerVersion(version: String?): Boolean { + return getMajorVersion(version) >= CUSTOM_P4_TRIGGER_VERSION + } } 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 8604ffe86d7..f89fb5746f0 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 @@ -224,7 +224,7 @@ class PipelineWebhookService @Autowired constructor( scmProxyService.addTGitWebhook(pipelineWebhook.projectId, repositoryConfig, codeEventType) } ScmType.CODE_P4 -> - if (WebhookUtils.getMajorVersion(version) >= WebhookUtils.P4_CUSTOM_TRIGGER_VERSION) { + if (WebhookUtils.isCustomP4TriggerVersion(version)) { val repo = client.get(ServiceRepositoryResource::class).get( pipelineWebhook.projectId, repositoryConfig.getURLEncodeRepositoryId(), diff --git a/support-files/sql/5001_init_dml/5001_ci_store-init_dml_mysql.sql b/support-files/sql/5001_init_dml/5001_ci_store-init_dml_mysql.sql index ab694c8d69d..aa1ad148426 100755 --- a/support-files/sql/5001_init_dml/5001_ci_store-init_dml_mysql.sql +++ b/support-files/sql/5001_init_dml/5001_ci_store-init_dml_mysql.sql @@ -24,7 +24,7 @@ REPLACE INTO `T_ATOM` (`ID`, `NAME`, `ATOM_CODE`, `CLASS_TYPE`, `SERVICE_SCOPE`, REPLACE INTO `T_ATOM` (`ID`, `NAME`, `ATOM_CODE`, `CLASS_TYPE`, `SERVICE_SCOPE`, `JOB_TYPE`, `OS`, `CLASSIFY_ID`, `DOCS_LINK`, `ATOM_TYPE`, `ATOM_STATUS`, `ATOM_STATUS_MSG`, `SUMMARY`, `DESCRIPTION`, `CATEGROY`, `VERSION`, `LOGO_URL`, `ICON`, `DEFAULT_FLAG`, `LATEST_FLAG`, `BUILD_LESS_RUN_FLAG`, `REPOSITORY_HASH_ID`, `CODE_SRC`, `PAY_FLAG`, `HTML_TEMPLATE_VERSION`, `PROPS`, `DATA`, `PUBLISHER`, `WEIGHT`, `CREATOR`, `MODIFIER`, `CREATE_TIME`, `UPDATE_TIME`, `VISIBILITY_LEVEL`) VALUES ('39580f08e9574fc291cdd8c51f39ddee','P4','codeP4WebHookTrigger','codeP4WebHookTrigger','[ \"pipeline\" ]','AGENT','[ \"LINUX\", \"MACOS\", \"WINDOWS\" ]','e1bea5430f574f9ea3e0312dc7de9efa','',0,7,NULL,'Start the pipeline when listening to related events of the Perforce repository',' start the pipeline when listening to related events of the Perforce repository',0,'1.0.0','/ms/artifactory/api/user/artifactories/file/download?filePath=%2Ffile%2Fpng%2Fp4Trigger.png&logo=true',NULL,b'1',b'0',b'0',NULL,NULL,b'0','1.1','{"input":{"notice":{"label":"","type":"tips","tipStr":"1. The trigger will create a devops_trigger depot in the repository
2. To create a trigger, the credentials associated with the repository must have administrator privileges
3. Deleting the trigger plugin will not delete the server-side trigger, you need to delete it manually
"},"repositoryType":{"rule":{},"type":"enum-input","required":true,"label":"Repository","list":[{"value":"ID","label":"Select by repository ID"},{"value":"NAME","label":"Enter by repository alias"}],"default":"ID","desc":""},"repositoryHashId":{"rule":{},"label":"","hasAddItem":true,"type":"request-selector","searchable":true,"placeholder":"Please select a repository name","required":true,"default":"","url":"/repository/api/user/repositories/{projectId}/hasPermissionList?permission=USE&repositoryType=CODE_P4&page=1&pageSize=100","paramId":"repositoryHashId","paramName":"aliasName","tools":{"edit":true,"del":false},"rely":{"operation":"OR","expression":[{"key":"repositoryType","value":"ID"}]}},"repositoryName":{"rule":{},"type":"vuex-input","required":true,"label":"","placeholder":"请Enter a repository alias","default":"","rely":{"operation":"AND","expression":[{"key":"repositoryType","value":"NAME"}]}},"eventType":{"rule":{},"required":false,"type":"enum-input","label":"Event Type","list":[{"label":"change commit","value":"CHANGE_COMMIT"},{"label":"change content","value":"CHANGE_CONTENT"},{"label":"change submit","value":"CHANGE_SUBMIT"},{"label":"shelve commit","value":"SHELVE_COMMIT"},{"label":"shelve submit","value":"SHELVE_SUBMIT"}],"default":"CHANGE_COMMIT"},"noticePath":{"label":"","type":"tips","tipStr":"The Perforce path matching starts from the depot path. For example, if there is a demo depot, the configuration rules are as follows:
1. Listen to the aaa stream under //demo, //demo/aaa/**
2. Listen to //demo The java file under, //demo/*.java"},"includePaths":{"rule":{},"required":true,"type":"vuex-input","label":"Listen to the following paths","placeholder":"Separate multiple paths with commas","default":""},"excludePaths":{"rule":{},"required":false,"type":"vuex-input","label":"Exclude the following paths","placeholder":"Separate multiple paths with commas","default":""}}}','{}','system','2','system','system','2021-11-16 12:18:20','2021-11-16 12:18:20', 0); REPLACE INTO `T_ATOM` (`ID`, `NAME`, `ATOM_CODE`, `CLASS_TYPE`, `SERVICE_SCOPE`, `JOB_TYPE`, `OS`, `CLASSIFY_ID`, `DOCS_LINK`, `ATOM_TYPE`, `ATOM_STATUS`, `ATOM_STATUS_MSG`, `SUMMARY`, `DESCRIPTION`, `CATEGROY`, `VERSION`, `LOGO_URL`, `ICON`, `DEFAULT_FLAG`, `LATEST_FLAG`, `BUILD_LESS_RUN_FLAG`, `REPOSITORY_HASH_ID`, `CODE_SRC`, `PAY_FLAG`, `HTML_TEMPLATE_VERSION`, `PROPS`, `DATA`, `PUBLISHER`, `WEIGHT`, `CREATOR`, `MODIFIER`, `CREATE_TIME`, `UPDATE_TIME`, `VISIBILITY_LEVEL`) VALUES - ('2d90938b6a164d069045e960051e5421','P4','codeP4WebHookTrigger','codeP4WebHookTrigger','[ \"pipeline\" ]','AGENT','[ \"LINUX\", \"MACOS\", \"WINDOWS\" ]','e1bea5430f574f9ea3e0312dc7de9efa','',0,7,NULL,'Start the pipeline when listening to related events of the Perforce repository',' start the pipeline when listening to related events of the Perforce repository',0,'2.0.0','/ms/artifactory/api/user/artifactories/file/download?filePath=%2Ffile%2Fpng%2Fp4Trigger.png&logo=true',NULL,b'1',b'1',b'0',NULL,NULL,b'0','1.1','{"input":{"notice":{"label":"","type":"tips","tipStr":"To enable this plugin, you need to config [P4 Triggers](https://github.com/TencentBlueKing/bk-ci/issues/8556#issuecomment-1493775141)"},"repositoryType":{"rule":{},"type":"enum-input","required":true,"label":"Repository","list":[{"value":"ID","label":"Select by repository ID"},{"value":"NAME","label":"Enter by repository alias"}],"default":"ID","desc":""},"repositoryHashId":{"rule":{},"label":"","hasAddItem":true,"type":"request-selector","searchable":true,"placeholder":"Please select a repository name","required":true,"default":"","url":"/repository/api/user/repositories/{projectId}/hasPermissionList?permission=USE&repositoryType=CODE_P4&page=1&pageSize=100","paramId":"repositoryHashId","paramName":"aliasName","tools":{"edit":true,"del":false},"rely":{"operation":"OR","expression":[{"key":"repositoryType","value":"ID"}]}},"repositoryName":{"rule":{},"type":"vuex-input","required":true,"label":"","placeholder":"请Enter a repository alias","default":"","rely":{"operation":"AND","expression":[{"key":"repositoryType","value":"NAME"}]}},"eventType":{"rule":{},"required":false,"type":"enum-input","label":"Event Type","list":[{"label":"change commit","value":"CHANGE_COMMIT"}],"default":"CHANGE_COMMIT"}}}','{}','system','2','system','system','2021-11-16 12:18:20','2021-11-16 12:18:20', 0); + ('2d90938b6a164d069045e960051e5421','P4','codeP4WebHookTrigger','codeP4WebHookTrigger','[ \"pipeline\" ]','AGENT','[ \"LINUX\", \"MACOS\", \"WINDOWS\" ]','e1bea5430f574f9ea3e0312dc7de9efa','',0,7,NULL,'Start the pipeline when listening to related events of the Perforce repository',' start the pipeline when listening to related events of the Perforce repository',0,'2.0.0','/ms/artifactory/api/user/artifactories/file/download?filePath=%2Ffile%2Fpng%2Fp4Trigger.png&logo=true',NULL,b'1',b'1',b'0',NULL,NULL,b'0','1.1','{"input":{"notice":{"label":"","type":"tips","tipStr":"To enable this plugin, you need to config [P4 Triggers](https://github.com/TencentBlueKing/bk-ci/issues/8556#issuecomment-1493775141)"},"repositoryType":{"rule":{},"type":"enum-input","required":true,"label":"Repository","list":[{"value":"ID","label":"Select by repository ID"},{"value":"NAME","label":"Enter by repository alias"}],"default":"ID","desc":""},"repositoryHashId":{"rule":{},"label":"","hasAddItem":true,"type":"request-selector","searchable":true,"placeholder":"Please select a repository name","required":true,"default":"","url":"/repository/api/user/repositories/{projectId}/hasPermissionList?permission=USE&repositoryType=CODE_P4&page=1&pageSize=100","paramId":"repositoryHashId","paramName":"aliasName","tools":{"edit":true,"del":false},"rely":{"operation":"OR","expression":[{"key":"repositoryType","value":"ID"}]}},"repositoryName":{"rule":{},"type":"vuex-input","required":true,"label":"","placeholder":"请Enter a repository alias","default":"","rely":{"operation":"AND","expression":[{"key":"repositoryType","value":"NAME"}]}},"eventType":{"rule":{},"required":false,"type":"enum-input","label":"Event Type","list":[{"label":"change commit","value":"CHANGE_COMMIT"}],"default":"CHANGE_COMMIT"},"noticePath":{"label":"","type":"tips","tipStr":"The Perforce path matching starts from the depot path. For example, if there is a demo depot, the configuration rules are as follows:
1. Listen to the aaa stream under //demo, //demo/aaa/**
2. Listen to //demo The java file under, //demo/*.java"},"includePaths":{"rule":{},"required":true,"type":"vuex-input","label":"Listen to the following paths","placeholder":"Separate multiple paths with commas","default":""},"excludePaths":{"rule":{},"required":false,"type":"vuex-input","label":"Exclude the following paths","placeholder":"Separate multiple paths with commas","default":""}}}','{}','system','2','system','system','2021-11-16 12:18:20','2021-11-16 12:18:20', 0); INSERT IGNORE INTO `T_BUILD_RESOURCE`(`ID`, `BUILD_RESOURCE_CODE`, `BUILD_RESOURCE_NAME`, `DEFAULT_FLAG`, `CREATOR`, `MODIFIER`, `CREATE_TIME`, `UPDATE_TIME`) VALUES ('55913ac708c211e62192fa163e50f2b5', 'centos7.2', 'centos7.2', b'0', 'system', 'system', '2019-07-12 12:29:59', '2019-07-12 12:29:59');