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..ed01eca5d8d 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 @@ -54,7 +54,15 @@ data class CodeGithubWebHookTriggerElement( @ApiModelProperty("新版的github原子的类型") val repositoryType: RepositoryType? = null, @ApiModelProperty("新版的github代码库名") - val repositoryName: String? = null + val repositoryName: String? = null, + @ApiModelProperty("code review 状态", required = false) + val includeCrState: List? = null, + @ApiModelProperty("code note comment", required = false) + val includeNoteComment: String? = null, + @ApiModelProperty("code note 类型", required = false) + val includeNoteTypes: List? = null, + @ApiModelProperty("issue事件action") + val includeIssueAction: List? = null ) : WebHookTriggerElement(name, id, status) { companion object { const val classType = "codeGithubWebHookTrigger" diff --git a/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/WebhookConstant.kt b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/WebhookConstant.kt index 0852bfbc5b0..77653f0e1a1 100644 --- a/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/WebhookConstant.kt +++ b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/WebhookConstant.kt @@ -50,6 +50,7 @@ const val BK_REPO_GIT_WEBHOOK_EXCLUDE_BRANCHS = "BK_CI_REPO_GIT_WEBHOOK_EXCLUDE_ const val BK_REPO_GIT_WEBHOOK_INCLUDE_PATHS = "BK_CI_REPO_GIT_WEBHOOK_INCLUDE_PATHS" const val BK_REPO_GIT_WEBHOOK_EXCLUDE_PATHS = "BK_CI_REPO_GIT_WEBHOOK_EXCLUDE_PATHS" const val BK_REPO_GIT_WEBHOOK_EXCLUDE_USERS = "BK_CI_REPO_GIT_WEBHOOK_EXCLUDE_USERS" +const val BK_REPO_GIT_WEBHOOK_INCLUDE_USERS = "BK_CI_REPO_GIT_WEBHOOK_INCLUDE_USERS" const val BK_REPO_GIT_WEBHOOK_BRANCH = "BK_CI_REPO_GIT_WEBHOOK_BRANCH" const val BK_REPO_GIT_MANUAL_UNLOCK = "BK_CI_REPO_GIT_MANUAL_UNLOCK" const val BK_REPO_GIT_WEBHOOK_ENABLE_CHECK = "BK_REPO_GIT_WEBHOOK_ENABLE_CHECK" diff --git a/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubBaseInfo.kt b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubBaseInfo.kt new file mode 100644 index 00000000000..c277a0d1e45 --- /dev/null +++ b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubBaseInfo.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.common.webhook.pojo.code.github + +import com.fasterxml.jackson.annotation.JsonProperty +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty + +@ApiModel("Github 基础信息") +open class GithubBaseInfo( + @ApiModelProperty("ID") + open val id: Long, + @ApiModelProperty("链接[API链接]") + open val url: String? = "", + @JsonProperty("html_url") + @ApiModelProperty("链接[网页链接]") + open val htmlUrl: String? = "", + @JsonProperty("node_id") + open val nodeId: String, + @JsonProperty("created_at") + open val createdAt: String? = "", // 2022-06-21T08:45:41Z + @JsonProperty("updated_at") + open val updatedAt: String? = "" +) { + companion object { + // github主页地址 + const val GITHUB_HOME_PAGE_URL = "https://github.com" + } +} diff --git a/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubCommitCommentEvent.kt b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubCommitCommentEvent.kt new file mode 100644 index 00000000000..a7bb58dd031 --- /dev/null +++ b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubCommitCommentEvent.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.common.webhook.pojo.code.github + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties +import com.fasterxml.jackson.annotation.JsonProperty +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty + +/** + * Github 评论分四种: + * 1. PR Review 评论 + * 1.1 基于PR直接评论 + * 1.2 基于PR Review的会话进行评论 + * 2. Issues 评论 + * 3. Commit 评论 + */ +@JsonIgnoreProperties(ignoreUnknown = true) +abstract class GithubCommentEvent( + open val action: String, + open val repository: GithubRepository, + open val comment: GithubComment, + override val sender: GithubUser +) : GithubEvent(sender) { + open fun getCommentType(): String = "" +} + +@JsonIgnoreProperties(ignoreUnknown = true) +data class GithubCommitCommentEvent( + override val action: String, + override val repository: GithubRepository, + override val comment: GithubCommitComment, + override val sender: GithubUser +) : GithubCommentEvent( + action = action, + repository = repository, + comment = comment, + sender = sender +) { + companion object { + const val classType = "commit_comment" + + // 评论类型:基于Commit进行评论 + const val commentType = "Commit" + } + + override fun getCommentType() = commentType +} + +@ApiModel("Github Review 评论事件") +data class GithubReviewCommentEvent( + override val action: String, + @JsonProperty("pull_request") + @ApiModelProperty("Issues相关信息") + val pullRequest: GithubPullRequest, + @ApiModelProperty("Github仓库相关信息") + override val repository: GithubRepository, + @ApiModelProperty("操作人信息") + override val sender: GithubUser, + @ApiModelProperty("Review会话信息") + override val comment: GithubReviewComment +) : GithubCommentEvent( + action = action, + repository = repository, + comment = comment, + sender = sender +) { + companion object { + const val classType = "pull_request_review_comment" + + // 评论类型:基于Pull Request Review进行评论 + const val commentType = "Review" + } + + override fun getCommentType() = commentType +} + +data class GithubReviewComment( + override val id: Long, + override val url: String?, + @JsonProperty("html_url") + override val htmlUrl: String?, + @JsonProperty("node_id") + override val nodeId: String, + override val body: String, + override val user: GithubUser, + @JsonProperty("created_at") + override val createdAt: String?, + @JsonProperty("updated_at") + override val updatedAt: String?, + @ApiModelProperty("Github PR Review Id") + @JsonProperty("pull_request_review_id") + val pullRequestReviewId: Long, + @ApiModelProperty("Github PR Review会话对应的文件") + val path: String +) : GithubComment( + id = id, + url = url, + htmlUrl = htmlUrl, + nodeId = nodeId, + body = body, + user = user, + createdAt = createdAt, + updatedAt = updatedAt +) + +@JsonIgnoreProperties(ignoreUnknown = true) +data class GithubIssueCommentEvent( + override val action: String, + override val repository: GithubRepository, + override val comment: GithubIssueComment, + override val sender: GithubUser, + val issue: GithubIssue +) : GithubCommentEvent( + action = action, + repository = repository, + comment = comment, + sender = sender +) { + companion object { + const val classType = "issue_comment" + } + + override fun getCommentType() = if (issue.pullRequest != null) { + // 对齐Code_Git直接在PR上评论则[noteableType=Review] + "Review" + } else { + "Issue" + } +} + +@Suppress("LongParameterList") +@ApiModel("Github 评论信息父类") +abstract class GithubComment( + @ApiModelProperty("评论ID") + override val id: Long, + @ApiModelProperty("评论链接[API链接]") + override val url: String?, + @JsonProperty("html_url") + @ApiModelProperty("评论链接[网页链接]") + override val htmlUrl: String?, + @JsonProperty("node_id") + override val nodeId: String, + @ApiModelProperty("评论内容") + open val body: String, + @ApiModelProperty("评论的用户") + open val user: GithubUser, + @JsonProperty("created_at") + @ApiModelProperty("创建时间") + override val createdAt: String?, // 2022-06-21T08:45:41Z + @JsonProperty("updated_at") + @ApiModelProperty("修改时间") + override val updatedAt: String? // 2022-06-21T08:45:41Z +) : GithubBaseInfo( + id = id, + url = url, + htmlUrl = htmlUrl, + nodeId = nodeId, + updatedAt = updatedAt, + createdAt = createdAt +) + +@SuppressWarnings("LongParameterList") +open class GithubCommitComment( + override val id: Long, + override val url: String?, + @JsonProperty("html_url") + override val htmlUrl: String?, + @JsonProperty("node_id") + override val nodeId: String, + override val body: String, + override val user: GithubUser, + @JsonProperty("created_at") + override val createdAt: String?, + @JsonProperty("updated_at") + override val updatedAt: String?, + @JsonProperty("commit_id") + @ApiModelProperty("commit sha") + val commitId: String +) : GithubComment( + id = id, + url = url, + htmlUrl = htmlUrl, + nodeId = nodeId, + body = body, + user = user, + createdAt = createdAt, + updatedAt = updatedAt +) + +@ApiModel("Github Issue 评论") +data class GithubIssueComment( + override val id: Long, + override val url: String?, + @JsonProperty("html_url") + override val htmlUrl: String?, + @JsonProperty("node_id") + override val nodeId: String, + override val body: String, + override val user: GithubUser, + @JsonProperty("created_at") + override val createdAt: String?, + @JsonProperty("updated_at") + override val updatedAt: String?, + @JsonProperty("issue_url") + @ApiModelProperty("评论链接[API链接]") + val issueUrl: String +) : GithubComment( + id = id, + url = url, + htmlUrl = htmlUrl, + nodeId = nodeId, + body = body, + user = user, + createdAt = createdAt, + updatedAt = updatedAt +) diff --git a/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubEvent.kt b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubEvent.kt index f366fb98274..94c31d3c031 100644 --- a/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubEvent.kt +++ b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubEvent.kt @@ -92,14 +92,14 @@ data class GithubUser( // val gistsUrl: String, // https://api.github.com/users/yongyiduan/gists{/gist_id} @JsonProperty("gravatar_id") val gravatarId: String, -// @JsonProperty("html_url") -// val htmlUrl: String, // https://github.com/yongyiduan + @JsonProperty("html_url") + override val htmlUrl: String?, // https://github.com/yongyiduan @JsonProperty("id") - val id: Int, // 88175075 + override val id: Long, // 88175075 @JsonProperty("login") val login: String, // yongyiduan @JsonProperty("node_id") - val nodeId: String, // MDQ6VXNlcjg4MTc1MDc1 + override val nodeId: String, // MDQ6VXNlcjg4MTc1MDc1 // @JsonProperty("organizations_url") // val organizationsUrl: String, // https://api.github.com/users/yongyiduan/orgs // @JsonProperty("received_events_url") @@ -113,9 +113,20 @@ data class GithubUser( // @JsonProperty("subscriptions_url") // val subscriptionsUrl: String, // https://api.github.com/users/yongyiduan/subscriptions @JsonProperty("type") - val type: String // User + val type: String, // User // @JsonProperty("url") -// val url: String // https://api.github.com/users/yongyiduan + override val url: String?, // https://api.github.com/users/yongyiduan, + @JsonProperty("created_at") + override val createdAt: String?, // 2022-06-21T08:45:41Z + @JsonProperty("updated_at") + override val updatedAt: String? // 2022-06-21T08:45:41Z +) : GithubBaseInfo( + id = id, + url = url, + htmlUrl = htmlUrl, + nodeId = nodeId, + updatedAt = updatedAt, + createdAt = createdAt ) @Suppress("ALL") @@ -171,7 +182,7 @@ data class GithubRepository( // @JsonProperty("contributors_url") // val contributorsUrl: String, // https://api.github.com/repos/yongyiduan/webhook-test/contributors @JsonProperty("created_at") - val createdAt: Any, // 1655798261 or 2022-06-21T08:45:42Z github这两种类型都会传,难受~ + override val createdAt: String?, // 1655798261 or 2022-06-21T08:45:42Z github这两种类型都会传,难受~ @JsonProperty("default_branch") val defaultBranch: String, // main // @JsonProperty("deployments_url") @@ -216,10 +227,10 @@ data class GithubRepository( val homepage: String?, // null // @JsonProperty("hooks_url") // val hooksUrl: String, // https://api.github.com/repos/yongyiduan/webhook-test/hooks -// @JsonProperty("html_url") -// val htmlUrl: String, // https://github.com/yongyiduan/webhook-test + @JsonProperty("html_url") + override val htmlUrl: String?, // https://github.com/yongyiduan/webhook-test @JsonProperty("id") - val id: Int, // 505743915 + override val id: Long, // 505743915 @JsonProperty("is_template") val isTemplate: Boolean, // false // @JsonProperty("issue_comment_url") @@ -245,7 +256,7 @@ data class GithubRepository( @JsonProperty("name") val name: String, // webhook-test @JsonProperty("node_id") - val nodeId: String, // R_kgDOHiUKKw + override val nodeId: String, // R_kgDOHiUKKw // @JsonProperty("notifications_url") // val notificationsUrl: String, // https://api.github.com/repos/yongyiduan/webhook-test/notifications{?since,all,participating} @JsonProperty("open_issues") @@ -289,15 +300,22 @@ data class GithubRepository( // @JsonProperty("trees_url") // val treesUrl: String, // https://api.github.com/repos/yongyiduan/webhook-test/git/trees{/sha} @JsonProperty("updated_at") - val updatedAt: String?, // 2022-06-21T07:54:56Z + override val updatedAt: String?, // 2022-06-21T07:54:56Z @JsonProperty("url") - val url: String, // https://github.com/yongyiduan/webhook-test + override val url: String, // https://github.com/yongyiduan/webhook-test @JsonProperty("visibility") val visibility: String, // public @JsonProperty("watchers") val watchers: Int, // 0 @JsonProperty("watchers_count") val watchersCount: Int // 0 +) : GithubBaseInfo( + id = id, + url = url, + htmlUrl = htmlUrl, + nodeId = nodeId, + updatedAt = updatedAt, + createdAt = createdAt ) @Suppress("ALL") diff --git a/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubIssuesEvent.kt b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubIssuesEvent.kt new file mode 100644 index 00000000000..7a45f8c34ef --- /dev/null +++ b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubIssuesEvent.kt @@ -0,0 +1,140 @@ +/* + * 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.webhook.pojo.code.github + +import com.fasterxml.jackson.annotation.JsonProperty +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty + +@ApiModel("Github Issues 事件") +data class GithubIssuesEvent( + val action: String, + @ApiModelProperty("Issues相关信息") + val issue: GithubIssue, + @ApiModelProperty("Github仓库相关信息") + val repository: GithubRepository, + @ApiModelProperty("操作人信息") + override val sender: GithubUser, + @ApiModelProperty("受理人") + val assignees: List? +) : GithubEvent(sender) { + companion object { + const val classType = "issues" + } + + fun convertAction() = when (action) { + GithubIssuesAction.OPENED.value -> "open" + GithubIssuesAction.CLOSED.value -> "close" + GithubIssuesAction.REOPENED.value -> "reopen" + GithubIssuesAction.EDITED.value -> "update" + else -> "" + } +} + +data class GithubIssue( + override val url: String?, + @JsonProperty("html_url") + @ApiModelProperty("Issue/Pull Request链接[网页链接]") + override val htmlUrl: String?, + @ApiModelProperty("Issue ID") + override val id: Long, + @JsonProperty("node_id") + override val nodeId: String, + @JsonProperty("created_at") + override val createdAt: String?, // 2022-06-21T08:45:41Z + @JsonProperty("updated_at") + override val updatedAt: String?, // 2022-06-21T08:45:41Z + @ApiModelProperty("Issue/Pull Request编号") + val number: Long, + @ApiModelProperty("Issue/Pull Request标题信息") + val title: String, + @ApiModelProperty("Issue/Pull Request创建用户") + val user: GithubUser, + @ApiModelProperty("Issue/Pull Request标签信息") + val labels: List, + @ApiModelProperty("issues/Pull Request 状态信息") + val state: String, + val locked: String, + @ApiModelProperty("issues/Pull Request 受理人") + val assignees: List?, + @JsonProperty("closed_at") + val closedAt: String?, + @JsonProperty("Issues/Pull Request 描述信息") + val body: String?, + @JsonProperty("pull_request") + @ApiModelProperty("issues 关联的pull request信息,为空时代表仅在issue上操作") + val pullRequest: GithubPullRequestUrl?, + val milestone: GithubMilestone? +) : GithubBaseInfo( + id = id, + url = url, + htmlUrl = htmlUrl, + nodeId = nodeId, + updatedAt = updatedAt, + createdAt = createdAt +) + +data class GithubPullRequestUrl( + val url: String, + @JsonProperty("html_url") + @ApiModelProperty("Pull Request链接[网页链接]") + val htmlUrl: String, + @JsonProperty("diff_url") + @ApiModelProperty("Pull Request 修改内容链接[raw]") + val diffUrl: String, + @JsonProperty("patch_url") + @ApiModelProperty("Pull Request 补丁链接[raw]") + val patchUrl: String +) + +@ApiModel("Github Issue 状态") +enum class GithubIssuesState(val value: String) { + CLOSED("close"), + OPEN("open") +} + +@ApiModel("Github Issue 操作") +enum class GithubIssuesAction(val value: String) { + @ApiModelProperty("重新打开") + REOPENED("reopened"), + + @ApiModelProperty("关闭") + CLOSED("closed"), + + @ApiModelProperty("创建") + OPENED("opened"), + + @ApiModelProperty("指派受理人") + ASSIGNED("assigned"), + + @ApiModelProperty("标记") + LABELED("labeled"), + + @ApiModelProperty("修改") + EDITED("edited"), +} diff --git a/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubPullRequestEvent.kt b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubPullRequestEvent.kt index 3a79fe905f9..ce9123cb147 100644 --- a/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubPullRequestEvent.kt +++ b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubPullRequestEvent.kt @@ -106,13 +106,13 @@ data class GithubPullRequest( @JsonProperty("locked") val locked: Boolean, // false @JsonProperty("maintainer_can_modify") - val maintainerCanModify: Boolean, // false + val maintainerCanModify: Boolean? = false, // false @JsonProperty("merge_commit_sha") val mergeCommitSha: String?, // null @JsonProperty("mergeable") - val mergeable: String?, // null + var mergeable: Boolean?, // null @JsonProperty("mergeable_state") - val mergeableState: String, // unknown + var mergeableState: String?, // unknown @JsonProperty("merged") val merged: Boolean, // false @JsonProperty("merged_at") @@ -163,7 +163,7 @@ data class GithubMilestone( @JsonProperty("creator") val creator: GithubUser, @JsonProperty("description") - val description: String, // Tracking milestone for version 1.0 + val description: String?, // Tracking milestone for version 1.0 @JsonProperty("due_on") val dueOn: String?, // 2012-10-09T23:39:01Z @JsonProperty("html_url") diff --git a/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubReviewEvent.kt b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubReviewEvent.kt new file mode 100644 index 00000000000..58aea62ee25 --- /dev/null +++ b/src/backend/ci/core/common/common-webhook/api-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/pojo/code/github/GithubReviewEvent.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.common.webhook.pojo.code.github + +import com.fasterxml.jackson.annotation.JsonProperty +import io.swagger.annotations.ApiModel +import io.swagger.annotations.ApiModelProperty + +@ApiModel("Github Review 事件") +data class GithubReviewEvent( + val action: String, + @JsonProperty("pull_request") + @ApiModelProperty("Issues相关信息") + val pullRequest: GithubPullRequest, + @ApiModelProperty("Github仓库相关信息") + val repository: GithubRepository, + @ApiModelProperty("操作人信息") + override val sender: GithubUser, + @ApiModelProperty("评审信息") + val review: GithubReview +) : GithubEvent(sender) { + companion object { + const val classType = "pull_request_review" + } + + fun convertState() = when { + isApproved() -> "approved" + isChangeRequired() -> "change_required" + isChangeDenied() -> "change_denied" + isApproving() -> "approving" + else -> "" + } + + // 当存在多个必要评审人时,一个用户评审通过不算通过,需判断合并状态 + private fun isApproved() = (pullRequest.mergeable == true) && + ((pullRequest.mergeableState?.toUpperCase() ?: "") == ReviewMergeStateStatus.CLEAN.name) + + private fun isChangeRequired() = review.state == GithubReviewState.CHANGES_REQUESTED.value + + private fun isChangeDenied() = action == GithubReviewState.DISMISSED.value + + // 当存在多个必要评审人时,一个用户评审通过但仍不允许merge,次状态为approving + private fun isApproving() = + (review.state == GithubReviewState.APPROVING.value || review.state == GithubReviewState.APPROVED.value) && + !isApproved() +} +data class GithubReview( + override val id: Long, + @JsonProperty("node_id") + override val nodeId: String, + @JsonProperty("html_url") + @ApiModelProperty("评审地址[网页地址]") + override val htmlUrl: String?, + @JsonProperty("created_at") + override val createdAt: String?, // 2022-06-21T08:45:41Z + @JsonProperty("updated_at") + override val updatedAt: String?, // 2022-06-21T08:45:41Z + val user: GithubUser, + @ApiModelProperty("评审内容") + val body: String?, + @JsonProperty("commit_id") + val commitId: String, + @ApiModelProperty("提交时间") + @JsonProperty("submitted_at") + val submittedAt: String, + @ApiModelProperty("评审状态") + val state: String, + @JsonProperty("pull_request_url") + @ApiModelProperty("PR地址[Api地址]") + val pullRequestUrl: String, + @JsonProperty("author_association") + val authorAssociation: String +) : GithubBaseInfo( + id = id, + htmlUrl = htmlUrl, + nodeId = nodeId, + updatedAt = updatedAt, + createdAt = createdAt +) + +@ApiModel("Github Review 状态") +enum class GithubReviewState(val value: String) { + @ApiModelProperty("批准") + APPROVED("approved"), + + @ApiModelProperty("要求修改") + CHANGES_REQUESTED("changes_requested"), + + @ApiModelProperty("评论") + COMMENTED("commented"), + + @ApiModelProperty("驳回") + DISMISSED("dismissed"), + + @ApiModelProperty("尚未提交的评审报告") + PENDING("pending"), + + @ApiModelProperty("评审中【自定义枚举项,实际不存在】") + APPROVING("approving") +} + +@ApiModel("Github Review 合并状态") +enum class ReviewMergeStateStatus { + @ApiModelProperty("头标已过时") + BEHIND, + @ApiModelProperty("阻塞") + BLOCKED, + @ApiModelProperty("可合并和传递提交状态") + CLEAN, + @ApiModelProperty("无法干净地创建合并提交") + DIRTY, + @ApiModelProperty("由于拉取请求是草稿") + DRAFT, + @ApiModelProperty("可与传递的提交状态和预接收挂钩合并") + HAS_HOOKS, + @ApiModelProperty("目前无法确定状态") + UNKNOWN, + @ApiModelProperty("可与非传递提交状态合并") + UNSTABLE +} diff --git a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/EventCacheService.kt b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/EventCacheService.kt index 41e8485f2c9..a09f9913984 100644 --- a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/EventCacheService.kt +++ b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/EventCacheService.kt @@ -2,6 +2,7 @@ package com.tencent.devops.common.webhook.service.code import com.tencent.devops.common.api.enums.RepositoryType import com.tencent.devops.common.client.Client +import com.tencent.devops.common.sdk.github.response.PullRequestResponse import com.tencent.devops.common.webhook.util.EventCacheUtil import com.tencent.devops.repository.api.ServiceP4Resource import com.tencent.devops.repository.pojo.Repository @@ -155,11 +156,13 @@ class EventCacheService @Autowired constructor( ): P4ServerInfo? { val eventCache = EventCacheUtil.getOrInitRepoCache(projectId = projectId, repo = repo) return eventCache?.serverInfo ?: run { - client.get(ServiceP4Resource::class).getServerInfo( + val p4ServerInfo = client.get(ServiceP4Resource::class).getServerInfo( projectId = projectId, repositoryId = repositoryId, repositoryType = repositoryType ).data + eventCache?.serverInfo = p4ServerInfo + p4ServerInfo } } @@ -183,4 +186,22 @@ class EventCacheService @Autowired constructor( commitReviewInfo } } + + fun getPrInfo( + githubRepoName: String, + pullNumber: String, + repo: Repository, + projectId: String + ): PullRequestResponse? { + val eventCache = EventCacheUtil.getOrInitRepoCache(projectId = projectId, repo = repo) + return eventCache?.githubPrInfo ?: run { + val prInfo = gitScmService.getPrInfo( + repo = repo, + githubRepoName = githubRepoName, + pullNumber = pullNumber + ) + eventCache?.githubPrInfo = prInfo + prInfo + } + } } diff --git a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/GitScmService.kt b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/GitScmService.kt index 798194d95f3..329cc31f311 100644 --- a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/GitScmService.kt +++ b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/GitScmService.kt @@ -31,7 +31,11 @@ import com.tencent.devops.common.api.enums.ScmType import com.tencent.devops.common.api.exception.ErrorCodeException import com.tencent.devops.common.api.util.DHUtil import com.tencent.devops.common.client.Client +import com.tencent.devops.common.sdk.github.request.GetPullRequestRequest +import com.tencent.devops.common.sdk.github.response.PullRequestResponse +import com.tencent.devops.repository.api.ServiceGithubResource import com.tencent.devops.repository.api.ServiceOauthResource +import com.tencent.devops.repository.api.github.ServiceGithubPRResource import com.tencent.devops.repository.api.scm.ServiceGitResource import com.tencent.devops.repository.api.scm.ServiceScmOauthResource import com.tencent.devops.repository.api.scm.ServiceScmResource @@ -408,4 +412,28 @@ class GitScmService @Autowired constructor( null } } + + fun getPrInfo( + githubRepoName: String, + pullNumber: String, + repo: Repository + ): PullRequestResponse? { + return try { + val accessToken = client.get(ServiceGithubResource::class).getAccessToken( + userId = repo.userName + ).data?.accessToken ?: "" + val prInfo = client.get(ServiceGithubPRResource::class).getPullRequest( + request = GetPullRequestRequest( + repoName = githubRepoName, + pullNumber = pullNumber + ), + token = accessToken + ).data + logger.info("get github pull info|repoName[$githubRepoName]|prNumber[$pullNumber]|[$prInfo]") + prInfo + } catch (ignored: Exception) { + logger.warn("fail to get github pull request", ignored) + null + } + } } diff --git a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/GithubIssueTriggerHandler.kt b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/GithubIssueTriggerHandler.kt new file mode 100644 index 00000000000..4348b9717a3 --- /dev/null +++ b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/GithubIssueTriggerHandler.kt @@ -0,0 +1,142 @@ +/* + * 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.webhook.service.code.handler.github + +import com.tencent.devops.common.pipeline.pojo.element.trigger.enums.CodeEventType +import com.tencent.devops.common.pipeline.utils.PIPELINE_GIT_EVENT_URL +import com.tencent.devops.common.webhook.annotation.CodeWebhookHandler +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_ISSUE_ACTION +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_ISSUE_DESCRIPTION +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_ISSUE_ID +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_ISSUE_MILESTONE_ID +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_ISSUE_OWNER +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_ISSUE_STATE +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_ISSUE_TITLE +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_ISSUE_URL +import com.tencent.devops.common.webhook.pojo.code.WebHookParams +import com.tencent.devops.common.webhook.pojo.code.github.GithubBaseInfo +import com.tencent.devops.common.webhook.pojo.code.github.GithubIssuesEvent +import com.tencent.devops.common.webhook.service.code.filter.ContainsFilter +import com.tencent.devops.common.webhook.service.code.filter.EventTypeFilter +import com.tencent.devops.common.webhook.service.code.filter.GitUrlFilter +import com.tencent.devops.common.webhook.service.code.filter.WebhookFilter +import com.tencent.devops.common.webhook.service.code.handler.CodeWebhookTriggerHandler +import com.tencent.devops.common.webhook.service.code.matcher.ScmWebhookMatcher +import com.tencent.devops.common.webhook.util.WebhookUtils +import com.tencent.devops.repository.pojo.Repository + +@CodeWebhookHandler +@Suppress("TooManyFunctions") +class GithubIssueTriggerHandler : CodeWebhookTriggerHandler { + override fun eventClass(): Class { + return GithubIssuesEvent::class.java + } + + override fun getUrl(event: GithubIssuesEvent): String { + return with(event) { + repository.htmlUrl ?: "${GithubBaseInfo.GITHUB_HOME_PAGE_URL}/${repository.fullName}" + } + } + + override fun getUsername(event: GithubIssuesEvent): String { + return event.sender.login + } + + override fun getRevision(event: GithubIssuesEvent): String { + return "" + } + + override fun getRepoName(event: GithubIssuesEvent): String { + return event.repository.fullName + } + + override fun getBranchName(event: GithubIssuesEvent): String { + return "" + } + + override fun getEventType(): CodeEventType { + return CodeEventType.ISSUES + } + + override fun getMessage(event: GithubIssuesEvent): String? { + return event.issue.title + } + + override fun preMatch(event: GithubIssuesEvent): ScmWebhookMatcher.MatchResult { + return ScmWebhookMatcher.MatchResult(true) + } + + override fun getWebhookFilters( + event: GithubIssuesEvent, + projectId: String, + pipelineId: String, + repository: Repository, + webHookParams: WebHookParams + ): List { + with(webHookParams) { + val urlFilter = GitUrlFilter( + pipelineId = pipelineId, + triggerOnUrl = getUrl(event), + repositoryUrl = repository.url, + includeHost = includeHost + ) + val eventTypeFilter = EventTypeFilter( + pipelineId = pipelineId, + triggerOnEventType = getEventType(), + eventType = eventType + ) + val actionFilter = ContainsFilter( + pipelineId = pipelineId, + filterName = "issueAction", + triggerOn = event.convertAction(), + included = WebhookUtils.convert(includeIssueAction) + ) + return listOf(urlFilter, eventTypeFilter, actionFilter) + } + } + + override fun retrieveParams( + event: GithubIssuesEvent, + projectId: String?, + repository: Repository? + ): Map { + val startParams = mutableMapOf() + with(event.issue) { + startParams[BK_REPO_GIT_WEBHOOK_ISSUE_TITLE] = title + startParams[BK_REPO_GIT_WEBHOOK_ISSUE_ID] = id + startParams[BK_REPO_GIT_WEBHOOK_ISSUE_DESCRIPTION] = body ?: "" + startParams[BK_REPO_GIT_WEBHOOK_ISSUE_STATE] = state + startParams[BK_REPO_GIT_WEBHOOK_ISSUE_OWNER] = user.login + startParams[BK_REPO_GIT_WEBHOOK_ISSUE_URL] = htmlUrl ?: "" + startParams[BK_REPO_GIT_WEBHOOK_ISSUE_MILESTONE_ID] = milestone?.id ?: "" + startParams[BK_REPO_GIT_WEBHOOK_ISSUE_ACTION] = event.action + startParams[PIPELINE_GIT_EVENT_URL] = htmlUrl ?: "" + } + return startParams + } +} diff --git a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/GithubReviewTriggerHandler.kt b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/GithubReviewTriggerHandler.kt new file mode 100644 index 00000000000..bbfc9dece7c --- /dev/null +++ b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/GithubReviewTriggerHandler.kt @@ -0,0 +1,175 @@ +/* + * 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.webhook.service.code.handler.github + +import com.tencent.devops.common.pipeline.pojo.element.trigger.enums.CodeEventType +import com.tencent.devops.common.webhook.annotation.CodeWebhookHandler +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_APPROVING_REVIEWERS +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_ID +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_IID +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_OWNER +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_SOURCE_BRANCH +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_SOURCE_PROJECT_ID +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_STATE +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_TARGET_BRANCH +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_TARGET_PROJECT_ID +import com.tencent.devops.common.webhook.pojo.code.WebHookParams +import com.tencent.devops.common.webhook.pojo.code.github.GithubBaseInfo +import com.tencent.devops.common.webhook.pojo.code.github.GithubReviewEvent +import com.tencent.devops.common.webhook.pojo.code.github.GithubReviewState +import com.tencent.devops.common.webhook.service.code.EventCacheService +import com.tencent.devops.common.webhook.service.code.filter.ContainsFilter +import com.tencent.devops.common.webhook.service.code.filter.EventTypeFilter +import com.tencent.devops.common.webhook.service.code.filter.GitUrlFilter +import com.tencent.devops.common.webhook.service.code.filter.WebhookFilter +import com.tencent.devops.common.webhook.service.code.handler.CodeWebhookTriggerHandler +import com.tencent.devops.common.webhook.service.code.matcher.ScmWebhookMatcher +import com.tencent.devops.common.webhook.util.WebhookUtils +import com.tencent.devops.repository.pojo.Repository +import org.slf4j.LoggerFactory +import org.springframework.beans.factory.annotation.Autowired + +@CodeWebhookHandler +@Suppress("TooManyFunctions") +class GithubReviewTriggerHandler @Autowired constructor( + val eventCacheService: EventCacheService +) : CodeWebhookTriggerHandler { + override fun eventClass(): Class { + return GithubReviewEvent::class.java + } + + override fun getUrl(event: GithubReviewEvent): String { + return with(event) { + repository.htmlUrl ?: "${GithubBaseInfo.GITHUB_HOME_PAGE_URL}/${repository.fullName}" + } + } + + override fun getUsername(event: GithubReviewEvent): String { + return event.sender.login + } + + override fun getRevision(event: GithubReviewEvent): String { + return "" + } + + override fun getRepoName(event: GithubReviewEvent): String { + return event.repository.fullName + } + + override fun getBranchName(event: GithubReviewEvent): String { + return "" + } + + override fun getEventType(): CodeEventType { + return CodeEventType.REVIEW + } + + override fun getMessage(event: GithubReviewEvent): String? { + return event.pullRequest.title + } + + override fun preMatch(event: GithubReviewEvent): ScmWebhookMatcher.MatchResult { + // Review事件仅提交操作才触发,评审通过、拒绝、要求修改 + val result = (event.action == "submitted" || event.action == "dismissed") && + event.review.state != GithubReviewState.COMMENTED.value + return ScmWebhookMatcher.MatchResult(result) + } + + override fun getWebhookFilters( + event: GithubReviewEvent, + projectId: String, + pipelineId: String, + repository: Repository, + webHookParams: WebHookParams + ): List { + with(webHookParams) { + eventCacheService.getPrInfo( + githubRepoName = event.repository.fullName, + pullNumber = event.pullRequest.number.toString(), + repo = repository, + projectId = projectId + )?.run { + event.pullRequest.mergeable = this.mergeable + event.pullRequest.mergeableState = this.mergeableState + } + logger.info("github review event[$event]") + val urlFilter = GitUrlFilter( + pipelineId = pipelineId, + triggerOnUrl = getUrl(event), + repositoryUrl = repository.url, + includeHost = includeHost + ) + val eventTypeFilter = EventTypeFilter( + pipelineId = pipelineId, + triggerOnEventType = getEventType(), + eventType = eventType + ) + val crStateFilter = ContainsFilter( + pipelineId = pipelineId, + filterName = "crState", + triggerOn = event.convertState(), + included = WebhookUtils.convert(includeCrState) + ) + return listOf(urlFilter, eventTypeFilter, crStateFilter) + } + } + + override fun retrieveParams( + event: GithubReviewEvent, + projectId: String?, + repository: Repository? + ): Map { + val startParams = mutableMapOf() + // PR 相关启动参数 + val prStartParam = WebhookUtils.prStartParam( + pullRequest = event.pullRequest, + homepage = event.repository.homepage + ) + startParams.putAll(prStartParam) + with(event.review) { + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_ID] = id + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_IID] = event.pullRequest.number + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_STATE] = state + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_OWNER] = user.login + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_SOURCE_BRANCH] = event.pullRequest.head.ref + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_TARGET_BRANCH] = event.pullRequest.base.ref + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_SOURCE_PROJECT_ID] = event.pullRequest.head.repo.id + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_TARGET_PROJECT_ID] = event.pullRequest.base.repo.id + event.pullRequest.requestedReviewers.run { + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_APPROVING_REVIEWERS] = this.joinToString(",") { + it.login + } + } + } + return startParams + } + + companion object { + private val logger = LoggerFactory.getLogger(GithubReviewTriggerHandler::class.java) + } +} diff --git a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/comment/GithubCommentTriggerHandler.kt b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/comment/GithubCommentTriggerHandler.kt new file mode 100644 index 00000000000..400a6d1afce --- /dev/null +++ b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/comment/GithubCommentTriggerHandler.kt @@ -0,0 +1,156 @@ +/* + * 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.webhook.service.code.handler.github.comment + +import com.tencent.devops.common.pipeline.pojo.element.trigger.enums.CodeEventType +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_NOTE_AUTHOR_ID +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_NOTE_COMMENT +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_NOTE_CREATED_AT +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_NOTE_ID +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_NOTE_NOTEABLE_TYPE +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_NOTE_PROJECT_ID +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_NOTE_UPDATED_AT +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_NOTE_URL +import com.tencent.devops.common.webhook.pojo.code.PIPELINE_WEBHOOK_NOTE_COMMENT +import com.tencent.devops.common.webhook.pojo.code.PIPELINE_WEBHOOK_NOTE_ID +import com.tencent.devops.common.webhook.pojo.code.WebHookParams +import com.tencent.devops.common.webhook.pojo.code.github.GithubBaseInfo +import com.tencent.devops.common.webhook.pojo.code.github.GithubCommentEvent +import com.tencent.devops.common.webhook.service.code.filter.ContainsFilter +import com.tencent.devops.common.webhook.service.code.filter.EventTypeFilter +import com.tencent.devops.common.webhook.service.code.filter.GitUrlFilter +import com.tencent.devops.common.webhook.service.code.filter.RegexContainFilter +import com.tencent.devops.common.webhook.service.code.filter.WebhookFilter +import com.tencent.devops.common.webhook.service.code.handler.CodeWebhookTriggerHandler +import com.tencent.devops.common.webhook.service.code.matcher.ScmWebhookMatcher +import com.tencent.devops.common.webhook.util.WebhookUtils +import com.tencent.devops.repository.pojo.Repository + +/** + * Github 评论事件处理器接口 + */ +@Suppress("TooManyFunctions") +interface GithubCommentTriggerHandler : CodeWebhookTriggerHandler { + override fun getUrl(event: T): String { + return with(event) { + repository.htmlUrl ?: "${GithubBaseInfo.GITHUB_HOME_PAGE_URL}/${repository.fullName}" + } + } + + override fun getUsername(event: T): String { + return event.sender.login + } + + override fun getRevision(event: T): String { + return "" + } + + override fun getRepoName(event: T): String { + return event.repository.fullName + } + + override fun getBranchName(event: T): String { + return "" + } + + override fun getEventType(): CodeEventType { + return CodeEventType.NOTE + } + + override fun getMessage(event: T): String? { + return event.comment.body + } + + override fun preMatch(event: T): ScmWebhookMatcher.MatchResult { + return ScmWebhookMatcher.MatchResult(true) + } + + override fun getWebhookFilters( + event: T, + projectId: String, + pipelineId: String, + repository: Repository, + webHookParams: WebHookParams + ): List { + with(webHookParams) { + val urlFilter = GitUrlFilter( + pipelineId = pipelineId, + triggerOnUrl = getUrl(event), + repositoryUrl = repository.url, + includeHost = includeHost + ) + val eventTypeFilter = EventTypeFilter( + pipelineId = pipelineId, + triggerOnEventType = getEventType(), + eventType = eventType + ) + val typeActionFilter = ContainsFilter( + pipelineId = pipelineId, + filterName = "noteTypeAction", + triggerOn = event.getCommentType(), + included = WebhookUtils.convert(includeNoteTypes) + ) + val commentActionFilter = RegexContainFilter( + pipelineId = pipelineId, + filterName = "noteCommentAction", + triggerOn = event.comment.body, + included = WebhookUtils.convert(includeNoteComment) + ) + return listOf(urlFilter, eventTypeFilter, typeActionFilter, commentActionFilter) + } + } + + override fun retrieveParams( + event: T, + projectId: String?, + repository: Repository? + ): Map { + // Github 评论事件公共参数 + val startParams = mutableMapOf() + with(event.comment) { + startParams[PIPELINE_WEBHOOK_NOTE_COMMENT] = body + startParams[PIPELINE_WEBHOOK_NOTE_ID] = id + startParams[BK_REPO_GIT_WEBHOOK_NOTE_COMMENT] = body + startParams[BK_REPO_GIT_WEBHOOK_NOTE_ID] = id + startParams[BK_REPO_GIT_WEBHOOK_NOTE_PROJECT_ID] = projectId.toString() + startParams[BK_REPO_GIT_WEBHOOK_NOTE_AUTHOR_ID] = user.id + startParams[BK_REPO_GIT_WEBHOOK_NOTE_CREATED_AT] = createdAt ?: "" + startParams[BK_REPO_GIT_WEBHOOK_NOTE_UPDATED_AT] = updatedAt ?: "" + startParams[BK_REPO_GIT_WEBHOOK_NOTE_URL] = url ?: "" + startParams[BK_REPO_GIT_WEBHOOK_NOTE_NOTEABLE_TYPE] = event.getCommentType() + } + // 填充其他参数 + startParams.putAll(getCommentParam(event)) + return startParams + } + + /** + * Github 评论事件关联参数,根据具体事件类型进行填充 + */ + fun getCommentParam(event: T): Map +} diff --git a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/comment/GithubCommitCommentTriggerHandler.kt b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/comment/GithubCommitCommentTriggerHandler.kt new file mode 100644 index 00000000000..607358634a5 --- /dev/null +++ b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/comment/GithubCommitCommentTriggerHandler.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.common.webhook.service.code.handler.github.comment + +import com.tencent.devops.common.pipeline.utils.PIPELINE_GIT_COMMIT_AUTHOR +import com.tencent.devops.common.pipeline.utils.PIPELINE_GIT_SHA +import com.tencent.devops.common.pipeline.utils.PIPELINE_GIT_SHA_SHORT +import com.tencent.devops.common.webhook.annotation.CodeWebhookHandler +import com.tencent.devops.common.webhook.pojo.code.github.GithubCommitCommentEvent + +@CodeWebhookHandler +@Suppress("TooManyFunctions") +class GithubCommitCommentTriggerHandler : GithubCommentTriggerHandler { + companion object { + const val SHORT_COMMIT_SHA_LENGTH = 8 + } + + override fun eventClass(): Class { + return GithubCommitCommentEvent::class.java + } + + override fun getCommentParam(event: GithubCommitCommentEvent): Map { + val startParams = mutableMapOf() + with(event.comment) { + startParams[PIPELINE_GIT_COMMIT_AUTHOR] = user.login + startParams[PIPELINE_GIT_SHA] = id + startParams[PIPELINE_GIT_SHA_SHORT] = commitId.substring(0, SHORT_COMMIT_SHA_LENGTH) + } + return startParams + } +} diff --git a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/comment/GithubIssueCommentTriggerHandler.kt b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/comment/GithubIssueCommentTriggerHandler.kt new file mode 100644 index 00000000000..0bb61c6054c --- /dev/null +++ b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/comment/GithubIssueCommentTriggerHandler.kt @@ -0,0 +1,87 @@ +/* + * 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.webhook.service.code.handler.github.comment + +import com.tencent.devops.common.webhook.annotation.CodeWebhookHandler +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_ISSUE_DESCRIPTION +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_ISSUE_ID +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_ISSUE_IID +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_ISSUE_MILESTONE_ID +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_ISSUE_OWNER +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_ISSUE_STATE +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_ISSUE_TITLE +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_ISSUE_URL +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_MR_ASSIGNEE +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_MR_AUTHOR +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_MR_DESCRIPTION +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_MR_ID +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_MR_MILESTONE +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_MR_NUMBER +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_MR_TITLE +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_MR_URL +import com.tencent.devops.common.webhook.pojo.code.github.GithubIssueCommentEvent + +@CodeWebhookHandler +@Suppress("TooManyFunctions") +class GithubIssueCommentTriggerHandler : GithubCommentTriggerHandler { + + override fun eventClass(): Class { + return GithubIssueCommentEvent::class.java + } + + override fun getCommentParam(event: GithubIssueCommentEvent): Map { + val startParams = mutableMapOf() + with(event.issue) { + // 注:直接在Github PR下进行的评论,Github的Webhook消息头为[X-GitHub-Event=issue_comment] + // pullRequest存在则代表直接在Github PR下进行的评论,填充Github PR相关参数,反之填充Issue相关参数 + if (pullRequest != null) { + startParams[BK_REPO_GIT_WEBHOOK_MR_URL] = pullRequest!!.htmlUrl + startParams[BK_REPO_GIT_WEBHOOK_MR_TITLE] = title + startParams[BK_REPO_GIT_WEBHOOK_MR_ID] = id + startParams[BK_REPO_GIT_WEBHOOK_MR_NUMBER] = number + startParams[BK_REPO_GIT_WEBHOOK_MR_DESCRIPTION] = body ?: "" + startParams[BK_REPO_GIT_WEBHOOK_MR_MILESTONE] = milestone?.id ?: "" + startParams[BK_REPO_GIT_WEBHOOK_MR_AUTHOR] = user.login + // 同步Code_Git,基于MR直接评论,noteable_type=Review + assignees?.run { + startParams[BK_REPO_GIT_WEBHOOK_MR_ASSIGNEE] = this.joinToString(",") { it.login } + } + } else { + startParams[BK_REPO_GIT_WEBHOOK_ISSUE_TITLE] = title + startParams[BK_REPO_GIT_WEBHOOK_ISSUE_ID] = id + startParams[BK_REPO_GIT_WEBHOOK_ISSUE_IID] = number + startParams[BK_REPO_GIT_WEBHOOK_ISSUE_DESCRIPTION] = body ?: "" + startParams[BK_REPO_GIT_WEBHOOK_ISSUE_STATE] = state + startParams[BK_REPO_GIT_WEBHOOK_ISSUE_OWNER] = user.login + startParams[BK_REPO_GIT_WEBHOOK_ISSUE_URL] = htmlUrl ?: "" + startParams[BK_REPO_GIT_WEBHOOK_ISSUE_MILESTONE_ID] = milestone?.id ?: "" + } + } + return startParams + } +} diff --git a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/comment/GithubReviewCommentTriggerHandler.kt b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/comment/GithubReviewCommentTriggerHandler.kt new file mode 100644 index 00000000000..25aeb4dce38 --- /dev/null +++ b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/github/comment/GithubReviewCommentTriggerHandler.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.common.webhook.service.code.handler.github.comment + +import com.tencent.devops.common.webhook.annotation.CodeWebhookHandler +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_ID +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_IID +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_SOURCE_BRANCH +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_SOURCE_COMMIT +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_SOURCE_PROJECT_ID +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_STATE +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_TARGET_BRANCH +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_TARGET_COMMIT +import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_REVIEW_TARGET_PROJECT_ID +import com.tencent.devops.common.webhook.pojo.code.github.GithubReviewCommentEvent + +@CodeWebhookHandler +@Suppress("TooManyFunctions") +class GithubReviewCommentTriggerHandler : GithubCommentTriggerHandler { + + override fun eventClass(): Class { + return GithubReviewCommentEvent::class.java + } + + override fun getCommentParam(event: GithubReviewCommentEvent): Map { + val startParams = mutableMapOf() + // review相关信息 + with(event) { + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_STATE] = pullRequest.state + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_ID] = comment.pullRequestReviewId + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_IID] = pullRequest.number + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_SOURCE_BRANCH] = pullRequest.head.ref + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_SOURCE_PROJECT_ID] = pullRequest.head.repo.id + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_SOURCE_COMMIT] = pullRequest.head.sha + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_TARGET_COMMIT] = pullRequest.base.sha + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_TARGET_BRANCH] = pullRequest.base.ref + startParams[BK_REPO_GIT_WEBHOOK_REVIEW_TARGET_PROJECT_ID] = pullRequest.base.repo.id + } + return startParams + } +} diff --git a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/tgit/TGitMrTriggerHandler.kt b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/tgit/TGitMrTriggerHandler.kt index 6889d56cf37..27bd066a950 100644 --- a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/tgit/TGitMrTriggerHandler.kt +++ b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/handler/tgit/TGitMrTriggerHandler.kt @@ -301,6 +301,7 @@ class TGitMrTriggerHandler( startParams[PIPELINE_GIT_EVENT_URL] = event.object_attributes.url ?: "" // 有覆盖风险的上下文做二次确认 + startParams.putIfEmpty(GIT_MR_NUMBER, event.object_attributes.iid.toString()) startParams.putIfEmpty(PIPELINE_GIT_MR_ID, event.object_attributes.id.toString()) startParams.putIfEmpty(PIPELINE_GIT_MR_URL, event.object_attributes.url ?: "") startParams.putIfEmpty(PIPELINE_GIT_MR_IID, event.object_attributes.iid.toString()) diff --git a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/param/GithubWebHookStartParam.kt b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/param/GithubWebHookStartParam.kt index 91389386616..f51dfa3a3d2 100644 --- a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/param/GithubWebHookStartParam.kt +++ b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/param/GithubWebHookStartParam.kt @@ -28,6 +28,7 @@ package com.tencent.devops.common.webhook.service.code.param import com.tencent.devops.common.pipeline.pojo.element.trigger.CodeGithubWebHookTriggerElement +import com.tencent.devops.common.pipeline.utils.PIPELINE_GIT_REPO_ID import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_COMMIT_ID import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_EVENT_TYPE import com.tencent.devops.common.webhook.pojo.code.BK_REPO_GIT_WEBHOOK_EXCLUDE_BRANCHS @@ -60,6 +61,7 @@ class GithubWebHookStartParam : ScmWebhookStartParams?): String { + return if (list.isNullOrEmpty()) { "" } else { - EnvUtils.parseEnv(element.excludeUsers!!, variables) - } - if (element.branchName == null) { - return null + list.joinToString(",") } - params.branchName = EnvUtils.parseEnv(element.branchName!!, variables) - params.eventType = element.eventType - params.excludeBranchName = EnvUtils.parseEnv(element.excludeBranchName ?: "", variables) - params.codeType = CodeType.GITHUB - return params } } diff --git a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/pojo/EventRepositoryCache.kt b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/pojo/EventRepositoryCache.kt index e7a7f140009..b76ba741b55 100644 --- a/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/pojo/EventRepositoryCache.kt +++ b/src/backend/ci/core/common/common-webhook/biz-common-webhook/src/main/kotlin/com/tencent/devops/common/webhook/service/code/pojo/EventRepositoryCache.kt @@ -1,5 +1,6 @@ package com.tencent.devops.common.webhook.service.code.pojo +import com.tencent.devops.common.sdk.github.response.PullRequestResponse import com.tencent.devops.scm.code.p4.api.P4ChangeList import com.tencent.devops.scm.code.p4.api.P4ServerInfo import com.tencent.devops.scm.pojo.GitCommit @@ -20,5 +21,6 @@ data class EventRepositoryCache( var repoAuthUser: String? = null, var p4ChangeFiles: P4ChangeList? = null, var p4ShelveChangeFiles: P4ChangeList? = null, - val serverInfo: P4ServerInfo? = null + var serverInfo: P4ServerInfo? = null, + var githubPrInfo: PullRequestResponse? = null ) diff --git a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/webhook/PipelineBuildWebhookService.kt b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/webhook/PipelineBuildWebhookService.kt index 3ed4f069ed7..33dc4b0f019 100644 --- a/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/webhook/PipelineBuildWebhookService.kt +++ b/src/backend/ci/core/process/biz-process/src/main/kotlin/com/tencent/devops/process/service/webhook/PipelineBuildWebhookService.kt @@ -51,10 +51,15 @@ import com.tencent.devops.common.pipeline.pojo.element.trigger.WebHookTriggerEle import com.tencent.devops.common.webhook.pojo.code.git.GitEvent import com.tencent.devops.common.webhook.pojo.code.git.GitReviewEvent import com.tencent.devops.common.webhook.pojo.code.github.GithubCheckRunEvent +import com.tencent.devops.common.webhook.pojo.code.github.GithubCommitCommentEvent import com.tencent.devops.common.webhook.pojo.code.github.GithubCreateEvent import com.tencent.devops.common.webhook.pojo.code.github.GithubEvent +import com.tencent.devops.common.webhook.pojo.code.github.GithubIssueCommentEvent +import com.tencent.devops.common.webhook.pojo.code.github.GithubIssuesEvent import com.tencent.devops.common.webhook.pojo.code.github.GithubPullRequestEvent import com.tencent.devops.common.webhook.pojo.code.github.GithubPushEvent +import com.tencent.devops.common.webhook.pojo.code.github.GithubReviewCommentEvent +import com.tencent.devops.common.webhook.pojo.code.github.GithubReviewEvent import com.tencent.devops.common.webhook.pojo.code.p4.P4Event import com.tencent.devops.common.webhook.pojo.code.svn.SvnCommitEvent import com.tencent.devops.common.webhook.service.code.loader.WebhookElementParamsRegistrar @@ -176,6 +181,11 @@ abstract class PipelineBuildWebhookService : ApplicationContextAware { GithubCreateEvent.classType -> objectMapper.readValue(body) GithubPullRequestEvent.classType -> objectMapper.readValue(body) GithubCheckRunEvent.classType -> objectMapper.readValue(body) + GithubCommitCommentEvent.classType -> objectMapper.readValue(body) + GithubIssueCommentEvent.classType -> objectMapper.readValue(body) + GithubReviewCommentEvent.classType -> objectMapper.readValue(body) + GithubIssuesEvent.classType -> objectMapper.readValue(body) + GithubReviewEvent.classType -> objectMapper.readValue(body) else -> { logger.info("Github event($eventType) is ignored") return true 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 35f2ae03b57..4bed7304206 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 @@ -18,7 +18,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 ('6e715b411b7e4c35b5944a03b4f488a9', 'GitLab', 'codeGitlabWebHookTrigger', 'codeGitlabWebHookTrigger', '[ \"pipeline\" ]', 'AGENT', '[ \"LINUX\", \"MACOS\", \"WINDOWS\" ]', 'e1bea5430f574f9ea3e0312dc7de9efa', '', 0, 7, NULL, 'Start the pipeline when listening to related events in the GitLab repository', 'Start the pipeline when listening to related events in the GitLab repository', 0, '1.0.0', '/ms/artifactory/api/user/artifactories/file/download?filePath=%2Ffile%2Fpng%2FgitlabTrigger.png&logo=true', NULL, b'1', b'1', b'0', NULL, NULL, b'0', '1.0', '{"repositoryType":{"rule":{},"type":"enum","component":"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":{},"type":"text","label":"Repository","hasAddItem":true,"required":true,"component":"request-selector","searchable":true,"placeholder":"Please select a repository name","default":"","url":"/repository/api/user/repositories/{projectId}/hasPermissionList?permission=USE&repositoryType=CODE_GITLAB&page=1&pageSize=100","paramId":"repositoryHashId","paramName":"aliasName","tools":{"edit":true,"del":false}},"repositoryName":{"rule":{},"type":"text","component":"vuex-input","required":true,"hidden":true,"label":"","placeholder":"Please enter a repository alias","default":""},"branchName":{"rule":{},"type":"text","required":false,"component":"vuex-input","label":"branch name","placeholder":"Defaults to all branches","default":""},"excludeBranchName":{"rule":{},"type":"text","required":false,"component":"vuex-input","label":"Exclude the following target branches","placeholder":"Multiple branches should be separated by commas","default":"","rely":{"operation":"NOT","expression":[{"key":"eventType","value":"TAG_PUSH"}]}},"includeSourceBranchName":{"rule":{},"type":"text","required":false,"component":"vuex-input","label":"Listen to the following source branches","placeholder":"Separate multiple paths with commas","default":"","rely":{"operation":"OR","expression":[{"key":"eventType","value":"MERGE_REQUEST"},{"key":"eventType","value":"MERGE_REQUEST_ACCEPT"}]}},"excludeSourceBranchName":{"rule":{},"type":"text","required":false,"component":"vuex-input","label":"Exclude the following source branches","placeholder":"Separate multiple paths with commas","default":"","rely":{"operation":"OR","expression":[{"key":"eventType","value":"MERGE_REQUEST"},{"key":"eventType","value":"MERGE_REQUEST_ACCEPT"}]}},"tagName":{"rule":{},"type":"text","required":false,"component":"vuex-input","label":"Listen to the following tags","placeholder":"The default is all tags, and multiple tags should be separated by English commas","default":"","rely":{"operation":"AND","expression":[{"key":"eventType","value":"TAG_PUSH"}]}},"excludeTagName":{"rule":{},"type":"text","required":false,"component":"vuex-input","label":"Exclude the following tags","placeholder":"Multiple tags should be separated by English commas","default":"","rely":{"operation":"AND","expression":[{"key":"eventType","value":"TAG_PUSH"}]}},"includePaths":{"rule":{},"type":"text","required":false,"component":"vuex-input","label":"Listen to the following paths","placeholder":"Separate multiple paths with commas","default":"","rely":{"operation":"NOT","expression":[{"key":"eventType","value":"TAG_PUSH"}]}},"excludePaths":{"rule":{},"type":"text","required":false,"component":"vuex-input","label":"Exclude the following paths","placeholder":"Separate multiple paths with commas","default":"","rely":{"operation":"NOT","expression":[{"key":"eventType","value":"TAG_PUSH"}]}},"includeUsers":{"rule":{},"component":"staff-input","required":false,"multiSelect":true,"label":"Includes following people","default":[],"rely":{"operation":"NOT","expression":[{"key":"eventType","value":"TAG_PUSH"}]}},"excludeUsers":{"rule":{},"component":"staff-input","required":false,"multiSelect":true,"label":"Exclude the following people","default":[],"rely":{"operation":"NOT","expression":[{"key":"eventType","value":"TAG_PUSH"}]}},"includeCommitMsg":{"rule":{},"type":"text","required":false,"component":"vuex-input","label":"Includes the following Commit Message","default":"","rely":{"operation":"NOT","expression":[{"key":"eventType","value":"TAG_PUSH"},{"key":"eventType","value":"MERGE_REQUEST_ACCEPT"}]}},"excludeCommitMsg":{"rule":{},"type":"text","required":false,"component":"vuex-input","label":"Exclude the following Commit Messages","default":"","rely":{"operation":"NOT","expression":[{"key":"eventType","value":"TAG_PUSH"},{"key":"eventType","value":"MERGE_REQUEST_ACCEPT"}]}},"eventType":{"rule":{},"type":"text","required":false,"component":"enum-input","label":"Event Type","list":[{"label":"Commit Push Hook","value":"PUSH","tips":"Triggered when there is a new push event to the project. If it is a tag push, it will not be triggered."},{"label":"Tag Push Hook","value":"TAG_PUSH","tips":"Triggered when tags are added or deleted in the project"},{"label":"Merge Request Hook","value":"MERGE_REQUEST","tips":"It will be triggered when a new Merge Request is added to the project"},{"label":"Merge Request Accept Hook","value":"MERGE_REQUEST_ACCEPT","tips":"项目中Merge Request accept时会触发"}],"default":"PUSH"}}', '{}', 'BlueKing', 0, 'system', 'system', '2019-03-04 18:09:39', '2020-04-26 12:16:06', 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 - ('eaa2bfb9f95245b482039f9bebccfcc9', 'GitHub', 'codeGithubWebHookTrigger', 'codeGithubWebHookTrigger', '[ \"pipeline\" ]', 'AGENT', '[ \"LINUX\", \"MACOS\", \"WINDOWS\" ]', 'e1bea5430f574f9ea3e0312dc7de9efa', '', 0, 7, NULL, 'Start the pipeline when listening to related events of the GitHub repository', 'Start the pipeline when listening to related events of the GitHub repository', 0, '1.0.0', '/ms/artifactory/api/user/artifactories/file/download?filePath=%2Ffile%2Fpng%2FgithubTrigger.png&logo=true', NULL, b'1', b'1', b'0', NULL, NULL, b'0', '1.0', '{\"repositoryType\":{\"rule\":{},\"type\":\"enum\",\"component\":\"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\":{},\"type\":\"text\",\"label\":\"\",\"hasAddItem\":true,\"component\":\"request-selector\",\"searchable\":true,\"placeholder\":\"Please select a repository name\",\"required\":true,\"default\":\"\",\"url\":\"/repository/api/user/repositories/{projectId}/hasPermissionList?permission=USE&repositoryType=GITHUB&page=1&pageSize=100\",\"paramId\":\"repositoryHashId\",\"paramName\":\"aliasName\",\"tools\":{\"edit\":true,\"del\":false},\"list\":[]},\"repositoryName\":{\"rule\":{},\"type\":\"text\",\"component\":\"vuex-input\",\"required\":true,\"hidden\":true,\"label\":\"\",\"placeholder\":\"Please enter a repository alias\",\"default\":\"\"},\"branchName\":{\"rule\":{},\"type\":\"text\",\"required\":false,\"component\":\"vuex-input\",\"label\":\"Listen to the following branches\",\"placeholder\":\"The default is all branches, and multiple branches should be separated by commas\",\"default\":\"\"},\"excludeBranchName\":{\"rule\":{},\"type\":\"text\",\"required\":false,\"component\":\"vuex-input\",\"label\":\"Exclude the following branches\",\"placeholder\":\"Multiple branches should be separated by commas\",\"default\":\"\"},\"excludeUsers\":{\"rule\":{},\"component\":\"vuex-input\",\"required\":false,\"label\":\"Exclude the following people\",\"default\":\"\"},\"eventType\":{\"rule\":{},\"type\":\"text\",\"required\":false,\"component\":\"enum-input\",\"label\":\"Event Type\",\"list\":[{\"label\":\"Commit Push Hook\",\"value\":\"PUSH\",\"tips\":\"Triggered when there is a new push event to the project. If it is a tag push, it will not be triggered.\"},{\"label\":\"Create Branch Or Tag\",\"value\":\"CREATE\",\"tips\":\"Triggered when a new branch or tag is added to the project\"},{\"label\":\"Pull Request Hook\",\"value\":\"PULL_REQUEST\",\"tips\":\"Triggered when a Pull Request is added to the project\"}],\"default\":\"PUSH\"}}', '{}', 'BlueKing', 2, 'system', 'system', '2019-03-04 18:09:39', '2020-04-26 12:17:06', 0); + ('eaa2bfb9f95245b482039f9bebccfcc9', 'GitHub', 'codeGithubWebHookTrigger', 'codeGithubWebHookTrigger', '[ \"pipeline\" ]', 'AGENT', '[ \"LINUX\", \"MACOS\", \"WINDOWS\" ]', 'e1bea5430f574f9ea3e0312dc7de9efa', '', 0, 7, NULL, 'Start the pipeline when listening to related events of the GitHub repository', 'Start the pipeline when listening to related events of the GitHub repository', 0, '1.0.0', '/ms/artifactory/api/user/artifactories/file/download?filePath=%2Ffile%2Fpng%2FgithubTrigger.png&logo=true', NULL, b'1', b'1', b'0', NULL, NULL, b'0', '1.0', '{ "repositoryType": { "rule": {}, "type": "enum", "component": "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": {}, "type": "text", "label": "", "hasAddItem": true, "component": "request-selector", "searchable": true, "placeholder": "Please select a repository name", "required": true, "default": "", "url": "/repository/api/user/repositories/{projectId}/hasPermissionList?permission=USE&repositoryType=GITHUB&page=1&pageSize=100", "paramId": "repositoryHashId", "paramName": "aliasName", "tools": { "edit": true, "del": false }, "list": [] }, "repositoryName": { "rule": {}, "type": "text", "component": "vuex-input", "required": true, "hidden": true, "label": "", "placeholder": "Please enter a repository alias", "default": "" }, "branchName": { "rule": {}, "type": "text", "required": false, "component": "vuex-input", "label": "Listen to the following branches", "placeholder": "The default is all branches, and multiple branches should be separated by commas", "default": "", "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "PUSH" }, { "key": "eventType", "value": "CREATE" }, { "key": "eventType", "value": "PULL_REQUEST" } ] } }, "excludeBranchName": { "rule": {}, "type": "text", "required": false, "component": "vuex-input", "label": "Exclude the following branches", "placeholder": "Multiple branches should be separated by commas", "default": "", "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "PUSH" }, { "key": "eventType", "value": "CREATE" }, { "key": "eventType", "value": "PULL_REQUEST" } ] } }, "excludeUsers": { "rule": {}, "component": "vuex-input", "required": false, "label": "Exclude the following people", "default": "", "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "PUSH" }, { "key": "eventType", "value": "CREATE" }, { "key": "eventType", "value": "PULL_REQUEST" } ] } }, "eventType": { "rule": {}, "type": "text", "required": false, "component": "enum-input", "label": "Event Type", "list": [ { "label": "Commit Push Hook", "value": "PUSH", "tips": "Triggered when there is a new push event to the project. If it is a tag push, it will not be triggered." }, { "label": "Create Branch Or Tag", "value": "CREATE", "tips": "Triggered when a new branch or tag is added to the project" }, { "label": "Pull Request Hook", "value": "PULL_REQUEST", "tips": "Triggered when a Pull Request is added to the project" }, { "label": "Code Review Hook", "value": "REVIEW", "tips": "Triggered when there is a code review event to the project" }, { "label": "Issue Hook", "value": "ISSUES", "tips": "Triggered when there is a issues event to the project" }, { "label": "Note Hook", "value": "NOTE", "tips": "Triggered when there is a note event to the project" } ], "default": "PUSH" }, "includeIssueAction": { "label": "Listen to the following action", "type": "selector", "component": "selector", "multiSelect": true, "list": [ { "id": "open", "name": "open" }, { "id": "close", "name": "close" }, { "id": "reopen", "name": "reopen" }, { "id": "update", "name": "update" } ], "rely": { "operation": "AND", "expression": [ { "key": "eventType", "value": "ISSUES" } ] } }, "includeCrState": { "label": "Listen to the following state", "component": "selector", "multiSelect": true, "list": [ { "id": "approving", "name": "approving" }, { "id": "approved", "name": "approved" }, { "id": "change_denied", "name": "change denied" }, { "id": "change_required", "name": "request changes" } ], "rely": { "operation": "AND", "expression": [ { "key": "eventType", "value": "REVIEW" } ] } }, "includeNoteComment": { "rule": {}, "type": "vuex-input", "required": false, "component": "vuex-input", "label": "Listening to the following comment", "desc": "", "placeholder": "Separate multiple comments with commas", "default": "", "rely": { "operation": "AND", "expression": [ { "key": "eventType", "value": "NOTE" } ] } }, "includeNoteTypes": { "label": "Listening to the following types of comments", "component": "selector", "multiSelect": true, "list": [ { "id": "Commit", "name": "Providing comments on commit" }, { "id": "Review", "name": "Providing comments on reviews" }, { "id": "Issue", "name": "Providing comments on issue" } ], "rely": { "operation": "AND", "expression": [ { "key": "eventType", "value": "NOTE" } ] } } }', '{}', 'BlueKing', 2, 'system', 'system', '2019-03-04 18:09:39', '2020-04-26 12:17:06', 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 ('24425d3fa0b645dc8ab23013e9f1df5e','TGit','codeTGitWebHookTrigger','codeTGitWebHookTrigger','[ \"pipeline\" ]','AGENT','[ \"LINUX\", \"MACOS\", \"WINDOWS\" ]','e1bea5430f574f9ea3e0312dc7de9efa','',0,7,NULL,'Start the pipeline when listening to related events of the TGit repository','Start the pipeline when listening to related events of the TGit repository',0,'1.0.0','/ms/artifactory/api/user/artifactories/file/download?filePath=%2Ffile%2Fpng%2FtgitTrigger.png&logo=true',NULL,b'1',b'1',b'0',NULL,NULL,b'0','1.1','{ "input": { "repositoryType": { "rule": {}, "type": "enum-input", "component": "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", "component": "request-selector", "searchable": true, "placeholder": "Please select a repository name", "required": true, "default": "", "url": "/repository/api/user/repositories/{projectId}/hasPermissionList?permission=USE&repositoryType=CODE_TGIT&page=1&pageSize=100", "paramId": "repositoryHashId", "paramName": "aliasName", "tools": { "edit": true, "del": false }, "rely": { "operation": "OR", "expression": [ { "key": "repositoryType", "value": "ID" } ] } }, "repositoryName": { "rule": {}, "component": "vuex-input", "type": "vuex-input", "required": true, "label": "", "placeholder": "Please enter a repository alias", "default": "", "rely": { "operation": "AND", "expression": [ { "key": "repositoryType", "value": "NAME" } ] } }, "eventType": { "rule": {}, "required": false, "component": "enum-input", "type": "enum-input", "label": "Event Type", "list": [ { "label": "Commit Push Hook", "value": "PUSH", "tips": "Triggered when there is a new push event to the project. If it is a tag push, it will not be triggered." }, { "label": "Tag Push Hook", "value": "TAG_PUSH", "tips": "Triggered when tags are added or deleted in the project" }, { "label": "Merge Request Hook", "value": "MERGE_REQUEST", "tips": "Triggered when a Merge Request is added to the project" }, { "label": "Merge Request Accept Hook", "value": "MERGE_REQUEST_ACCEPT", "tips": "It will be triggered when Merge Request accept in the project" }, { "label": "Issue Hook", "value": "ISSUES", "tips": "Triggered when there is a issues event to the project" }, { "label": "Note Hook", "value": "NOTE", "tips": "Triggered when there is a note event to the project" } ], "default": "PUSH" }, "branchName": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Listen to the following target branches", "placeholder": "The default is all branches, and multiple branches should be separated by commas", "default": "", "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "PUSH" }, { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "excludeBranchName": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Exclude the following target branches", "placeholder": "Multiple branches should be separated by commas", "default": "", "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "PUSH" }, { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "includeSourceBranchName": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Listen to the following branches", "placeholder": "Separate multiple paths with commas", "default": "", "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "excludeSourceBranchName": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Exclude the following source branches", "placeholder": "Separate multiple paths with commas", "default": "", "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "tagName": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Listen to the following tags", "placeholder": "The default is all tags, and multiple tags should be separated by commas", "default": "", "rely": { "operation": "AND", "expression": [ { "key": "eventType", "value": "TAG_PUSH" } ] } }, "excludeTagName": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Exclude the following tags", "placeholder": "Multiple tags should be separated by commas", "default": "", "rely": { "operation": "AND", "expression": [ { "key": "eventType", "value": "TAG_PUSH" } ] } }, "fromBranches": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Listen to the following source branches", "desc": "Tags created by the Git client do not contain information about the branch they were created from. In this case, tags created cannot be used to listen to the target branch", "placeholder": "Multiple branches should be separated by commas", "default": "", "rely": { "operation": "AND", "expression": [ { "key": "eventType", "value": "TAG_PUSH" } ] } }, "pathFilterType": { "rule": {}, "type": "enum-input", "component": "enum-input", "required": true, "label": "Path filtering type", "list": [ { "value": "NamePrefixFilter", "label": "Matching by Path Prefix" }, { "value": "RegexBasedFilter", "label": "Matching by Wildcard" } ], "default": "NamePrefixFilter", "desc": "", "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "PUSH" }, { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "includePaths": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Listen to the following paths", "placeholder": "Separate multiple paths with commas", "default": "", "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "PUSH" }, { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "excludePaths": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Exclude the following paths", "placeholder": "Separate multiple paths with commas", "default": "", "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "PUSH" }, { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "includeUsers": { "rule": {}, "type": "staff-input", "component": "staff-input", "required": false, "label": "Includes following people", "default": [], "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "PUSH" }, { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "excludeUsers": { "rule": {}, "type": "staff-input", "component": "staff-input", "required": false, "label": "Exclude the following people", "default": [], "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "PUSH" }, { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "enableCheck": { "rule": {}, "type": "atom-checkbox", "component": "atom-checkbox", "required": false, "text": "Write commit check", "default": true, "hidden": false, "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "block": { "rule": {}, "type": "atom-checkbox", "component": "atom-checkbox", "required": false, "text": "Lock Commit", "default": false, "hidden": false, "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "enableCheck", "value": true } ] } }, "webhookQueue": { "rule": {}, "type": "atom-checkbox", "component": "atom-checkbox", "required": false, "text": "When the MR has the same source and target branches, only the latest triggered task will be kept in the waiting queue", "default": false, "hidden": false, "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "MERGE_REQUEST" } ] } }, "includeNoteTypes": { "label": "Listening to the following types of comments", "type": "selector", "component": "selector", "optionsConf": { "searchable": true, "multiple": true }, "options": [ { "id": "Commit", "name": "Providing comments on commit" }, { "id": "Review", "name": "Providing comments on reviews" }, { "id": "Issue", "name": "Providing comments on issue" } ], "rely": { "operation": "AND", "expression": [ { "key": "eventType", "value": "NOTE" } ] } }, "includeNoteComment": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Listening to the following comment", "desc": "", "placeholder": "Separate multiple comments with commas", "default": "", "rely": { "operation": "AND", "expression": [ { "key": "eventType", "value": "NOTE" } ] } }, "includeIssueAction": { "label": "Listen to the following action", "type": "selector", "component": "selector", "optionsConf": { "searchable": true, "multiple": true }, "options": [ { "id": "open", "name": "open" }, { "id": "close", "name": "close" }, { "id": "reopen", "name": "reopen" }, { "id": "update", "name": "update" } ], "rely": { "operation": "AND", "expression": [ { "key": "eventType", "value": "ISSUES" } ] } }, "enableThirdFilter": { "rule": {}, "type": "atom-checkbox", "component": "atom-checkbox", "required": false, "text": "Enable third-party filtering", "default": false, "hidden": true }, "thirdUrl": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Interface address", "desc": "", "placeholder": "Please enter th{ "input": { "repositoryType": { "rule": {}, "type": "enum-input", "component": "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", "component": "request-selector", "searchable": true, "placeholder": "Please select a repository name", "required": true, "default": "", "url": "/repository/api/user/repositories/{projectId}/hasPermissionList?permission=USE&repositoryType=CODE_TGIT&page=1&pageSize=100", "paramId": "repositoryHashId", "paramName": "aliasName", "tools": { "edit": true, "del": false }, "rely": { "operation": "OR", "expression": [ { "key": "repositoryType", "value": "ID" } ] } }, "repositoryName": { "rule": {}, "component": "vuex-input", "type": "vuex-input", "required": true, "label": "", "placeholder": "Please enter a repository alias", "default": "", "rely": { "operation": "AND", "expression": [ { "key": "repositoryType", "value": "NAME" } ] } }, "eventType": { "rule": {}, "required": false, "component": "enum-input", "type": "enum-input", "label": "Event Type", "list": [ { "label": "Commit Push Hook", "value": "PUSH", "tips": "Triggered when there is a new push event to the project. If it is a tag push, it will not be triggered." }, { "label": "Tag Push Hook", "value": "TAG_PUSH", "tips": "Triggered when tags are added or deleted in the project" }, { "label": "Merge Request Hook", "value": "MERGE_REQUEST", "tips": "Triggered when a Merge Request is added to the project" }, { "label": "Merge Request Accept Hook", "value": "MERGE_REQUEST_ACCEPT", "tips": "It will be triggered when Merge Request accept in the project" }, { "label": "Issue Hook", "value": "ISSUES", "tips": "Triggered when there is a issues event to the project" }, { "label": "Note Hook", "value": "NOTE", "tips": "Triggered when there is a note event to the project" } ], "default": "PUSH" }, "branchName": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Listen to the following target branches", "placeholder": "The default is all branches, and multiple branches should be separated by commas", "default": "", "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "PUSH" }, { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "excludeBranchName": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Exclude the following target branches", "placeholder": "Multiple branches should be separated by commas", "default": "", "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "PUSH" }, { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "includeSourceBranchName": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Listen to the following branches", "placeholder": "Separate multiple paths with commas", "default": "", "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "excludeSourceBranchName": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Exclude the following source branches", "placeholder": "Separate multiple paths with commas", "default": "", "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "tagName": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Listen to the following tags", "placeholder": "The default is all tags, and multiple tags should be separated by commas", "default": "", "rely": { "operation": "AND", "expression": [ { "key": "eventType", "value": "TAG_PUSH" } ] } }, "excludeTagName": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Exclude the following tags", "placeholder": "Multiple tags should be separated by commas", "default": "", "rely": { "operation": "AND", "expression": [ { "key": "eventType", "value": "TAG_PUSH" } ] } }, "fromBranches": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Listen to the following source branches", "desc": "Tags created by the Git client do not contain information about the branch they were created from. In this case, tags created cannot be used to listen to the target branch", "placeholder": "Multiple branches should be separated by commas", "default": "", "rely": { "operation": "AND", "expression": [ { "key": "eventType", "value": "TAG_PUSH" } ] } }, "pathFilterType": { "rule": {}, "type": "enum-input", "component": "enum-input", "required": true, "label": "Path filtering type", "list": [ { "value": "NamePrefixFilter", "label": "Matching by Path Prefix" }, { "value": "RegexBasedFilter", "label": "Matching by Wildcard" } ], "default": "NamePrefixFilter", "desc": "", "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "PUSH" }, { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "includePaths": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Listen to the following paths", "placeholder": "Separate multiple paths with commas", "default": "", "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "PUSH" }, { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "excludePaths": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Exclude the following paths", "placeholder": "Separate multiple paths with commas", "default": "", "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "PUSH" }, { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "includeUsers": { "rule": {}, "type": "staff-input", "component": "staff-input", "required": false, "label": "Includes following people", "default": [], "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "PUSH" }, { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "excludeUsers": { "rule": {}, "type": "staff-input", "component": "staff-input", "required": false, "label": "Exclude the following people", "default": [], "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "PUSH" }, { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "enableCheck": { "rule": {}, "type": "atom-checkbox", "component": "atom-checkbox", "required": false, "text": "Write commit check", "default": true, "hidden": false, "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "eventType", "value": "MERGE_REQUEST_ACCEPT" } ] } }, "block": { "rule": {}, "type": "atom-checkbox", "component": "atom-checkbox", "required": false, "text": "Lock Commit", "default": false, "hidden": false, "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "MERGE_REQUEST" }, { "key": "enableCheck", "value": true } ] } }, "webhookQueue": { "rule": {}, "type": "atom-checkbox", "component": "atom-checkbox", "required": false, "text": "When the MR has the same source and target branches, only the latest triggered task will be kept in the waiting queue", "default": false, "hidden": false, "rely": { "operation": "OR", "expression": [ { "key": "eventType", "value": "MERGE_REQUEST" } ] } }, "includeNoteTypes": { "label": "Listening to the following types of comments", "type": "selector", "component": "selector", "optionsConf": { "searchable": true, "multiple": true }, "options": [ { "id": "Commit", "name": "Providing comments on commit" }, { "id": "Review", "name": "Providing comments on reviews" }, { "id": "Issue", "name": "Providing comments on issue" } ], "rely": { "operation": "AND", "expression": [ { "key": "eventType", "value": "NOTE" } ] } }, "includeNoteComment": { "rule": {}, "required": false, "type": "vuex-input", "component": "vuex-input", "label": "Listening to the following comment", "desc": "", "placeholder": "Separate multiple comments with commas", "default": "", "rely": { "operation": "AND", "expression": [ { "key": "eventType", "value": "NOTE" } ] } }, "includeIssueAction": { "label": "Listen to the following action", "type": "selector", "component": "selector", "optionsConf": { "searchable": true, "multiple": true }, "options": [ { "id": "open", "name": "open" }, { "id": "close", "name": "close" }, { "id": "reopen", "name": "reopen" }, { "id": "update", "name": "update" } ], "rely": { "operation": "AND", "expression": [ { "key": "eventType", "value": "ISSUES" } ] } } } }','{}','BlueKing','2','system','system','2020-08-29 12:18:20','2020-09-03 10:43:18', 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