Add initial hook handler
This commit is contained in:
parent
15770e6237
commit
e2a45df3b8
2 changed files with 110 additions and 1 deletions
|
@ -197,7 +197,7 @@ func setupHandlers() {
|
|||
m.Post("/hook/bitbucket.org", handler.ErrorHandler(hookHandler.HookBitbucket))
|
||||
|
||||
// handlers for GitLab post-commit hooks
|
||||
//m.Post("/hook/gitlab", handler.ErrorHandler(gitlab.Hook))
|
||||
m.Post("/hook/gitlab", handler.ErrorHandler(gitlab.Hook))
|
||||
|
||||
// handlers for first-time installation
|
||||
m.Get("/install", handler.ErrorHandler(handler.Install))
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/drone/drone/pkg/build/script"
|
||||
"github.com/drone/drone/pkg/database"
|
||||
. "github.com/drone/drone/pkg/model"
|
||||
"github.com/drone/drone/pkg/queue"
|
||||
|
@ -136,6 +139,112 @@ func (g *GitlabHandler) newGitlabRepo(u *User, owner, name string) (*Repo, error
|
|||
return repo, err
|
||||
}
|
||||
|
||||
func (g *GitlabHandler) Hook(w http.ResponseWriter, r *http.Request) error {
|
||||
var payload []byte
|
||||
n, err := r.Body.Read(payload)
|
||||
if n == 0 {
|
||||
return fmt.Errorf("Request Empty: %q", err)
|
||||
}
|
||||
parsed, err := gogitlab.ParseHook(payload)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if parsed.ObjectKind == "merge_request" {
|
||||
return g.PullRequestHook(parsed)
|
||||
}
|
||||
|
||||
if len(parsed.After) == 0 {
|
||||
return RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
||||
}
|
||||
|
||||
rID := r.FormValue("id")
|
||||
repo, err := database.GetRepoSlug(rID)
|
||||
if err != nil {
|
||||
return RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
||||
}
|
||||
|
||||
user, err := database.GetUser(repo.UserID)
|
||||
if err != nil {
|
||||
return RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
|
||||
}
|
||||
|
||||
_, err = database.GetCommitHash(parsed.After, repo.ID)
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
println("commit already exists")
|
||||
return RenderText(w, http.StatusText(http.StatusBadGateway), http.StatusBadGateway)
|
||||
}
|
||||
|
||||
commit := &Commit{}
|
||||
commit.RepoID = repo.ID
|
||||
commit.Branch = parsed.Branch()
|
||||
commit.Hash = parsed.After
|
||||
commit.Status = "Pending"
|
||||
commit.Created = time.Now().UTC()
|
||||
|
||||
head := parsed.Head()
|
||||
commit.Message = head.Message
|
||||
commit.Timestamp = head.Timestamp
|
||||
if head.Author != nil {
|
||||
commit.SetAuthor(head.Author.Email)
|
||||
} else {
|
||||
commit.SetAuthor(parsed.UserName)
|
||||
}
|
||||
|
||||
// get the github settings from the database
|
||||
settings := database.SettingsMust()
|
||||
|
||||
// get the drone.yml file from GitHub
|
||||
client := gogitlab.NewGitlab(settings.GitlabApiUrl, g.apiPath, user.GitlabToken)
|
||||
|
||||
content, err := client.RepoRawFile(ns(repo.Owner, repo.Name), commit.Hash, ".drone.yml")
|
||||
if err != nil {
|
||||
msg := "No .drone.yml was found in this repository. You need to add one.\n"
|
||||
if err := saveFailedBuild(commit, msg); err != nil {
|
||||
return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
// parse the build script
|
||||
buildscript, err := script.ParseBuild(content, repo.Params)
|
||||
if err != nil {
|
||||
msg := "Could not parse your .drone.yml file. It needs to be a valid drone yaml file.\n\n" + err.Error() + "\n"
|
||||
if err := saveFailedBuild(commit, msg); err != nil {
|
||||
return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
|
||||
}
|
||||
|
||||
// save the commit to the database
|
||||
if err := database.SaveCommit(commit); err != nil {
|
||||
return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
// save the build to the database
|
||||
build := &Build{}
|
||||
build.Slug = "1" // TODO
|
||||
build.CommitID = commit.ID
|
||||
build.Created = time.Now().UTC()
|
||||
build.Status = "Pending"
|
||||
if err := database.SaveBuild(build); err != nil {
|
||||
return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
// notify websocket that a new build is pending
|
||||
//realtime.CommitPending(repo.UserID, repo.TeamID, repo.ID, commit.ID, repo.Private)
|
||||
//realtime.BuildPending(repo.UserID, repo.TeamID, repo.ID, commit.ID, build.ID, repo.Private)
|
||||
|
||||
g.queue.Add(&queue.BuildTask{Repo: repo, Commit: commit, Build: build, Script: buildscript}) //Push(repo, commit, build, buildscript)
|
||||
|
||||
// OK!
|
||||
return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK)
|
||||
|
||||
}
|
||||
|
||||
func (g *GitlabHandler) PullRequestHook(p *gogitlab.HookPayload) error {
|
||||
return fmt.Errorf("Not implemented yet")
|
||||
}
|
||||
|
||||
// ns namespaces user and repo.
|
||||
// Returns user%2Frepo
|
||||
func ns(user, repo string) string {
|
||||
|
|
Loading…
Reference in a new issue