add webhook pull_request synchronize action

This commit is contained in:
nazoking
2015-02-27 13:36:50 +09:00
parent 579ed19949
commit 597f86dc7b
9 changed files with 130 additions and 20 deletions

View File

@@ -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 =>

View File

@@ -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 =>

View File

@@ -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 {

View File

@@ -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)
}
}

View File

@@ -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{

View File

@@ -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",

View File

@@ -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")

View File

@@ -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
}
}

View 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")
} }
}
}