github.com/unclejack/drone@v0.2.1-0.20140918182345-831b034aa33b/pkg/handler/bitbucket.go (about) 1 package handler 2 3 import ( 4 "database/sql" 5 "net/http" 6 "time" 7 8 "github.com/drone/drone/pkg/database" 9 . "github.com/drone/drone/pkg/model" 10 "github.com/drone/drone/pkg/queue" 11 "github.com/drone/go-bitbucket/bitbucket" 12 ) 13 14 type BitbucketHandler struct { 15 queue *queue.Queue 16 } 17 18 func NewBitbucketHandler(queue *queue.Queue) *BitbucketHandler { 19 return &BitbucketHandler{ 20 queue: queue, 21 } 22 } 23 24 // Processes a generic POST-RECEIVE Bitbucket hook and 25 // attempts to trigger a build. 26 func (h *BitbucketHandler) Hook(w http.ResponseWriter, r *http.Request) error { 27 // get the payload from the request 28 payload := r.FormValue("payload") 29 30 // parse the post-commit hook 31 hook, err := bitbucket.ParseHook([]byte(payload)) 32 if err != nil { 33 return err 34 } 35 36 // get the repo from the URL 37 repoId := r.FormValue("id") 38 39 // get the repo from the database, return error if not found 40 repo, err := database.GetRepoSlug(repoId) 41 if err != nil { 42 return RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) 43 } 44 45 // Get the user that owns the repository 46 user, err := database.GetUser(repo.UserID) 47 if err != nil { 48 return RenderText(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest) 49 } 50 51 // Verify that the commit doesn't already exist. 52 // We should never build the same commit twice. 53 _, err = database.GetCommitHash(hook.Commits[len(hook.Commits)-1].Hash, repo.ID) 54 if err != nil && err != sql.ErrNoRows { 55 return RenderText(w, http.StatusText(http.StatusBadGateway), http.StatusBadGateway) 56 } 57 58 commit := &Commit{} 59 commit.RepoID = repo.ID 60 commit.Branch = hook.Commits[len(hook.Commits)-1].Branch 61 commit.Hash = hook.Commits[len(hook.Commits)-1].Hash 62 commit.Status = "Pending" 63 commit.Created = time.Now().UTC() 64 commit.Message = hook.Commits[len(hook.Commits)-1].Message 65 commit.Timestamp = time.Now().UTC().String() 66 commit.SetAuthor(hook.Commits[len(hook.Commits)-1].Author) 67 68 // get the github settings from the database 69 settings := database.SettingsMust() 70 71 // create the Bitbucket client 72 client := bitbucket.New( 73 settings.BitbucketKey, 74 settings.BitbucketSecret, 75 user.BitbucketToken, 76 user.BitbucketSecret, 77 ) 78 79 // get the yaml from the database 80 raw, err := client.Sources.Find(repo.Owner, repo.Name, commit.Hash, ".drone.yml") 81 if err != nil { 82 return RenderText(w, http.StatusText(http.StatusNotFound), http.StatusNotFound) 83 } 84 85 // save the commit to the database 86 if err := database.SaveCommit(commit); err != nil { 87 return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) 88 } 89 90 // save the build to the database 91 build := &Build{} 92 build.Slug = "1" // TODO 93 build.CommitID = commit.ID 94 build.Created = time.Now().UTC() 95 build.Status = "Pending" 96 build.BuildScript = raw.Data 97 if err := database.SaveBuild(build); err != nil { 98 return RenderText(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError) 99 } 100 101 // send the build to the queue 102 h.queue.Add(&queue.BuildTask{Repo: repo, Commit: commit, Build: build}) 103 104 // OK! 105 return RenderText(w, http.StatusText(http.StatusOK), http.StatusOK) 106 }