initial work to re-implement the GitHub status API (issue #403)
This commit is contained in:
parent
994b6f0994
commit
2450cda3c5
2 changed files with 157 additions and 0 deletions
149
plugin/notify/github/github.go
Normal file
149
plugin/notify/github/github.go
Normal file
|
@ -0,0 +1,149 @@
|
|||
package github
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"code.google.com/p/goauth2/oauth"
|
||||
"github.com/drone/drone/shared/model"
|
||||
"github.com/google/go-github/github"
|
||||
)
|
||||
|
||||
// GitHub enterprise URL
|
||||
var URL = os.Getenv("GITHUB_ENTERPRISE_API")
|
||||
|
||||
const (
|
||||
NotifyDisabled = "disabled"
|
||||
NotifyFalse = "false"
|
||||
NotifyOff = "off"
|
||||
)
|
||||
|
||||
const (
|
||||
StatusPending = "peding"
|
||||
StatusSuccess = "success"
|
||||
StatusFailure = "failure"
|
||||
StatusError = "error"
|
||||
)
|
||||
|
||||
const (
|
||||
DescPending = "this build is pending"
|
||||
DescSuccess = "the build was succcessful"
|
||||
DescFailure = "the build failed"
|
||||
DescError = "oops, something went wrong"
|
||||
)
|
||||
|
||||
type GitHub string
|
||||
|
||||
// Send uses the github status API to update the build
|
||||
// status in github or github enterprise.
|
||||
func (g GitHub) Send(context *model.Request) error {
|
||||
|
||||
// a user can toggle the status api on / off
|
||||
// in the .drone.yml
|
||||
switch g {
|
||||
case NotifyDisabled, NotifyOff, NotifyFalse:
|
||||
return nil
|
||||
}
|
||||
|
||||
// this should only be executed for GitHub and
|
||||
// GitHub enterprise requests.
|
||||
switch context.Repo.Remote {
|
||||
case model.RemoteGithub, model.RemoteGithubEnterprise:
|
||||
break
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
|
||||
var target = getTarget(
|
||||
context.Host,
|
||||
context.Repo.Host,
|
||||
context.Repo.Owner,
|
||||
context.Repo.Name,
|
||||
context.Commit.Branch,
|
||||
context.Commit.Sha,
|
||||
)
|
||||
|
||||
return send(
|
||||
context.Repo.Host,
|
||||
context.Repo.Owner,
|
||||
context.Repo.Name,
|
||||
context.Commit.Sha,
|
||||
target,
|
||||
getDesc(context.Commit.Status),
|
||||
getStatus(context.Commit.Status),
|
||||
context.User.Token,
|
||||
)
|
||||
}
|
||||
|
||||
func send(host, owner, repo, ref, status, target, desc, token string) error {
|
||||
transport := &oauth.Transport{
|
||||
Token: &oauth.Token{AccessToken: token},
|
||||
}
|
||||
|
||||
data := github.RepoStatus{
|
||||
Context: github.String("Drone"),
|
||||
State: github.String(status),
|
||||
Description: github.String(desc),
|
||||
TargetURL: github.String(target),
|
||||
}
|
||||
|
||||
client := github.NewClient(transport.Client())
|
||||
|
||||
// if this is for github enterprise we need to set
|
||||
// the base url. Per the documentation, we need to
|
||||
// ensure there is a trailing slash.
|
||||
if host != model.RemoteGithub {
|
||||
client.BaseURL, _ = url.Parse(URL)
|
||||
if !strings.HasSuffix(client.BaseURL.Path, "/") {
|
||||
client.BaseURL.Path = client.BaseURL.Path + "/"
|
||||
}
|
||||
}
|
||||
|
||||
_, _, err := client.Repositories.CreateStatus(owner, repo, ref, &data)
|
||||
return err
|
||||
}
|
||||
|
||||
// getStatus is a helper functin that converts a Drone
|
||||
// status to a GitHub status.
|
||||
func getStatus(status string) string {
|
||||
switch status {
|
||||
case model.StatusEnqueue, model.StatusStarted:
|
||||
return StatusPending
|
||||
case model.StatusSuccess:
|
||||
return StatusSuccess
|
||||
case model.StatusFailure:
|
||||
return StatusFailure
|
||||
case model.StatusError, model.StatusKilled:
|
||||
return StatusError
|
||||
default:
|
||||
return StatusError
|
||||
}
|
||||
}
|
||||
|
||||
// getDesc is a helper function that generates a description
|
||||
// message for the build based on the status.
|
||||
func getDesc(status string) string {
|
||||
switch status {
|
||||
case model.StatusEnqueue, model.StatusStarted:
|
||||
return DescPending
|
||||
case model.StatusSuccess:
|
||||
return DescSuccess
|
||||
case model.StatusFailure:
|
||||
return DescFailure
|
||||
case model.StatusError, model.StatusKilled:
|
||||
return DescError
|
||||
default:
|
||||
return DescError
|
||||
}
|
||||
}
|
||||
|
||||
// getTarget is a helper function that generates a URL
|
||||
// for the user to click and jump to the build results.
|
||||
//
|
||||
// for example:
|
||||
// https://drone.io/github.com/drone/drone-test-go/master/c22aec9c53
|
||||
func getTarget(url, host, owner, repo, branch, commit string) string {
|
||||
return fmt.Sprintf("%s/%s/%s/%s/%s/%s", url, host, owner, repo, branch, commit)
|
||||
}
|
|
@ -4,6 +4,7 @@ import (
|
|||
"log"
|
||||
|
||||
"github.com/drone/drone/plugin/notify/email"
|
||||
"github.com/drone/drone/plugin/notify/github"
|
||||
"github.com/drone/drone/shared/model"
|
||||
)
|
||||
|
||||
|
@ -20,6 +21,8 @@ type Notification struct {
|
|||
Hipchat *Hipchat `yaml:"hipchat,omitempty"`
|
||||
Irc *IRC `yaml:"irc,omitempty"`
|
||||
Slack *Slack `yaml:"slack,omitempty"`
|
||||
|
||||
GitHub github.GitHub `yaml:"github_status"`
|
||||
}
|
||||
|
||||
func (n *Notification) Send(context *model.Request) error {
|
||||
|
@ -63,5 +66,10 @@ func (n *Notification) Send(context *model.Request) error {
|
|||
}
|
||||
}
|
||||
|
||||
// send email notifications
|
||||
if err := n.GitHub.Send(context); err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue