mirror of
https://github.com/gitbucket/gitbucket.git
synced 2025-11-04 20:45:58 +01:00
add webhook pull_request synchronize action
This commit is contained in:
@@ -24,6 +24,7 @@ import api._
|
||||
class RepositoryViewerController extends RepositoryViewerControllerBase
|
||||
with RepositoryService with AccountService with ActivityService with IssuesService with WebHookService with CommitsService
|
||||
with ReadableUsersAuthenticator with ReferrerAuthenticator with CollaboratorsAuthenticator with PullRequestService with CommitStatusService
|
||||
with WebHookPullRequestService
|
||||
|
||||
|
||||
/**
|
||||
@@ -31,7 +32,8 @@ class RepositoryViewerController extends RepositoryViewerControllerBase
|
||||
*/
|
||||
trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
self: RepositoryService with AccountService with ActivityService with IssuesService with WebHookService with CommitsService
|
||||
with ReadableUsersAuthenticator with ReferrerAuthenticator with CollaboratorsAuthenticator with PullRequestService with CommitStatusService =>
|
||||
with ReadableUsersAuthenticator with ReferrerAuthenticator with CollaboratorsAuthenticator with PullRequestService with CommitStatusService
|
||||
with WebHookPullRequestService =>
|
||||
|
||||
ArchiveCommand.registerFormat("zip", new ZipFormat)
|
||||
ArchiveCommand.registerFormat("tar.gz", new TgzFormat)
|
||||
@@ -562,6 +564,7 @@ trait RepositoryViewerControllerBase extends ControllerBase {
|
||||
closeIssuesFromMessage(message, loginAccount.userName, repository.owner, repository.name)
|
||||
|
||||
// call web hook
|
||||
callPullRequestWebHookByRequestBranch("synchronize", repository, branch, context.baseUrl, loginAccount)
|
||||
val commit = new JGitUtil.CommitInfo(JGitUtil.getRevCommitFromId(git, commitId))
|
||||
callWebHookOf(repository.owner, repository.name, "push") {
|
||||
getAccountByUserName(repository.owner).map{ ownerAccount =>
|
||||
|
||||
@@ -2,7 +2,7 @@ package service
|
||||
|
||||
import model.Profile._
|
||||
import profile.simple._
|
||||
import model.{PullRequest, Issue}
|
||||
import model.{PullRequest, Issue, WebHook, Account}
|
||||
import util.JGitUtil
|
||||
|
||||
trait PullRequestService { self: IssuesService =>
|
||||
|
||||
@@ -116,6 +116,40 @@ trait WebHookPullRequestService extends WebHookService {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def getPullRequestsByRequestForWebhook(userName:String, repositoryName:String, branch:String)
|
||||
(implicit s: Session): Map[(Issue, PullRequest, Account, Account), List[WebHook]] =
|
||||
(for{
|
||||
is <- Issues if is.closed === false.bind
|
||||
pr <- PullRequests if pr.byPrimaryKey(is.userName, is.repositoryName, is.issueId)
|
||||
if pr.requestUserName === userName.bind
|
||||
if pr.requestRepositoryName === repositoryName.bind
|
||||
if pr.requestBranch === branch.bind
|
||||
bu <- Accounts if bu.userName === pr.userName
|
||||
ru <- Accounts if ru.userName === pr.requestUserName
|
||||
wh <- WebHooks if wh.byRepository(is.userName , is.repositoryName)
|
||||
} yield {
|
||||
((is, pr, bu, ru), wh)
|
||||
}).list.groupBy(_._1).mapValues(_.map(_._2))
|
||||
|
||||
def callPullRequestWebHookByRequestBranch(action: String, requestRepository: RepositoryService.RepositoryInfo, requestBranch: String, baseUrl: String, sender: model.Account)(implicit s: Session, context:JsonFormat.Context): Unit = {
|
||||
import WebHookService._
|
||||
for{
|
||||
((issue, pullRequest, baseOwner, headOwner), webHooks) <- getPullRequestsByRequestForWebhook(requestRepository.owner, requestRepository.name, requestBranch)
|
||||
baseRepo <- getRepository(pullRequest.userName, pullRequest.repositoryName, baseUrl)
|
||||
} yield {
|
||||
val payload = WebHookPullRequestPayload(
|
||||
action = action,
|
||||
issue = issue,
|
||||
pullRequest = pullRequest,
|
||||
headRepository = requestRepository,
|
||||
headOwner = headOwner,
|
||||
baseRepository = baseRepo,
|
||||
baseOwner = baseOwner,
|
||||
sender = sender)
|
||||
callWebHook("pull_request", webHooks, payload)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trait WebHookIssueCommentService extends WebHookPullRequestService {
|
||||
|
||||
@@ -97,7 +97,8 @@ import scala.collection.JavaConverters._
|
||||
|
||||
class CommitLogHook(owner: String, repository: String, pusher: String, baseUrl: String)(implicit session: Session)
|
||||
extends PostReceiveHook with PreReceiveHook
|
||||
with RepositoryService with AccountService with IssuesService with ActivityService with PullRequestService with WebHookService {
|
||||
with RepositoryService with AccountService with IssuesService with ActivityService with PullRequestService with WebHookService
|
||||
with WebHookPullRequestService {
|
||||
|
||||
private val logger = LoggerFactory.getLogger(classOf[CommitLogHook])
|
||||
private var existIds: Seq[String] = Nil
|
||||
@@ -121,6 +122,7 @@ class CommitLogHook(owner: String, repository: String, pusher: String, baseUrl:
|
||||
val pushedIds = scala.collection.mutable.Set[String]()
|
||||
commands.asScala.foreach { command =>
|
||||
logger.debug(s"commandType: ${command.getType}, refName: ${command.getRefName}")
|
||||
implicit val apiContext = api.JsonFormat.Context(baseUrl)
|
||||
val refName = command.getRefName.split("/")
|
||||
val branchName = refName.drop(2).mkString("/")
|
||||
val commits = if (refName(1) == "tags") {
|
||||
@@ -137,8 +139,10 @@ class CommitLogHook(owner: String, repository: String, pusher: String, baseUrl:
|
||||
countIssue(IssueSearchCondition(state = "open"), false, owner -> repository) +
|
||||
countIssue(IssueSearchCondition(state = "closed"), false, owner -> repository)
|
||||
|
||||
val repositoryInfo = getRepository(owner, repository, baseUrl).get
|
||||
|
||||
// Extract new commit and apply issue comment
|
||||
val defaultBranch = getRepository(owner, repository, baseUrl).get.repository.defaultBranch
|
||||
val defaultBranch = repositoryInfo.repository.defaultBranch
|
||||
val newCommits = commits.flatMap { commit =>
|
||||
if (!existIds.contains(commit.id) && !pushedIds.contains(commit.id)) {
|
||||
if (issueCount > 0) {
|
||||
@@ -175,16 +179,17 @@ class CommitLogHook(owner: String, repository: String, pusher: String, baseUrl:
|
||||
ReceiveCommand.Type.UPDATE |
|
||||
ReceiveCommand.Type.UPDATE_NONFASTFORWARD =>
|
||||
updatePullRequests(owner, repository, branchName)
|
||||
getAccountByUserName(pusher).map{ pusherAccount =>
|
||||
callPullRequestWebHookByRequestBranch("synchronize", repositoryInfo, branchName, baseUrl, pusherAccount)
|
||||
}
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
|
||||
// call web hook
|
||||
implicit val apiContext = api.JsonFormat.Context(baseUrl)
|
||||
callWebHookOf(owner, repository, "push"){
|
||||
for(pusherAccount <- getAccountByUserName(pusher);
|
||||
ownerAccount <- getAccountByUserName(owner);
|
||||
repositoryInfo <- getRepository(owner, repository, baseUrl)) yield {
|
||||
ownerAccount <- getAccountByUserName(owner)) yield {
|
||||
WebHookPushPayload(git, pusherAccount, command.getRefName, repositoryInfo, newCommits, ownerAccount)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,11 +6,6 @@ import model._
|
||||
|
||||
class AccessTokenServiceSpec extends Specification with ServiceSpecBase {
|
||||
|
||||
def generateNewAccount(name:String)(implicit s:Session):Account = {
|
||||
AccountService.createAccount(name, name, name, s"${name}@example.com", false, None)
|
||||
AccountService.getAccountByUserName(name).get
|
||||
}
|
||||
|
||||
"AccessTokenService" should {
|
||||
"generateAccessToken" in { withTestDB { implicit session =>
|
||||
AccessTokenService.generateAccessToken("root", "note") must be like{
|
||||
|
||||
@@ -6,10 +6,6 @@ import model.Profile._
|
||||
import profile.simple._
|
||||
class CommitStatusServiceSpec extends Specification with ServiceSpecBase with CommitStatusService
|
||||
with RepositoryService with AccountService{
|
||||
def generateNewAccount(name:String)(implicit s:Session):Account = {
|
||||
createAccount(name, name, name, s"${name}@example.com", false, None)
|
||||
getAccountByUserName(name).get
|
||||
}
|
||||
val now = new java.util.Date()
|
||||
val fixture1 = CommitStatus(
|
||||
userName = "root",
|
||||
|
||||
@@ -5,10 +5,6 @@ import model._
|
||||
import model.Profile._
|
||||
import profile.simple._
|
||||
class RepositoryServiceSpec extends Specification with ServiceSpecBase with RepositoryService with AccountService{
|
||||
def generateNewAccount(name:String)(implicit s:Session):Account = {
|
||||
createAccount(name, name, name, s"${name}@example.com", false, None)
|
||||
getAccountByUserName(name).get
|
||||
}
|
||||
"RepositoryService" should {
|
||||
"renameRepository can rename CommitState" in { withTestDB { implicit session =>
|
||||
val tester = generateNewAccount("tester")
|
||||
|
||||
@@ -8,6 +8,7 @@ import java.sql.DriverManager
|
||||
import org.apache.commons.io.FileUtils
|
||||
import scala.util.Random
|
||||
import java.io.File
|
||||
import model._
|
||||
|
||||
trait ServiceSpecBase {
|
||||
|
||||
@@ -24,4 +25,41 @@ trait ServiceSpecBase {
|
||||
}
|
||||
}
|
||||
|
||||
def generateNewAccount(name:String)(implicit s:Session):Account = {
|
||||
AccountService.createAccount(name, name, name, s"${name}@example.com", false, None)
|
||||
AccountService.getAccountByUserName(name).get
|
||||
}
|
||||
|
||||
lazy val dummyService = new RepositoryService with AccountService with IssuesService with PullRequestService (){}
|
||||
|
||||
def generateNewUserWithDBRepository(userName:String, repositoryName:String)(implicit s:Session):Account = {
|
||||
val ac = generateNewAccount(userName)
|
||||
dummyService.createRepository(repositoryName, userName, None, false)
|
||||
ac
|
||||
}
|
||||
def generateNewPullRequest(base:String, request:String)(implicit s:Session):(Issue, PullRequest) = {
|
||||
val Array(baseUserName, baseRepositoryName, baesBranch)=base.split("/")
|
||||
val Array(requestUserName, requestRepositoryName, requestBranch)=request.split("/")
|
||||
val issueId = dummyService.createIssue(
|
||||
owner = baseUserName,
|
||||
repository = baseRepositoryName,
|
||||
loginUser = requestUserName,
|
||||
title = "issue title",
|
||||
content = None,
|
||||
assignedUserName = None,
|
||||
milestoneId = None,
|
||||
isPullRequest = true)
|
||||
|
||||
dummyService.createPullRequest(
|
||||
originUserName = baseUserName,
|
||||
originRepositoryName = baseRepositoryName,
|
||||
issueId = issueId,
|
||||
originBranch = baesBranch,
|
||||
requestUserName = requestUserName,
|
||||
requestRepositoryName = requestRepositoryName,
|
||||
requestBranch = requestBranch,
|
||||
commitIdFrom = baesBranch,
|
||||
commitIdTo = requestBranch)
|
||||
dummyService.getPullRequest(baseUserName, baseRepositoryName, issueId).get
|
||||
}
|
||||
}
|
||||
|
||||
43
src/test/scala/service/WebHookServiceSpec.scala
Normal file
43
src/test/scala/service/WebHookServiceSpec.scala
Normal file
@@ -0,0 +1,43 @@
|
||||
package service
|
||||
|
||||
import org.specs2.mutable.Specification
|
||||
import java.util.Date
|
||||
import model._
|
||||
|
||||
class WebHookServiceSpec extends Specification with ServiceSpecBase {
|
||||
lazy val service = new WebHookPullRequestService with AccountService with RepositoryService with PullRequestService with IssuesService
|
||||
|
||||
"WebHookPullRequestService.getPullRequestsByRequestForWebhook" should {
|
||||
"find from request branch" in { withTestDB { implicit session =>
|
||||
val user1 = generateNewUserWithDBRepository("user1","repo1")
|
||||
val user2 = generateNewUserWithDBRepository("user2","repo2")
|
||||
val user3 = generateNewUserWithDBRepository("user3","repo3")
|
||||
val (issue1, pullreq1) = generateNewPullRequest("user1/repo1/master1", "user2/repo2/master2")
|
||||
val (issue3, pullreq3) = generateNewPullRequest("user3/repo3/master3", "user2/repo2/master2")
|
||||
val (issue32, pullreq32) = generateNewPullRequest("user3/repo3/master32", "user2/repo2/master2")
|
||||
generateNewPullRequest("user2/repo2/master2", "user1/repo1/master2")
|
||||
service.addWebHookURL("user1", "repo1", "webhook1-1")
|
||||
service.addWebHookURL("user1", "repo1", "webhook1-2")
|
||||
service.addWebHookURL("user2", "repo2", "webhook2-1")
|
||||
service.addWebHookURL("user2", "repo2", "webhook2-2")
|
||||
service.addWebHookURL("user3", "repo3", "webhook3-1")
|
||||
service.addWebHookURL("user3", "repo3", "webhook3-2")
|
||||
|
||||
service.getPullRequestsByRequestForWebhook("user1","repo1","master1") must_== Map.empty
|
||||
|
||||
var r = service.getPullRequestsByRequestForWebhook("user2","repo2","master2").mapValues(_.map(_.url).toSet)
|
||||
r.size must_== 3
|
||||
r((issue1, pullreq1, user1, user2)) must_== Set("webhook1-1","webhook1-2")
|
||||
r((issue3, pullreq3, user3, user2)) must_== Set("webhook3-1","webhook3-2")
|
||||
r((issue32, pullreq32, user3, user2)) must_== Set("webhook3-1","webhook3-2")
|
||||
|
||||
// when closed, it not founds.
|
||||
service.updateClosed("user1","repo1",issue1.issueId, true)
|
||||
|
||||
var r2 = service.getPullRequestsByRequestForWebhook("user2","repo2","master2").mapValues(_.map(_.url).toSet)
|
||||
r2.size must_== 2
|
||||
r2((issue3, pullreq3, user3, user2)) must_== Set("webhook3-1","webhook3-2")
|
||||
r2((issue32, pullreq32, user3, user2)) must_== Set("webhook3-1","webhook3-2")
|
||||
} }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user