add reviewer fields, endpoints
This commit is contained in:
parent
b0c7f1f4eb
commit
e319aaff15
16 changed files with 198 additions and 31 deletions
|
@ -22,12 +22,15 @@ type Build struct {
|
|||
Title string `json:"title" meddler:"build_title"`
|
||||
Message string `json:"message" meddler:"build_message"`
|
||||
Timestamp int64 `json:"timestamp" meddler:"build_timestamp"`
|
||||
Sender string `json:"sender" meddler:"build_sender"`
|
||||
Author string `json:"author" meddler:"build_author"`
|
||||
Avatar string `json:"author_avatar" meddler:"build_avatar"`
|
||||
Email string `json:"author_email" meddler:"build_email"`
|
||||
Link string `json:"link_url" meddler:"build_link"`
|
||||
Signed bool `json:"signed" meddler:"build_signed"`
|
||||
Verified bool `json:"verified" meddler:"build_verified"`
|
||||
Signed bool `json:"signed" meddler:"build_signed"` // deprecate
|
||||
Verified bool `json:"verified" meddler:"build_verified"` // deprecate
|
||||
Reviewer string `json:"reviewed_by" meddler:"build_reviewer"`
|
||||
Reviewed int64 `json:"reviewed_at" meddler:"build_reviewed"`
|
||||
Jobs []*Job `json:"jobs,omitempty" meddler:"-"`
|
||||
}
|
||||
|
||||
|
|
|
@ -8,13 +8,15 @@ const (
|
|||
)
|
||||
|
||||
const (
|
||||
StatusSkipped = "skipped"
|
||||
StatusPending = "pending"
|
||||
StatusRunning = "running"
|
||||
StatusSuccess = "success"
|
||||
StatusFailure = "failure"
|
||||
StatusKilled = "killed"
|
||||
StatusError = "error"
|
||||
StatusSkipped = "skipped"
|
||||
StatusPending = "pending"
|
||||
StatusRunning = "running"
|
||||
StatusSuccess = "success"
|
||||
StatusFailure = "failure"
|
||||
StatusKilled = "killed"
|
||||
StatusError = "error"
|
||||
StatusBlocked = "blocked"
|
||||
StatusDeclined = "declined"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -29,5 +29,6 @@ type Repo struct {
|
|||
AllowPush bool `json:"allow_push" meddler:"repo_allow_push"`
|
||||
AllowDeploy bool `json:"allow_deploys" meddler:"repo_allow_deploys"`
|
||||
AllowTag bool `json:"allow_tags" meddler:"repo_allow_tags"`
|
||||
Config string `json:"config_path" meddler:"repo_config_path"`
|
||||
Hash string `json:"-" meddler:"repo_hash"`
|
||||
}
|
||||
|
|
|
@ -2,8 +2,8 @@ package bitbucket
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/drone/drone/model"
|
||||
|
@ -19,17 +19,19 @@ const (
|
|||
)
|
||||
|
||||
const (
|
||||
descPending = "this build is pending"
|
||||
descSuccess = "the build was successful"
|
||||
descFailure = "the build failed"
|
||||
descError = "oops, something went wrong"
|
||||
descPending = "this build is pending"
|
||||
descSuccess = "the build was successful"
|
||||
descFailure = "the build failed"
|
||||
descBlocked = "the build requires approval"
|
||||
descDeclined = "the build was rejected"
|
||||
descError = "oops, something went wrong"
|
||||
)
|
||||
|
||||
// convertStatus is a helper function used to convert a Drone status to a
|
||||
// Bitbucket commit status.
|
||||
func convertStatus(status string) string {
|
||||
switch status {
|
||||
case model.StatusPending, model.StatusRunning:
|
||||
case model.StatusPending, model.StatusRunning, model.StatusBlocked:
|
||||
return statusPending
|
||||
case model.StatusSuccess:
|
||||
return statusSuccess
|
||||
|
@ -48,6 +50,10 @@ func convertDesc(status string) string {
|
|||
return descSuccess
|
||||
case model.StatusFailure:
|
||||
return descFailure
|
||||
case model.StatusBlocked:
|
||||
return descBlocked
|
||||
case model.StatusDeclined:
|
||||
return descDeclined
|
||||
default:
|
||||
return descError
|
||||
}
|
||||
|
@ -163,6 +169,7 @@ func convertPullHook(from *internal.PullRequestHook) *model.Build {
|
|||
Message: from.PullRequest.Desc,
|
||||
Avatar: from.Actor.Links.Avatar.Href,
|
||||
Author: from.Actor.Login,
|
||||
Sender: from.Actor.Login,
|
||||
Timestamp: from.PullRequest.Updated.UTC().Unix(),
|
||||
}
|
||||
}
|
||||
|
@ -177,6 +184,7 @@ func convertPushHook(hook *internal.PushHook, change *internal.Change) *model.Bu
|
|||
Message: change.New.Target.Message,
|
||||
Avatar: hook.Actor.Links.Avatar.Href,
|
||||
Author: hook.Actor.Login,
|
||||
Sender: hook.Actor.Login,
|
||||
Timestamp: change.New.Target.Date.UTC().Unix(),
|
||||
}
|
||||
switch change.New.Type {
|
||||
|
@ -198,9 +206,9 @@ var reGitMail = regexp.MustCompile("<(.*)>")
|
|||
|
||||
// extracts the email from a git commit author string
|
||||
func extractEmail(gitauthor string) (author string) {
|
||||
matches := reGitMail.FindAllStringSubmatch(gitauthor,-1)
|
||||
if len(matches) == 1 {
|
||||
author = matches[0][1]
|
||||
}
|
||||
return
|
||||
matches := reGitMail.FindAllStringSubmatch(gitauthor, -1)
|
||||
if len(matches) == 1 {
|
||||
author = matches[0][1]
|
||||
}
|
||||
return
|
||||
}
|
||||
|
|
|
@ -19,10 +19,12 @@ const (
|
|||
)
|
||||
|
||||
const (
|
||||
descPending = "this build is pending"
|
||||
descSuccess = "the build was successful"
|
||||
descFailure = "the build failed"
|
||||
descError = "oops, something went wrong"
|
||||
descPending = "this build is pending"
|
||||
descSuccess = "the build was successful"
|
||||
descFailure = "the build failed"
|
||||
descBlocked = "the build requires approval"
|
||||
descDeclined = "the build was rejected"
|
||||
descError = "oops, something went wrong"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -35,12 +37,12 @@ const (
|
|||
// GitHub commit status.
|
||||
func convertStatus(status string) string {
|
||||
switch status {
|
||||
case model.StatusPending, model.StatusRunning:
|
||||
case model.StatusPending, model.StatusRunning, model.StatusBlocked:
|
||||
return statusPending
|
||||
case model.StatusFailure, model.StatusDeclined:
|
||||
return statusFailure
|
||||
case model.StatusSuccess:
|
||||
return statusSuccess
|
||||
case model.StatusFailure:
|
||||
return statusFailure
|
||||
default:
|
||||
return statusError
|
||||
}
|
||||
|
@ -56,6 +58,10 @@ func convertDesc(status string) string {
|
|||
return descSuccess
|
||||
case model.StatusFailure:
|
||||
return descFailure
|
||||
case model.StatusBlocked:
|
||||
return descBlocked
|
||||
case model.StatusDeclined:
|
||||
return descDeclined
|
||||
default:
|
||||
return descError
|
||||
}
|
||||
|
@ -185,6 +191,7 @@ func convertPushHook(from *webhook) *model.Build {
|
|||
Avatar: from.Sender.Avatar,
|
||||
Author: from.Sender.Login,
|
||||
Remote: from.Repo.CloneURL,
|
||||
Sender: from.Sender.Login,
|
||||
}
|
||||
if len(build.Author) == 0 {
|
||||
build.Author = from.Head.Author.Username
|
||||
|
@ -213,6 +220,7 @@ func convertDeployHook(from *webhook) *model.Build {
|
|||
Ref: from.Deployment.Ref,
|
||||
Branch: from.Deployment.Ref,
|
||||
Deploy: from.Deployment.Env,
|
||||
Sender: from.Sender.Login,
|
||||
}
|
||||
// if the ref is a sha or short sha we need to manuallyconstruct the ref.
|
||||
if strings.HasPrefix(build.Commit, build.Ref) || build.Commit == build.Ref {
|
||||
|
@ -242,6 +250,7 @@ func convertPullHook(from *webhook, merge bool) *model.Build {
|
|||
Author: from.PullRequest.User.Login,
|
||||
Avatar: from.PullRequest.User.Avatar,
|
||||
Title: from.PullRequest.Title,
|
||||
Sender: from.Sender.Login,
|
||||
Remote: from.PullRequest.Head.Repo.CloneURL,
|
||||
Refspec: fmt.Sprintf(refspec,
|
||||
from.PullRequest.Head.Ref,
|
||||
|
|
|
@ -181,6 +181,7 @@ func Test_helper(t *testing.T) {
|
|||
from.PullRequest.Title = "Updated README.md"
|
||||
from.PullRequest.User.Login = "octocat"
|
||||
from.PullRequest.User.Avatar = "https://avatars1.githubusercontent.com/u/583231"
|
||||
from.Sender.Login = "octocat"
|
||||
|
||||
build := convertPullHook(from, true)
|
||||
g.Assert(build.Event).Equal(model.EventPull)
|
||||
|
@ -193,6 +194,7 @@ func Test_helper(t *testing.T) {
|
|||
g.Assert(build.Title).Equal(from.PullRequest.Title)
|
||||
g.Assert(build.Author).Equal(from.PullRequest.User.Login)
|
||||
g.Assert(build.Avatar).Equal(from.PullRequest.User.Avatar)
|
||||
g.Assert(build.Sender).Equal(from.Sender.Login)
|
||||
})
|
||||
|
||||
g.It("should convert a deployment from webhook", func() {
|
||||
|
|
|
@ -95,7 +95,7 @@ const HookPullRequest = `
|
|||
"default_branch": "master"
|
||||
},
|
||||
"sender": {
|
||||
"login": "baxterthehacker",
|
||||
"login": "octocat",
|
||||
"avatar_url": "https://avatars.githubusercontent.com/u/6752317?v=3"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -629,18 +629,20 @@ const (
|
|||
)
|
||||
|
||||
const (
|
||||
DescPending = "this build is pending"
|
||||
DescRunning = "this buils is running"
|
||||
DescPending = "the build is pending"
|
||||
DescRunning = "the buils is running"
|
||||
DescSuccess = "the build was successful"
|
||||
DescFailure = "the build failed"
|
||||
DescCanceled = "the build canceled"
|
||||
DescBlocked = "the build is pending approval"
|
||||
DescDeclined = "the build was rejected"
|
||||
)
|
||||
|
||||
// getStatus is a helper functin that converts a Drone
|
||||
// status to a GitHub status.
|
||||
func getStatus(status string) string {
|
||||
switch status {
|
||||
case model.StatusPending:
|
||||
case model.StatusPending, model.StatusBlocked:
|
||||
return StatusPending
|
||||
case model.StatusRunning:
|
||||
return StatusRunning
|
||||
|
@ -669,6 +671,10 @@ func getDesc(status string) string {
|
|||
return DescFailure
|
||||
case model.StatusKilled:
|
||||
return DescCanceled
|
||||
case model.StatusBlocked:
|
||||
return DescBlocked
|
||||
case model.StatusDeclined:
|
||||
return DescDeclined
|
||||
default:
|
||||
return DescFailure
|
||||
}
|
||||
|
|
|
@ -129,6 +129,7 @@ var HookPullRequest = `{
|
|||
},
|
||||
"sender": {
|
||||
"id": 1,
|
||||
"login": "gordon",
|
||||
"username": "gordon",
|
||||
"full_name": "Gordon the Gopher",
|
||||
"email": "gordon@golang.org",
|
||||
|
|
|
@ -74,6 +74,10 @@ func buildFromPush(hook *pushHook) *model.Build {
|
|||
if author == "" {
|
||||
author = hook.Sender.Username
|
||||
}
|
||||
sender := hook.Sender.Username
|
||||
if sender == "" {
|
||||
sender = hook.Sender.Login
|
||||
}
|
||||
|
||||
return &model.Build{
|
||||
Event: model.EventPush,
|
||||
|
@ -85,6 +89,7 @@ func buildFromPush(hook *pushHook) *model.Build {
|
|||
Avatar: avatar,
|
||||
Author: author,
|
||||
Timestamp: time.Now().UTC().Unix(),
|
||||
Sender: sender,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -98,6 +103,10 @@ func buildFromTag(hook *pushHook) *model.Build {
|
|||
if author == "" {
|
||||
author = hook.Sender.Username
|
||||
}
|
||||
sender := hook.Sender.Username
|
||||
if sender == "" {
|
||||
sender = hook.Sender.Login
|
||||
}
|
||||
|
||||
return &model.Build{
|
||||
Event: model.EventTag,
|
||||
|
@ -108,6 +117,7 @@ func buildFromTag(hook *pushHook) *model.Build {
|
|||
Message: fmt.Sprintf("created tag %s", hook.Ref),
|
||||
Avatar: avatar,
|
||||
Author: author,
|
||||
Sender: sender,
|
||||
Timestamp: time.Now().UTC().Unix(),
|
||||
}
|
||||
}
|
||||
|
@ -118,6 +128,10 @@ func buildFromPullRequest(hook *pullRequestHook) *model.Build {
|
|||
hook.Repo.URL,
|
||||
fixMalformedAvatar(hook.PullRequest.User.Avatar),
|
||||
)
|
||||
sender := hook.Sender.Username
|
||||
if sender == "" {
|
||||
sender = hook.Sender.Login
|
||||
}
|
||||
build := &model.Build{
|
||||
Event: model.EventPull,
|
||||
Commit: hook.PullRequest.Head.Sha,
|
||||
|
@ -127,6 +141,7 @@ func buildFromPullRequest(hook *pullRequestHook) *model.Build {
|
|||
Message: hook.PullRequest.Title,
|
||||
Author: hook.PullRequest.User.Username,
|
||||
Avatar: avatar,
|
||||
Sender: sender,
|
||||
Title: hook.PullRequest.Title,
|
||||
Refspec: fmt.Sprintf("%s:%s",
|
||||
hook.PullRequest.Head.Ref,
|
||||
|
|
|
@ -116,6 +116,7 @@ type pullRequestHook struct {
|
|||
} `json:"repository"`
|
||||
Sender struct {
|
||||
ID int64 `json:"id"`
|
||||
Login string `json:"login"`
|
||||
Username string `json:"username"`
|
||||
Name string `json:"full_name"`
|
||||
Email string `json:"email"`
|
||||
|
|
|
@ -108,6 +108,8 @@ func Load(middleware ...gin.HandlerFunc) http.Handler {
|
|||
repo.POST("/chown", session.MustRepoAdmin(), server.ChownRepo)
|
||||
|
||||
repo.POST("/builds/:number", session.MustPush, server.PostBuild)
|
||||
repo.POST("/builds/:number/approve", session.MustPush, server.PostApproval)
|
||||
repo.POST("/builds/:number/decline", session.MustPush, server.PostDecline)
|
||||
repo.DELETE("/builds/:number/:job", session.MustPush, server.DeleteBuild)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -156,6 +156,69 @@ func DeleteBuild(c *gin.Context) {
|
|||
c.String(204, "")
|
||||
}
|
||||
|
||||
func PostApproval(c *gin.Context) {
|
||||
var (
|
||||
repo = session.Repo(c)
|
||||
user = session.User(c)
|
||||
num, _ = strconv.Atoi(
|
||||
c.Params.ByName("number"),
|
||||
)
|
||||
)
|
||||
|
||||
build, err := store.GetBuildNumber(c, repo, num)
|
||||
if err != nil {
|
||||
c.AbortWithError(404, err)
|
||||
return
|
||||
}
|
||||
if build.Status != model.StatusBlocked {
|
||||
c.String(500, "cannot decline a build with status %s", build.Status)
|
||||
return
|
||||
}
|
||||
build.Status = model.StatusPending
|
||||
build.Reviewed = time.Now().Unix()
|
||||
build.Reviewer = user.Login
|
||||
|
||||
if err := store.UpdateBuild(c, build); err != nil {
|
||||
c.String(500, "error updating build. %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
//
|
||||
// TODO start build
|
||||
//
|
||||
|
||||
c.JSON(200, build)
|
||||
}
|
||||
|
||||
func PostDecline(c *gin.Context) {
|
||||
var (
|
||||
repo = session.Repo(c)
|
||||
user = session.User(c)
|
||||
num, _ = strconv.Atoi(
|
||||
c.Params.ByName("number"),
|
||||
)
|
||||
)
|
||||
|
||||
build, err := store.GetBuildNumber(c, repo, num)
|
||||
if err != nil {
|
||||
c.AbortWithError(404, err)
|
||||
return
|
||||
}
|
||||
if build.Status != model.StatusBlocked {
|
||||
c.String(500, "cannot decline a build with status %s", build.Status)
|
||||
return
|
||||
}
|
||||
build.Status = model.StatusDeclined
|
||||
build.Reviewed = time.Now().Unix()
|
||||
build.Reviewer = user.Login
|
||||
|
||||
if err := store.UpdateBuild(c, build); err != nil {
|
||||
c.String(500, "error updating build. %s", err)
|
||||
return
|
||||
}
|
||||
c.JSON(200, build)
|
||||
}
|
||||
|
||||
func GetBuildQueue(c *gin.Context) {
|
||||
out, err := store.GetBuildQueue(c)
|
||||
if err != nil {
|
||||
|
|
18
store/datastore/ddl/mysql/12.sql
Normal file
18
store/datastore/ddl/mysql/12.sql
Normal file
|
@ -0,0 +1,18 @@
|
|||
-- +migrate Up
|
||||
|
||||
ALTER TABLE repos ADD COLUMN repo_config_path VARCHAR(255);
|
||||
ALTER TABLE builds ADD COLUMN build_sender VARCHAR(255);
|
||||
ALTER TABLE builds ADD COLUMN build_reviewer VARCHAR(255);
|
||||
ALTER TABLE builds ADD COLUMN build_reviewed INTEGER;
|
||||
|
||||
UPDATE repos SET repo_config_path = '';
|
||||
UPDATE builds SET build_reviewer = '';
|
||||
UPDATE builds SET build_reviewed = 0;
|
||||
UPDATE builds SET build_sender = '';
|
||||
|
||||
-- +migrate Down
|
||||
|
||||
ALTER TABLE repos DROP COLUMN repo_config_path;
|
||||
ALTER TABLE builds DROP COLUMN build_sender;
|
||||
ALTER TABLE builds DROP COLUMN build_reviewer;
|
||||
ALTER TABLE builds DROP COLUMN build_reviewed;
|
18
store/datastore/ddl/postgres/12.sql
Normal file
18
store/datastore/ddl/postgres/12.sql
Normal file
|
@ -0,0 +1,18 @@
|
|||
-- +migrate Up
|
||||
|
||||
ALTER TABLE repos ADD COLUMN repo_config_path VARCHAR(255);
|
||||
ALTER TABLE builds ADD COLUMN build_reviewer VARCHAR(255);
|
||||
ALTER TABLE builds ADD COLUMN build_reviewed INTEGER;
|
||||
ALTER TABLE builds ADD COLUMN build_sender VARCHAR(255);
|
||||
|
||||
UPDATE repos SET repo_config_path = '';
|
||||
UPDATE builds SET build_reviewer = '';
|
||||
UPDATE builds SET build_reviewed = 0;
|
||||
UPDATE builds SET build_sender = '';
|
||||
|
||||
-- +migrate Down
|
||||
|
||||
ALTER TABLE repos DROP COLUMN repo_config_path;
|
||||
ALTER TABLE builds DROP COLUMN build_reviewer;
|
||||
ALTER TABLE builds DROP COLUMN build_reviewed;
|
||||
ALTER TABLE builds DROP COLUMN build_sender;
|
18
store/datastore/ddl/sqlite3/12.sql
Normal file
18
store/datastore/ddl/sqlite3/12.sql
Normal file
|
@ -0,0 +1,18 @@
|
|||
-- +migrate Up
|
||||
|
||||
ALTER TABLE repos ADD COLUMN repo_config_path TEXT;
|
||||
ALTER TABLE builds ADD COLUMN build_reviewer TEXT;
|
||||
ALTER TABLE builds ADD COLUMN build_reviewed INTEGER;
|
||||
ALTER TABLE builds ADD COLUMN build_sender TEXT;
|
||||
|
||||
UPDATE repos SET repo_config_path = '';
|
||||
UPDATE builds SET build_reviewer = '';
|
||||
UPDATE builds SET build_reviewed = 0;
|
||||
UPDATE builds SET build_sender = '';
|
||||
|
||||
-- +migrate Down
|
||||
|
||||
ALTER TABLE repos DROP COLUMN repo_config_path;
|
||||
ALTER TABLE builds DROP COLUMN build_reviewer;
|
||||
ALTER TABLE builds DROP COLUMN build_reviewed;
|
||||
ALTER TABLE builds DROP COLUMN build_sender;
|
Loading…
Reference in a new issue