diff --git a/remote/bitbucketserver/bitbucketserver.go b/remote/bitbucketserver/bitbucketserver.go index 8b70edf8..6012955f 100644 --- a/remote/bitbucketserver/bitbucketserver.go +++ b/remote/bitbucketserver/bitbucketserver.go @@ -149,8 +149,17 @@ func (c *Config) File(u *model.User, r *model.Repo, b *model.Build, f string) ([ } // Status is not supported by the bitbucketserver driver. -func (*Config) Status(*model.User, *model.Repo, *model.Build, string) error { - return nil +func (c *Config) Status(u *model.User,r *model.Repo,b *model.Build,link string) error { + status := internal.BuildStatus{ + State: convertStatus(b.Status), + Desc: convertDesc(b.Status), + Key: "Drone", + Url: link, + } + + client := internal.NewClientWithToken(c.URL, c.Consumer, u.Token) + + return client.CreateStatus(b.Commit, &status) } func (c *Config) Netrc(user *model.User, r *model.Repo) (*model.Netrc, error) { diff --git a/remote/bitbucketserver/convert.go b/remote/bitbucketserver/convert.go index 65fe8e3c..20f7069f 100644 --- a/remote/bitbucketserver/convert.go +++ b/remote/bitbucketserver/convert.go @@ -13,6 +13,48 @@ import ( "time" ) + +const ( + statusPending = "INPROGRESS" + statusSuccess = "SUCCESSFUL" + statusFailure = "FAILED" +) + +const ( + descPending = "this build is pending" + descSuccess = "the build was successful" + descFailure = "the build failed" + 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: + return statusPending + case model.StatusSuccess: + return statusSuccess + default: + return statusFailure + } +} + +// convertDesc is a helper function used to convert a Drone status to a +// Bitbucket status description. +func convertDesc(status string) string { + switch status { + case model.StatusPending, model.StatusRunning: + return descPending + case model.StatusSuccess: + return descSuccess + case model.StatusFailure: + return descFailure + default: + return descError + } +} + // convertRepo is a helper function used to convert a Bitbucket server repository // structure to the common Drone repository structure. func convertRepo(from *internal.Repo) *model.Repo { diff --git a/remote/bitbucketserver/internal/client.go b/remote/bitbucketserver/internal/client.go index 05853848..11bf904f 100644 --- a/remote/bitbucketserver/internal/client.go +++ b/remote/bitbucketserver/internal/client.go @@ -9,6 +9,7 @@ import ( "github.com/mrjones/oauth" "io/ioutil" "net/http" + "io" ) const ( @@ -20,6 +21,7 @@ const ( pathSource = "%s/projects/%s/repos/%s/browse/%s?at=%s&raw" hookName = "com.atlassian.stash.plugin.stash-web-post-receive-hooks-plugin:postReceiveHook" pathHookEnabled = "%s/rest/api/1.0/projects/%s/repos/%s/settings/hooks/%s/enabled" + pathStatus = "%s/rest/build-status/1.0/commits/%s" ) type Client struct { @@ -151,11 +153,18 @@ func (c *Client) CreateHook(owner string, name string, callBackLink string) erro return c.doPut(fmt.Sprintf(pathHookEnabled, c.base, owner, name, hookName), hookBytes) } +func (c *Client) CreateStatus(revision string, status *BuildStatus) error { + uri := fmt.Sprintf(pathStatus, c.base, revision) + return c.doPost(uri, status) +} + func (c *Client) DeleteHook(owner string, name string, link string) error { //TODO: eventially should only delete the link callback return c.doDelete(fmt.Sprintf(pathHookEnabled, c.base, owner, name, hookName)) } +//TODO: make these as as general do with the action + //Helper function to help create the hook func (c *Client) doPut(url string, body []byte) error { request, err := http.NewRequest("PUT", url, bytes.NewBuffer(body)) @@ -166,9 +175,34 @@ func (c *Client) doPut(url string, body []byte) error { } defer response.Body.Close() return nil - } + +//Helper function to help create the hook +func (c *Client) doPost(url string, status *BuildStatus) error { + // write it to the body of the request. + var buf io.ReadWriter + if status != nil { + buf = new(bytes.Buffer) + err := json.NewEncoder(buf).Encode(status) + if err != nil { + return err + } + } + request, err := http.NewRequest("POST", url, buf) + request.Header.Add("Content-Type", "application/json") + response, err := c.client.Do(request) + if err != nil { + return err + } + defer response.Body.Close() + return nil +} + + + + + //Helper function to do delete on the hook func (c *Client) doDelete(url string) error { request, err := http.NewRequest("DELETE", url, nil) diff --git a/remote/bitbucketserver/internal/types.go b/remote/bitbucketserver/internal/types.go index 0e879e27..9b50c3a0 100644 --- a/remote/bitbucketserver/internal/types.go +++ b/remote/bitbucketserver/internal/types.go @@ -24,6 +24,14 @@ type SelfRefLink struct { Href string `json:"href"` } +type BuildStatus struct { + State string `json:"state"` + Key string `json:"key"` + Name string `json:"name,omitempty"` + Url string `json:"url"` + Desc string `json:"description,omitempty"` +} + type Repo struct { Forkable bool `json:"forkable"` ID int `json:"id"`