(refs #74)Add "Test Hook" button.

This commit is contained in:
takezoe
2013-09-18 20:10:53 +09:00
parent aa8da1b046
commit d8698d02b7
4 changed files with 106 additions and 42 deletions

View File

@@ -2,10 +2,15 @@ package app
import service._ import service._
import util.Directory._ import util.Directory._
import util.{UsersAuthenticator, OwnerAuthenticator} import util.{JGitUtil, UsersAuthenticator, OwnerAuthenticator}
import jp.sf.amateras.scalatra.forms._ import jp.sf.amateras.scalatra.forms._
import org.apache.commons.io.FileUtils import org.apache.commons.io.FileUtils
import org.scalatra.FlashMapSupport import org.scalatra.FlashMapSupport
import service.WebHookService.{WebHookRepository, WebHookUser, WebHookCommit, WebHookPayload}
import org.eclipse.jgit.diff.DiffEntry
import scala.collection.mutable.ListBuffer
import org.eclipse.jgit.revwalk.RevCommit
import util.JGitUtil.CommitInfo
class RepositorySettingsController extends RepositorySettingsControllerBase class RepositorySettingsController extends RepositorySettingsControllerBase
with RepositoryService with AccountService with WebHookService with RepositoryService with AccountService with WebHookService
@@ -103,7 +108,7 @@ trait RepositorySettingsControllerBase extends ControllerBase with FlashMapSuppo
* Display the web hook page. * Display the web hook page.
*/ */
get("/:owner/:repository/settings/hooks")(ownerOnly { repository => get("/:owner/:repository/settings/hooks")(ownerOnly { repository =>
settings.html.hooks(getWebHookURLs(repository.owner, repository.name), repository) settings.html.hooks(getWebHookURLs(repository.owner, repository.name), repository, flash.get("info"))
}) })
/** /**
@@ -123,6 +128,42 @@ trait RepositorySettingsControllerBase extends ControllerBase with FlashMapSuppo
redirect(s"/${repository.owner}/${repository.name}/settings/hooks") redirect(s"/${repository.owner}/${repository.name}/settings/hooks")
}) })
/**
* Send the test request to registered web hook URLs.
*/
get("/:owner/:repository/settings/hooks/test")(ownerOnly { repository =>
JGitUtil.withGit(getRepositoryDir(repository.owner, repository.name)){ git =>
// TODO Retrieve only specified branch logs.
val i = git.log.setMaxCount(3).call.iterator
// TODO Don't use ListBuffer!!!!
val list = new ListBuffer[CommitInfo]()
while(i.hasNext){
val commit = i.next
list.append(new CommitInfo(commit))
}
val payload = new WebHookPayload(
git,
"refs/heads/" + repository.repository.defaultBranch,
repository,
list.toList,
getAccountByUserName(repository.owner).get)
callWebHook(repository.owner, repository.name, payload)
flash += "info" -> "Test payload deployed!"
}
redirect(s"/${repository.owner}/${repository.name}/settings/hooks")
})
get("/xxx/xxx/xxx/webhooktest"){
println(params("payload"))
}
post("/xxx/xxx/xxx/webhooktest"){
println(params("payload"))
}
/** /**
* Display the delete repository page. * Display the delete repository page.
*/ */

View File

@@ -5,6 +5,15 @@ import Database.threadLocalSession
import model._ import model._
import org.slf4j.LoggerFactory import org.slf4j.LoggerFactory
import service.RepositoryService.RepositoryInfo
import util.JGitUtil
import org.eclipse.jgit.diff.DiffEntry
import util.JGitUtil.CommitInfo
import org.eclipse.jgit.api.Git
import org.apache.http.message.BasicNameValuePair
import org.apache.http.client.entity.UrlEncodedFormEntity
import org.apache.http.protocol.HTTP
import org.apache.http.NameValuePair
trait WebHookService { trait WebHookService {
import WebHookService._ import WebHookService._
@@ -40,7 +49,11 @@ trait WebHookService {
webHookURLs.foreach { webHookUrl => webHookURLs.foreach { webHookUrl =>
val f = future { val f = future {
val httpPost = new HttpPost(webHookUrl.url) val httpPost = new HttpPost(webHookUrl.url)
httpPost.getParams.setParameter("payload", json)
val params: java.util.List[NameValuePair] = new java.util.ArrayList()
params.add(new BasicNameValuePair("payload", json))
httpPost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8))
httpClient.execute(httpPost) httpClient.execute(httpPost)
httpPost.releaseConnection() httpPost.releaseConnection()
} }
@@ -61,7 +74,44 @@ object WebHookService {
case class WebHookPayload( case class WebHookPayload(
ref: String, ref: String,
commits: List[WebHookCommit], commits: List[WebHookCommit],
repository: WebHookRepository) repository: WebHookRepository){
def this(git: Git, refName: String, repositoryInfo: RepositoryInfo, commits: List[CommitInfo], repositoryOwner: Account) =
this(
refName,
commits.map { commit =>
val diffs = JGitUtil.getDiffs(git, commit.id, false)
val commitUrl = repositoryInfo.url.replaceFirst("/git/", "/").replaceFirst("\\.git$", "") + "/commit/" + commit.id
WebHookCommit(
id = commit.id,
message = commit.fullMessage,
timestamp = commit.time.toString,
url = commitUrl,
added = diffs._1.collect { case x if(x.changeType == DiffEntry.ChangeType.ADD) => x.newPath },
removed = diffs._1.collect { case x if(x.changeType == DiffEntry.ChangeType.DELETE) => x.oldPath },
modified = diffs._1.collect { case x if(x.changeType != DiffEntry.ChangeType.ADD &&
x.changeType != DiffEntry.ChangeType.DELETE) => x.newPath },
author = WebHookUser(
name = commit.committer,
email = commit.mailAddress
)
)
}.toList,
WebHookRepository(
name = repositoryInfo.name,
url = repositoryInfo.url,
description = repositoryInfo.repository.description.getOrElse(""),
watchers = 0,
forks = repositoryInfo.forkedCount,
`private` = repositoryInfo.repository.isPrivate,
owner = WebHookUser(
name = repositoryOwner.userName,
email = repositoryOwner.mailAddress
)
)
)
}
case class WebHookCommit( case class WebHookCommit(
id: String, id: String,

View File

@@ -62,7 +62,7 @@ class GitBucketReceivePackFactory extends ReceivePackFactory[HttpServletRequest]
val paths = request.getRequestURI.substring(request.getContextPath.length).split("/") val paths = request.getRequestURI.substring(request.getContextPath.length).split("/")
val owner = paths(2) val owner = paths(2)
val repository = paths(3).replaceFirst("\\.git$", "") val repository = paths(3).replaceFirst("\\.git$", "")
val baseURL = request.getRequestURL.toString.replaceFirst("/git/", "/").replaceFirst("\\.git/.*$", "") val baseURL = request.getRequestURL.toString.replaceFirst("/git/.*", "")
logger.debug("repository:" + owner + "/" + repository) logger.debug("repository:" + owner + "/" + repository)
logger.debug("baseURL:" + baseURL) logger.debug("baseURL:" + baseURL)
@@ -116,43 +116,14 @@ class CommitLogHook(owner: String, repository: String, userName: String, baseURL
} }
} }
println(getRepository(owner, repository, baseURL).get.url)
// call web hook // call web hook
val repositoryInfo = getRepository(owner, repository, "").get val payload = new WebHookPayload(git,
val repositoryOwner = getAccountByUserName(owner) command.getRefName,
getRepository(owner, repository, baseURL).get,
val payload = WebHookPayload( newCommits,
ref = command.getRefName, getAccountByUserName(owner).get)
commits = newCommits.map { commit =>
val diffs = JGitUtil.getDiffs(git, commit.id, false)
WebHookCommit(
id = commit.id,
message = commit.fullMessage,
timestamp = commit.time.toString,
url = baseURL + "/commit/" + commit.id,
added = diffs._1.collect { case x if(x.changeType == DiffEntry.ChangeType.ADD) => x.newPath },
removed = diffs._1.collect { case x if(x.changeType == DiffEntry.ChangeType.DELETE) => x.oldPath },
modified = diffs._1.collect { case x if(x.changeType != DiffEntry.ChangeType.ADD &&
x.changeType != DiffEntry.ChangeType.DELETE) => x.newPath },
author = WebHookUser(
name = commit.committer,
email = commit.mailAddress
)
)
}.toList,
repository = WebHookRepository(
name = repositoryInfo.name,
url = baseURL,
description = repositoryInfo.repository.description.getOrElse(""),
watchers = 0,
forks = repositoryInfo.forkedCount,
`private` = repositoryInfo.repository.isPrivate,
owner = WebHookUser(
name = repositoryOwner.get.userName,
email = repositoryOwner.get.mailAddress
)
)
)
callWebHook(owner, repository, payload) callWebHook(owner, repository, payload)
} }

View File

@@ -1,9 +1,10 @@
@(webHooks: List[model.WebHook], repository: service.RepositoryService.RepositoryInfo)(implicit context: app.Context) @(webHooks: List[model.WebHook], repository: service.RepositoryService.RepositoryInfo, info: Option[Any])(implicit context: app.Context)
@import context._ @import context._
@import view.helpers._ @import view.helpers._
@html.main("Settings", Some(repository)){ @html.main("Settings", Some(repository)){
@html.header("settings", repository) @html.header("settings", repository)
@menu("hooks", repository){ @menu("hooks", repository){
@helper.html.information(info)
<h3>WebHook URLs</h3> <h3>WebHook URLs</h3>
<ul> <ul>
@webHooks.map { webHook => @webHooks.map { webHook =>
@@ -16,6 +17,7 @@
</div> </div>
<input type="text" name="url" id="url" style="width: 300px; margin-bottom: 0px;"/> <input type="text" name="url" id="url" style="width: 300px; margin-bottom: 0px;"/>
<input type="submit" class="btn" value="Add"/> <input type="submit" class="btn" value="Add"/>
<a href="@url(repository)/settings/hooks/test" class="btn">Test Hook</a>
</form> </form>
} }
} }