2015-09-30 01:21:17 +00:00
|
|
|
package github
|
|
|
|
|
|
|
|
import (
|
2015-10-30 21:47:46 +00:00
|
|
|
"crypto/tls"
|
2015-09-30 01:21:17 +00:00
|
|
|
"encoding/json"
|
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
2016-03-30 00:05:28 +00:00
|
|
|
"regexp"
|
2015-09-30 01:21:17 +00:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
"github.com/drone/drone/model"
|
2016-04-29 19:39:56 +00:00
|
|
|
"github.com/drone/drone/remote"
|
2015-09-30 01:21:17 +00:00
|
|
|
"github.com/drone/drone/shared/httputil"
|
|
|
|
"github.com/drone/drone/shared/oauth2"
|
|
|
|
|
|
|
|
"github.com/google/go-github/github"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
2016-04-29 19:39:56 +00:00
|
|
|
DefaultURL = "https://github.com" // Default GitHub URL
|
|
|
|
DefaultAPI = "https://api.github.com" // Default GitHub API URL
|
2015-09-30 01:21:17 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type Github struct {
|
|
|
|
URL string
|
|
|
|
API string
|
|
|
|
Client string
|
|
|
|
Secret string
|
2016-03-10 19:30:14 +00:00
|
|
|
Scope string
|
2016-03-05 05:15:50 +00:00
|
|
|
MergeRef string
|
2015-09-30 01:21:17 +00:00
|
|
|
PrivateMode bool
|
|
|
|
SkipVerify bool
|
|
|
|
}
|
|
|
|
|
2016-04-29 19:39:56 +00:00
|
|
|
func New(url, client, secret string, scope []string, private, skipverify, mergeref bool) (remote.Remote, error) {
|
|
|
|
remote := &Github{
|
|
|
|
URL: strings.TrimSuffix(url, "/"),
|
|
|
|
Client: client,
|
|
|
|
Secret: secret,
|
|
|
|
Scope: strings.Join(scope, ","),
|
|
|
|
PrivateMode: private,
|
|
|
|
SkipVerify: skipverify,
|
|
|
|
MergeRef: "head",
|
2015-09-30 01:21:17 +00:00
|
|
|
}
|
|
|
|
|
2016-04-29 19:39:56 +00:00
|
|
|
if remote.URL == DefaultURL {
|
|
|
|
remote.API = DefaultAPI
|
|
|
|
} else {
|
|
|
|
remote.API = remote.URL + "/api/v3/"
|
2016-03-10 19:30:14 +00:00
|
|
|
}
|
2016-04-29 19:39:56 +00:00
|
|
|
if mergeref {
|
|
|
|
remote.MergeRef = "merge"
|
2016-03-05 05:15:50 +00:00
|
|
|
}
|
|
|
|
|
2016-04-29 19:39:56 +00:00
|
|
|
return remote, nil
|
2015-09-30 01:21:17 +00:00
|
|
|
}
|
|
|
|
|
2016-04-29 19:39:56 +00:00
|
|
|
// Login authenticates the session and returns the remote user details.
|
|
|
|
func (g *Github) Login(res http.ResponseWriter, req *http.Request) (*model.User, error) {
|
2015-09-30 01:21:17 +00:00
|
|
|
|
|
|
|
var config = &oauth2.Config{
|
|
|
|
ClientId: g.Client,
|
|
|
|
ClientSecret: g.Secret,
|
2016-03-10 19:30:14 +00:00
|
|
|
Scope: g.Scope,
|
2015-09-30 01:21:17 +00:00
|
|
|
AuthURL: fmt.Sprintf("%s/login/oauth/authorize", g.URL),
|
|
|
|
TokenURL: fmt.Sprintf("%s/login/oauth/access_token", g.URL),
|
|
|
|
RedirectURL: fmt.Sprintf("%s/authorize", httputil.GetURL(req)),
|
|
|
|
}
|
|
|
|
|
|
|
|
// get the OAuth code
|
|
|
|
var code = req.FormValue("code")
|
|
|
|
if len(code) == 0 {
|
|
|
|
var random = GetRandom()
|
|
|
|
http.Redirect(res, req, config.AuthCodeURL(random), http.StatusSeeOther)
|
2016-04-29 19:39:56 +00:00
|
|
|
return nil, nil
|
2015-09-30 01:21:17 +00:00
|
|
|
}
|
|
|
|
|
2015-10-30 21:47:46 +00:00
|
|
|
var trans = &oauth2.Transport{
|
|
|
|
Config: config,
|
|
|
|
}
|
|
|
|
if g.SkipVerify {
|
|
|
|
trans.Transport = &http.Transport{
|
|
|
|
Proxy: http.ProxyFromEnvironment,
|
|
|
|
TLSClientConfig: &tls.Config{
|
|
|
|
InsecureSkipVerify: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
2015-09-30 01:21:17 +00:00
|
|
|
var token, err = trans.Exchange(code)
|
|
|
|
if err != nil {
|
2016-04-29 19:39:56 +00:00
|
|
|
return nil, fmt.Errorf("Error exchanging token. %s", err)
|
2015-09-30 01:21:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var client = NewClient(g.API, token.AccessToken, g.SkipVerify)
|
|
|
|
var useremail, errr = GetUserEmail(client)
|
|
|
|
if errr != nil {
|
2016-04-29 19:39:56 +00:00
|
|
|
return nil, fmt.Errorf("Error retrieving user or verified email. %s", errr)
|
2015-09-30 01:21:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
user := model.User{}
|
|
|
|
user.Login = *useremail.Login
|
|
|
|
user.Email = *useremail.Email
|
|
|
|
user.Token = token.AccessToken
|
|
|
|
user.Avatar = *useremail.AvatarURL
|
2016-04-29 19:39:56 +00:00
|
|
|
return &user, nil
|
2015-09-30 01:21:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Auth authenticates the session and returns the remote user
|
|
|
|
// login for the given token and secret
|
|
|
|
func (g *Github) Auth(token, secret string) (string, error) {
|
|
|
|
client := NewClient(g.API, token, g.SkipVerify)
|
|
|
|
user, _, err := client.Users.Get("")
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return *user.Login, nil
|
|
|
|
}
|
|
|
|
|
2016-04-29 19:39:56 +00:00
|
|
|
func (g *Github) Teams(u *model.User) ([]*model.Team, error) {
|
|
|
|
client := NewClient(g.API, u.Token, g.SkipVerify)
|
|
|
|
orgs, err := GetOrgs(client)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var teams []*model.Team
|
|
|
|
for _, org := range orgs {
|
|
|
|
teams = append(teams, &model.Team{
|
|
|
|
Login: *org.Login,
|
|
|
|
Avatar: *org.AvatarURL,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return teams, nil
|
|
|
|
}
|
|
|
|
|
2015-09-30 01:21:17 +00:00
|
|
|
// Repo fetches the named repository from the remote system.
|
|
|
|
func (g *Github) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
|
|
|
client := NewClient(g.API, u.Token, g.SkipVerify)
|
2016-04-29 19:39:56 +00:00
|
|
|
r, err := GetRepo(client, owner, name)
|
2015-09-30 01:21:17 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2016-04-29 19:39:56 +00:00
|
|
|
repo := &model.Repo{
|
|
|
|
Owner: owner,
|
|
|
|
Name: name,
|
|
|
|
FullName: *r.FullName,
|
|
|
|
Link: *r.HTMLURL,
|
|
|
|
IsPrivate: *r.Private,
|
|
|
|
Clone: *r.CloneURL,
|
|
|
|
Avatar: *r.Owner.AvatarURL,
|
|
|
|
Kind: model.RepoGit,
|
2015-09-30 01:21:17 +00:00
|
|
|
}
|
|
|
|
|
2016-04-29 19:39:56 +00:00
|
|
|
if r.DefaultBranch != nil {
|
|
|
|
repo.Branch = *r.DefaultBranch
|
|
|
|
} else {
|
|
|
|
repo.Branch = "master"
|
2015-09-30 01:21:17 +00:00
|
|
|
}
|
2015-10-02 23:02:37 +00:00
|
|
|
|
2016-04-29 19:39:56 +00:00
|
|
|
if g.PrivateMode {
|
|
|
|
repo.IsPrivate = true
|
2015-10-02 23:02:37 +00:00
|
|
|
}
|
|
|
|
|
2015-09-30 01:21:17 +00:00
|
|
|
return repo, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Repos fetches a list of repos from the remote system.
|
|
|
|
func (g *Github) Repos(u *model.User) ([]*model.RepoLite, error) {
|
|
|
|
client := NewClient(g.API, u.Token, g.SkipVerify)
|
|
|
|
|
2016-03-26 15:48:35 +00:00
|
|
|
all, err := GetUserRepos(client)
|
2015-09-30 01:21:17 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
var repos = []*model.RepoLite{}
|
|
|
|
for _, repo := range all {
|
|
|
|
repos = append(repos, &model.RepoLite{
|
|
|
|
Owner: *repo.Owner.Login,
|
|
|
|
Name: *repo.Name,
|
|
|
|
FullName: *repo.FullName,
|
|
|
|
Avatar: *repo.Owner.AvatarURL,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
return repos, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Perm fetches the named repository permissions from
|
|
|
|
// the remote system for the specified user.
|
|
|
|
func (g *Github) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
|
|
|
|
|
|
|
client := NewClient(g.API, u.Token, g.SkipVerify)
|
|
|
|
repo, err := GetRepo(client, owner, name)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
m := &model.Perm{}
|
|
|
|
m.Admin = (*repo.Permissions)["admin"]
|
|
|
|
m.Push = (*repo.Permissions)["push"]
|
|
|
|
m.Pull = (*repo.Permissions)["pull"]
|
|
|
|
return m, nil
|
|
|
|
}
|
|
|
|
|
2016-03-22 10:34:33 +00:00
|
|
|
// File fetches a file from the remote repository and returns in string format.
|
|
|
|
func (g *Github) File(u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
|
2015-09-30 01:21:17 +00:00
|
|
|
client := NewClient(g.API, u.Token, g.SkipVerify)
|
2016-03-22 10:34:33 +00:00
|
|
|
cfg, err := GetFile(client, r.Owner, r.Name, f, b.Commit)
|
|
|
|
return cfg, err
|
2015-09-30 01:21:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Status sends the commit status to the remote system.
|
|
|
|
// An example would be the GitHub pull request status.
|
|
|
|
func (g *Github) Status(u *model.User, r *model.Repo, b *model.Build, link string) error {
|
|
|
|
client := NewClient(g.API, u.Token, g.SkipVerify)
|
2016-03-30 00:05:28 +00:00
|
|
|
if b.Event == "deployment" {
|
|
|
|
return deploymentStatus(client, r, b, link)
|
2016-03-29 18:07:50 +00:00
|
|
|
} else {
|
2016-03-30 00:05:28 +00:00
|
|
|
return repoStatus(client, r, b, link)
|
2016-03-29 18:07:50 +00:00
|
|
|
}
|
|
|
|
}
|
2015-09-30 01:21:17 +00:00
|
|
|
|
2016-03-29 18:07:50 +00:00
|
|
|
func repoStatus(client *github.Client, r *model.Repo, b *model.Build, link string) error {
|
2015-09-30 01:21:17 +00:00
|
|
|
status := getStatus(b.Status)
|
|
|
|
desc := getDesc(b.Status)
|
|
|
|
data := github.RepoStatus{
|
2015-12-22 13:10:39 +00:00
|
|
|
Context: github.String("continuous-integration/drone"),
|
2015-09-30 01:21:17 +00:00
|
|
|
State: github.String(status),
|
|
|
|
Description: github.String(desc),
|
|
|
|
TargetURL: github.String(link),
|
|
|
|
}
|
|
|
|
_, _, err := client.Repositories.CreateStatus(r.Owner, r.Name, b.Commit, &data)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2016-04-29 19:39:56 +00:00
|
|
|
var reDeploy = regexp.MustCompile(".+/deployments/(\\d+)")
|
|
|
|
|
2016-03-29 18:07:50 +00:00
|
|
|
func deploymentStatus(client *github.Client, r *model.Repo, b *model.Build, link string) error {
|
2016-04-29 19:39:56 +00:00
|
|
|
matches := reDeploy.FindStringSubmatch(b.Link)
|
2016-03-30 00:05:28 +00:00
|
|
|
// if the deployment was not triggered from github, don't send a deployment status
|
|
|
|
if len(matches) != 2 {
|
|
|
|
return nil
|
|
|
|
}
|
2016-03-30 11:58:24 +00:00
|
|
|
// the deployment ID is only available in the the link to the build as the last element in the URL
|
|
|
|
id, _ := strconv.Atoi(matches[1])
|
2016-03-29 18:07:50 +00:00
|
|
|
status := getStatus(b.Status)
|
|
|
|
desc := getDesc(b.Status)
|
|
|
|
data := github.DeploymentStatusRequest{
|
2016-03-30 00:05:28 +00:00
|
|
|
State: github.String(status),
|
|
|
|
Description: github.String(desc),
|
|
|
|
TargetURL: github.String(link),
|
2016-03-29 18:07:50 +00:00
|
|
|
}
|
|
|
|
_, _, err := client.Repositories.CreateDeploymentStatus(r.Owner, r.Name, id, &data)
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2015-09-30 01:21:17 +00:00
|
|
|
// Netrc returns a .netrc file that can be used to clone
|
|
|
|
// private repositories from a remote system.
|
|
|
|
func (g *Github) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) {
|
|
|
|
url_, err := url.Parse(g.URL)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
netrc := &model.Netrc{}
|
|
|
|
netrc.Login = u.Token
|
|
|
|
netrc.Password = "x-oauth-basic"
|
|
|
|
netrc.Machine = url_.Host
|
|
|
|
return netrc, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Activate activates a repository by creating the post-commit hook and
|
|
|
|
// adding the SSH deploy key, if applicable.
|
2016-05-01 23:30:00 +00:00
|
|
|
func (g *Github) Activate(u *model.User, r *model.Repo, link string) error {
|
2015-09-30 01:21:17 +00:00
|
|
|
client := NewClient(g.API, u.Token, g.SkipVerify)
|
2016-04-29 19:39:56 +00:00
|
|
|
_, err := CreateUpdateHook(client, r.Owner, r.Name, link)
|
2015-09-30 01:21:17 +00:00
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
// Deactivate removes a repository by removing all the post-commit hooks
|
|
|
|
// which are equal to link and removing the SSH deploy key.
|
|
|
|
func (g *Github) Deactivate(u *model.User, r *model.Repo, link string) error {
|
|
|
|
client := NewClient(g.API, u.Token, g.SkipVerify)
|
|
|
|
return DeleteHook(client, r.Owner, r.Name, link)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Hook parses the post-commit hook from the Request body
|
|
|
|
// and returns the required data in a standard format.
|
|
|
|
func (g *Github) Hook(r *http.Request) (*model.Repo, *model.Build, error) {
|
|
|
|
|
|
|
|
switch r.Header.Get("X-Github-Event") {
|
|
|
|
case "pull_request":
|
|
|
|
return g.pullRequest(r)
|
|
|
|
case "push":
|
|
|
|
return g.push(r)
|
2015-10-27 00:31:26 +00:00
|
|
|
case "deployment":
|
|
|
|
return g.deployment(r)
|
2015-09-30 01:21:17 +00:00
|
|
|
default:
|
|
|
|
return nil, nil, nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// push parses a hook with event type `push` and returns
|
|
|
|
// the commit data.
|
|
|
|
func (g *Github) push(r *http.Request) (*model.Repo, *model.Build, error) {
|
|
|
|
payload := GetPayload(r)
|
|
|
|
hook := &pushHook{}
|
|
|
|
err := json.Unmarshal(payload, hook)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
if hook.Deleted {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
repo := &model.Repo{}
|
|
|
|
repo.Owner = hook.Repo.Owner.Login
|
|
|
|
if len(repo.Owner) == 0 {
|
|
|
|
repo.Owner = hook.Repo.Owner.Name
|
|
|
|
}
|
|
|
|
repo.Name = hook.Repo.Name
|
|
|
|
// Generating rather than using hook.Repo.FullName as it's
|
|
|
|
// not always present
|
|
|
|
repo.FullName = fmt.Sprintf("%s/%s", repo.Owner, repo.Name)
|
|
|
|
repo.Link = hook.Repo.HTMLURL
|
|
|
|
repo.IsPrivate = hook.Repo.Private
|
|
|
|
repo.Clone = hook.Repo.CloneURL
|
|
|
|
repo.Branch = hook.Repo.DefaultBranch
|
2015-10-27 20:03:37 +00:00
|
|
|
repo.Kind = model.RepoGit
|
2015-09-30 01:21:17 +00:00
|
|
|
|
|
|
|
build := &model.Build{}
|
|
|
|
build.Event = model.EventPush
|
|
|
|
build.Commit = hook.Head.ID
|
|
|
|
build.Ref = hook.Ref
|
|
|
|
build.Link = hook.Head.URL
|
|
|
|
build.Branch = strings.Replace(build.Ref, "refs/heads/", "", -1)
|
|
|
|
build.Message = hook.Head.Message
|
|
|
|
// build.Timestamp = hook.Head.Timestamp
|
2015-10-07 01:31:01 +00:00
|
|
|
build.Email = hook.Head.Author.Email
|
2015-09-30 01:21:17 +00:00
|
|
|
build.Avatar = hook.Sender.Avatar
|
|
|
|
build.Author = hook.Sender.Login
|
|
|
|
build.Remote = hook.Repo.CloneURL
|
|
|
|
|
2015-10-07 01:31:01 +00:00
|
|
|
if len(build.Author) == 0 {
|
|
|
|
build.Author = hook.Head.Author.Username
|
|
|
|
// default gravatar?
|
|
|
|
}
|
|
|
|
|
2015-10-26 20:10:46 +00:00
|
|
|
if strings.HasPrefix(build.Ref, "refs/tags/") {
|
|
|
|
// just kidding, this is actually a tag event
|
|
|
|
build.Event = model.EventTag
|
|
|
|
}
|
2015-09-30 01:21:17 +00:00
|
|
|
|
|
|
|
return repo, build, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// pullRequest parses a hook with event type `pullRequest`
|
|
|
|
// and returns the commit data.
|
|
|
|
func (g *Github) pullRequest(r *http.Request) (*model.Repo, *model.Build, error) {
|
|
|
|
payload := GetPayload(r)
|
|
|
|
hook := &struct {
|
|
|
|
Action string `json:"action"`
|
|
|
|
PullRequest *github.PullRequest `json:"pull_request"`
|
|
|
|
Repo *github.Repository `json:"repository"`
|
|
|
|
}{}
|
|
|
|
err := json.Unmarshal(payload, hook)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
// ignore these
|
|
|
|
if hook.Action != "opened" && hook.Action != "synchronize" {
|
|
|
|
return nil, nil, nil
|
|
|
|
}
|
|
|
|
if *hook.PullRequest.State != "open" {
|
|
|
|
return nil, nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
repo := &model.Repo{}
|
|
|
|
repo.Owner = *hook.Repo.Owner.Login
|
|
|
|
repo.Name = *hook.Repo.Name
|
|
|
|
repo.FullName = *hook.Repo.FullName
|
|
|
|
repo.Link = *hook.Repo.HTMLURL
|
|
|
|
repo.IsPrivate = *hook.Repo.Private
|
|
|
|
repo.Clone = *hook.Repo.CloneURL
|
2015-10-27 20:03:37 +00:00
|
|
|
repo.Kind = model.RepoGit
|
2015-09-30 01:21:17 +00:00
|
|
|
repo.Branch = "master"
|
|
|
|
if hook.Repo.DefaultBranch != nil {
|
|
|
|
repo.Branch = *hook.Repo.DefaultBranch
|
|
|
|
}
|
|
|
|
|
|
|
|
build := &model.Build{}
|
|
|
|
build.Event = model.EventPull
|
|
|
|
build.Commit = *hook.PullRequest.Head.SHA
|
2016-03-05 05:15:50 +00:00
|
|
|
build.Ref = fmt.Sprintf("refs/pull/%d/%s", *hook.PullRequest.Number, g.MergeRef)
|
2015-09-30 01:21:17 +00:00
|
|
|
build.Link = *hook.PullRequest.HTMLURL
|
|
|
|
build.Branch = *hook.PullRequest.Head.Ref
|
|
|
|
build.Message = *hook.PullRequest.Title
|
2015-11-11 21:41:45 +00:00
|
|
|
build.Author = *hook.PullRequest.User.Login
|
|
|
|
build.Avatar = *hook.PullRequest.User.AvatarURL
|
2015-09-30 01:21:17 +00:00
|
|
|
build.Remote = *hook.PullRequest.Base.Repo.CloneURL
|
|
|
|
build.Title = *hook.PullRequest.Title
|
|
|
|
// build.Timestamp = time.Now().UTC().Format("2006-01-02 15:04:05.000000000 +0000 MST")
|
|
|
|
|
|
|
|
return repo, build, nil
|
|
|
|
}
|
|
|
|
|
2015-10-27 00:31:26 +00:00
|
|
|
func (g *Github) deployment(r *http.Request) (*model.Repo, *model.Build, error) {
|
|
|
|
payload := GetPayload(r)
|
|
|
|
hook := &deployHook{}
|
|
|
|
|
|
|
|
err := json.Unmarshal(payload, hook)
|
|
|
|
if err != nil {
|
|
|
|
return nil, nil, err
|
|
|
|
}
|
|
|
|
|
2015-10-27 21:53:55 +00:00
|
|
|
// for older versions of GitHub. Remove.
|
|
|
|
if hook.Deployment.ID == 0 {
|
|
|
|
hook.Deployment.ID = hook.ID
|
|
|
|
hook.Deployment.Sha = hook.Sha
|
|
|
|
hook.Deployment.Ref = hook.Ref
|
|
|
|
hook.Deployment.Task = hook.Name
|
|
|
|
hook.Deployment.Env = hook.Env
|
|
|
|
hook.Deployment.Desc = hook.Desc
|
|
|
|
}
|
|
|
|
|
2015-10-27 00:31:26 +00:00
|
|
|
repo := &model.Repo{}
|
|
|
|
repo.Owner = hook.Repo.Owner.Login
|
|
|
|
if len(repo.Owner) == 0 {
|
|
|
|
repo.Owner = hook.Repo.Owner.Name
|
|
|
|
}
|
|
|
|
repo.Name = hook.Repo.Name
|
|
|
|
repo.FullName = fmt.Sprintf("%s/%s", repo.Owner, repo.Name)
|
|
|
|
repo.Link = hook.Repo.HTMLURL
|
|
|
|
repo.IsPrivate = hook.Repo.Private
|
|
|
|
repo.Clone = hook.Repo.CloneURL
|
|
|
|
repo.Branch = hook.Repo.DefaultBranch
|
2015-10-27 20:03:37 +00:00
|
|
|
repo.Kind = model.RepoGit
|
2015-10-27 00:31:26 +00:00
|
|
|
|
|
|
|
// ref can be
|
|
|
|
// branch, tag, or sha
|
|
|
|
|
|
|
|
build := &model.Build{}
|
|
|
|
build.Event = model.EventDeploy
|
|
|
|
build.Commit = hook.Deployment.Sha
|
|
|
|
build.Link = hook.Deployment.Url
|
|
|
|
build.Message = hook.Deployment.Desc
|
|
|
|
build.Avatar = hook.Sender.Avatar
|
|
|
|
build.Author = hook.Sender.Login
|
|
|
|
build.Ref = hook.Deployment.Ref
|
|
|
|
build.Branch = hook.Deployment.Ref
|
2015-10-27 20:09:13 +00:00
|
|
|
build.Deploy = hook.Deployment.Env
|
2015-10-27 00:31:26 +00:00
|
|
|
|
|
|
|
// if the ref is a sha or short sha we need to manually
|
|
|
|
// construct the ref.
|
|
|
|
if strings.HasPrefix(build.Commit, build.Ref) || build.Commit == build.Ref {
|
|
|
|
build.Branch = repo.Branch
|
|
|
|
build.Ref = fmt.Sprintf("refs/heads/%s", repo.Branch)
|
|
|
|
|
|
|
|
}
|
|
|
|
// if the ref is a branch we should make sure it has refs/heads prefix
|
|
|
|
if !strings.HasPrefix(build.Ref, "refs/") { // branch or tag
|
|
|
|
build.Ref = fmt.Sprintf("refs/heads/%s", build.Branch)
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return repo, build, nil
|
|
|
|
}
|
|
|
|
|
2015-10-27 23:48:05 +00:00
|
|
|
func (g *Github) String() string {
|
|
|
|
return "github"
|
|
|
|
}
|
|
|
|
|
2015-09-30 01:21:17 +00:00
|
|
|
const (
|
|
|
|
StatusPending = "pending"
|
|
|
|
StatusSuccess = "success"
|
|
|
|
StatusFailure = "failure"
|
|
|
|
StatusError = "error"
|
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
DescPending = "this build is pending"
|
|
|
|
DescSuccess = "the build was successful"
|
|
|
|
DescFailure = "the build failed"
|
|
|
|
DescError = "oops, something went wrong"
|
|
|
|
)
|
|
|
|
|
|
|
|
// getStatus is a helper functin that converts a Drone
|
|
|
|
// status to a GitHub status.
|
|
|
|
func getStatus(status string) string {
|
|
|
|
switch status {
|
|
|
|
case model.StatusPending, model.StatusRunning:
|
|
|
|
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.StatusPending, model.StatusRunning:
|
|
|
|
return DescPending
|
|
|
|
case model.StatusSuccess:
|
|
|
|
return DescSuccess
|
|
|
|
case model.StatusFailure:
|
|
|
|
return DescFailure
|
|
|
|
case model.StatusError, model.StatusKilled:
|
|
|
|
return DescError
|
|
|
|
default:
|
|
|
|
return DescError
|
|
|
|
}
|
|
|
|
}
|