Initial take at the bitbucket server remote additions.
This commit is contained in:
parent
d7e108688b
commit
59edcd3389
6 changed files with 644 additions and 0 deletions
1
Makefile
1
Makefile
|
@ -12,6 +12,7 @@ deps:
|
||||||
go get -u github.com/elazarl/go-bindata-assetfs/...
|
go get -u github.com/elazarl/go-bindata-assetfs/...
|
||||||
go get -u github.com/dchest/jsmin
|
go get -u github.com/dchest/jsmin
|
||||||
go get -u github.com/franela/goblin
|
go get -u github.com/franela/goblin
|
||||||
|
go get -u github.com/mrjones/oauth
|
||||||
|
|
||||||
gen: gen_static gen_template gen_migrations
|
gen: gen_static gen_template gen_migrations
|
||||||
|
|
||||||
|
|
343
remote/bitbucketserver/bitbucketserver.go
Normal file
343
remote/bitbucketserver/bitbucketserver.go
Normal file
|
@ -0,0 +1,343 @@
|
||||||
|
package bitbucketserver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/drone/drone/shared/envconfig"
|
||||||
|
"net/url"
|
||||||
|
log "github.com/Sirupsen/logrus"
|
||||||
|
"net/http"
|
||||||
|
"github.com/drone/drone/model"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"strconv"
|
||||||
|
"encoding/json"
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
type BitbucketServer struct {
|
||||||
|
URL string
|
||||||
|
ConsumerKey string
|
||||||
|
GitUserName string
|
||||||
|
GitPassword string
|
||||||
|
Open bool
|
||||||
|
}
|
||||||
|
|
||||||
|
func Load(env envconfig.Env) *BitbucketServer{
|
||||||
|
|
||||||
|
//Read
|
||||||
|
config := env.String("REMOTE_CONFIG", "")
|
||||||
|
gitUserName := env.String("GIT_USERNAME", "")
|
||||||
|
gitUserPassword := env.String("GIT_USERPASSWORD","")
|
||||||
|
|
||||||
|
url_, err := url.Parse(config)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln("unable to parse remote dsn. %s", err)
|
||||||
|
}
|
||||||
|
params := url_.Query()
|
||||||
|
url_.Path = ""
|
||||||
|
url_.RawQuery = ""
|
||||||
|
|
||||||
|
bitbucketserver := BitbucketServer{}
|
||||||
|
bitbucketserver.URL = url_.String()
|
||||||
|
bitbucketserver.GitUserName = gitUserName
|
||||||
|
bitbucketserver.GitPassword = gitUserPassword
|
||||||
|
bitbucketserver.ConsumerKey = params.Get("consumer_key")
|
||||||
|
bitbucketserver.Open, _ = strconv.ParseBool(params.Get("open"))
|
||||||
|
|
||||||
|
return &bitbucketserver
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bs *BitbucketServer) Login(res http.ResponseWriter, req *http.Request) (*model.User, bool, error){
|
||||||
|
log.Info("Starting to login for bitbucketServer")
|
||||||
|
|
||||||
|
c := NewClient(bs.ConsumerKey, bs.URL)
|
||||||
|
|
||||||
|
log.Info("getting the requestToken")
|
||||||
|
requestToken, url, err := c.GetRequestTokenAndUrl("oob")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var code = req.FormValue("oauth_verifier")
|
||||||
|
if len(code) == 0 {
|
||||||
|
log.Info("redirecting to %s", url)
|
||||||
|
http.Redirect(res, req, url, http.StatusSeeOther)
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var request_oauth_token = req.FormValue("oauth_token")
|
||||||
|
requestToken.Token = request_oauth_token
|
||||||
|
accessToken, err := c.AuthorizeToken(requestToken, code)
|
||||||
|
if err !=nil {
|
||||||
|
log.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := c.MakeHttpClient(accessToken)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
response, err := client.Get(bs.URL + "/plugins/servlet/applinks/whoami")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
bits, err := ioutil.ReadAll(response.Body)
|
||||||
|
userName := string(bits)
|
||||||
|
|
||||||
|
response1, err := client.Get(bs.URL + "/rest/api/1.0/users/" +userName)
|
||||||
|
contents, err := ioutil.ReadAll(response1.Body)
|
||||||
|
defer response1.Body.Close()
|
||||||
|
var mUser User
|
||||||
|
json.Unmarshal(contents, &mUser)
|
||||||
|
|
||||||
|
user := model.User{}
|
||||||
|
user.Login = userName
|
||||||
|
user.Email = mUser.EmailAddress
|
||||||
|
user.Token = accessToken.Token
|
||||||
|
|
||||||
|
user.Avatar = avatarLink(mUser.EmailAddress)
|
||||||
|
|
||||||
|
|
||||||
|
return &user, bs.Open, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bs *BitbucketServer) Auth(token, secret string) (string, error) {
|
||||||
|
log.Info("Staring to auth for bitbucketServer. %s", token)
|
||||||
|
if len(token) == 0 {
|
||||||
|
return "", fmt.Errorf("Hasn't logged in yet")
|
||||||
|
}
|
||||||
|
return token, nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bs *BitbucketServer) Repo(u *model.User, owner, name string) (*model.Repo, error){
|
||||||
|
log.Info("Staring repo for bitbucketServer with user " + u.Login + " " + owner + " " + name )
|
||||||
|
|
||||||
|
client := NewClientWithToken(bs.ConsumerKey, bs.URL, u.Token)
|
||||||
|
|
||||||
|
url := bs.URL + "/rest/api/1.0/projects/" + owner + "/repos/" + name
|
||||||
|
log.Info("Trying to get " + url)
|
||||||
|
response, err := client.Get(url)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
contents, err := ioutil.ReadAll(response.Body)
|
||||||
|
bsRepo := BSRepo{}
|
||||||
|
json.Unmarshal(contents, &bsRepo)
|
||||||
|
|
||||||
|
cloneLink := ""
|
||||||
|
repoLink := ""
|
||||||
|
|
||||||
|
for _, item := range bsRepo.Links.Clone {
|
||||||
|
if item.Name == "http" {
|
||||||
|
cloneLink = item.Href
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for _, item := range bsRepo.Links.Self {
|
||||||
|
if item.Href != "" {
|
||||||
|
repoLink = item.Href
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//TODO: get the real allow tag+ infomration
|
||||||
|
repo := &model.Repo{}
|
||||||
|
repo.Clone = cloneLink
|
||||||
|
repo.Link = repoLink
|
||||||
|
repo.Name=bsRepo.Slug
|
||||||
|
repo.Owner=bsRepo.Project.Key
|
||||||
|
repo.AllowTag=false
|
||||||
|
repo.AllowDeploy=false
|
||||||
|
repo.AllowPull=false
|
||||||
|
repo.AllowPush=true
|
||||||
|
repo.FullName = bsRepo.Project.Key +"/" +bsRepo.Slug
|
||||||
|
repo.Branch = "master"
|
||||||
|
repo.Kind = model.RepoGit
|
||||||
|
|
||||||
|
|
||||||
|
return repo, nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func (bs *BitbucketServer) Repos(u *model.User) ([]*model.RepoLite, error){
|
||||||
|
log.Info("Staring repos for bitbucketServer " + u.Login)
|
||||||
|
var repos = []*model.RepoLite{}
|
||||||
|
|
||||||
|
client := NewClientWithToken(bs.ConsumerKey, bs.URL, u.Token)
|
||||||
|
|
||||||
|
response, err := client.Get(bs.URL + "/rest/api/1.0/repos?limit=10000")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
contents, err := ioutil.ReadAll(response.Body)
|
||||||
|
var repoResponse Repos
|
||||||
|
json.Unmarshal(contents, &repoResponse)
|
||||||
|
|
||||||
|
for _, repo := range repoResponse.Values {
|
||||||
|
repos = append(repos, &model.RepoLite{
|
||||||
|
Name: repo.Slug,
|
||||||
|
FullName: repo.Project.Key + "/" + repo.Slug,
|
||||||
|
Owner: repo.Project.Key,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return repos, nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bs *BitbucketServer) Perm(u *model.User, owner, repo string) (*model.Perm, error){
|
||||||
|
|
||||||
|
//TODO: find the real permissions
|
||||||
|
log.Info("Staring perm for bitbucketServer")
|
||||||
|
perms := new(model.Perm)
|
||||||
|
perms.Pull = true
|
||||||
|
perms.Admin = true
|
||||||
|
perms.Push = true
|
||||||
|
return perms , nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bs *BitbucketServer) File(u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error){
|
||||||
|
log.Info(fmt.Sprintf("Staring file for bitbucketServer login: %s repo: %s buildevent: %s string: %s",u.Login, r.Name, b.Event, f))
|
||||||
|
|
||||||
|
client := NewClientWithToken(bs.ConsumerKey, bs.URL, u.Token)
|
||||||
|
fileURL := fmt.Sprintf("%s/projects/%s/repos/%s/browse/%s?raw", bs.URL,r.Owner,r.Name,f)
|
||||||
|
log.Info(fileURL)
|
||||||
|
response, err := client.Get(fileURL)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
if response.StatusCode == 404 {
|
||||||
|
return nil,nil
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
responseBytes, err := ioutil.ReadAll(response.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return responseBytes, nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bs *BitbucketServer) Status(u *model.User, r *model.Repo, b *model.Build, link string) error{
|
||||||
|
log.Info("Staring status for bitbucketServer")
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bs *BitbucketServer) Netrc(user *model.User, r *model.Repo) (*model.Netrc, error){
|
||||||
|
log.Info("Starting the Netrc lookup")
|
||||||
|
u, err := url.Parse(bs.URL)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
return &model.Netrc{
|
||||||
|
Machine: u.Host,
|
||||||
|
Login: bs.GitUserName,
|
||||||
|
Password: bs.GitPassword,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bs *BitbucketServer) Activate(u *model.User, r *model.Repo, k *model.Key, link string) error{
|
||||||
|
log.Info(fmt.Sprintf("Staring activate for bitbucketServer user: %s repo: %s key: %s link: %s",u.Login,r.Name,k,link))
|
||||||
|
client := NewClientWithToken(bs.ConsumerKey, bs.URL, u.Token)
|
||||||
|
hook, err := bs.CreateHook(client, r.Owner,r.Name, "com.atlassian.stash.plugin.stash-web-post-receive-hooks-plugin:postReceiveHook",link)
|
||||||
|
if err !=nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
log.Info(hook)
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bs *BitbucketServer) Deactivate(u *model.User, r *model.Repo, link string) error{
|
||||||
|
log.Info(fmt.Sprintf("Staring deactivating for bitbucketServer user: %s repo: %s link: %s",u.Login,r.Name,link))
|
||||||
|
client := NewClientWithToken(bs.ConsumerKey, bs.URL, u.Token)
|
||||||
|
err := bs.DeleteHook(client, r.Owner,r.Name, "com.atlassian.stash.plugin.stash-web-post-receive-hooks-plugin:postReceiveHook",link)
|
||||||
|
if err !=nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
func (bs *BitbucketServer) Hook(r *http.Request) (*model.Repo, *model.Build, error){
|
||||||
|
log.Info("Staring hook for bitbucketServer")
|
||||||
|
defer r.Body.Close()
|
||||||
|
contents, err := ioutil.ReadAll(r.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Info(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var hookPost postHook
|
||||||
|
json.Unmarshal(contents, &hookPost)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
buildModel := &model.Build{}
|
||||||
|
buildModel.Event = model.EventPush
|
||||||
|
buildModel.Ref = hookPost.RefChanges[0].RefID
|
||||||
|
buildModel.Author = hookPost.Changesets.Values[0].ToCommit.Author.EmailAddress
|
||||||
|
buildModel.Commit = hookPost.RefChanges[0].RefID
|
||||||
|
buildModel.Avatar = avatarLink(hookPost.Changesets.Values[0].ToCommit.Author.EmailAddress)
|
||||||
|
|
||||||
|
//All you really need is the name and owner. That's what creates the lookup key, so it needs to match the repo info. Just an FYI
|
||||||
|
repo := &model.Repo{}
|
||||||
|
repo.Name=hookPost.Repository.Slug
|
||||||
|
repo.Owner = hookPost.Repository.Project.Key
|
||||||
|
repo.AllowTag=false
|
||||||
|
repo.AllowDeploy=false
|
||||||
|
repo.AllowPull=false
|
||||||
|
repo.AllowPush=true
|
||||||
|
repo.FullName = hookPost.Repository.Project.Key +"/" +hookPost.Repository.Slug
|
||||||
|
repo.Branch = "master"
|
||||||
|
repo.Kind = model.RepoGit
|
||||||
|
|
||||||
|
return repo, buildModel, nil;
|
||||||
|
}
|
||||||
|
func (bs *BitbucketServer) String() string {
|
||||||
|
return "bitbucketserver"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
type HookDetail struct {
|
||||||
|
Key string `"json:key"`
|
||||||
|
Name string `"json:name"`
|
||||||
|
Type string `"json:type"`
|
||||||
|
Description string `"json:description"`
|
||||||
|
Version string `"json:version"`
|
||||||
|
ConfigFormKey string `"json:configFormKey"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Hook struct {
|
||||||
|
Enabled bool `"json:enabled"`
|
||||||
|
Details *HookDetail `"json:details"`
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Enable hook for named repository
|
||||||
|
func (bs *BitbucketServer)CreateHook(client *http.Client, project, slug, hook_key, link string) (*Hook, error) {
|
||||||
|
|
||||||
|
// Set hook
|
||||||
|
hookBytes := []byte(fmt.Sprintf(`{"hook-url-0":"%s"}`,link))
|
||||||
|
|
||||||
|
// Enable hook
|
||||||
|
enablePath := fmt.Sprintf("/rest/api/1.0/projects/%s/repos/%s/settings/hooks/%s/enabled",
|
||||||
|
project, slug, hook_key)
|
||||||
|
|
||||||
|
doPut(client, bs.URL + enablePath, hookBytes)
|
||||||
|
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Disable hook for named repository
|
||||||
|
func (bs *BitbucketServer)DeleteHook(client *http.Client, project, slug, hook_key, link string) error {
|
||||||
|
enablePath := fmt.Sprintf("/rest/api/1.0/projects/%s/repos/%s/settings/hooks/%s/enabled",
|
||||||
|
project, slug, hook_key)
|
||||||
|
doDelete(client, bs.URL + enablePath)
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
61
remote/bitbucketserver/client.go
Normal file
61
remote/bitbucketserver/client.go
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
package bitbucketserver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"crypto/tls"
|
||||||
|
log "github.com/Sirupsen/logrus"
|
||||||
|
"io/ioutil"
|
||||||
|
"encoding/pem"
|
||||||
|
"crypto/x509"
|
||||||
|
"github.com/mrjones/oauth"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
func NewClient(ConsumerKey string, URL string) *oauth.Consumer{
|
||||||
|
privateKeyFileContents, err := ioutil.ReadFile("/private_key.pem")
|
||||||
|
log.Info("Tried to read the key")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
block, _ := pem.Decode([]byte(privateKeyFileContents))
|
||||||
|
privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
c := oauth.NewRSAConsumer(
|
||||||
|
ConsumerKey,
|
||||||
|
privateKey,
|
||||||
|
oauth.ServiceProvider{
|
||||||
|
RequestTokenUrl: URL + "/plugins/servlet/oauth/request-token",
|
||||||
|
AuthorizeTokenUrl: URL + "/plugins/servlet/oauth/authorize",
|
||||||
|
AccessTokenUrl: URL + "/plugins/servlet/oauth/access-token",
|
||||||
|
HttpMethod: "POST",
|
||||||
|
})
|
||||||
|
c.HttpClient = &http.Client{
|
||||||
|
Transport: &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewClientWithToken(ConsumerKey string, URL string, AccessToken string) *http.Client{
|
||||||
|
NewClient(ConsumerKey, URL)
|
||||||
|
c := NewClient(ConsumerKey, URL)
|
||||||
|
|
||||||
|
var token oauth.AccessToken
|
||||||
|
token.Token = AccessToken
|
||||||
|
client, err := c.MakeHttpClient(&token)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
return client
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
63
remote/bitbucketserver/helper.go
Normal file
63
remote/bitbucketserver/helper.go
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
package bitbucketserver
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
"bytes"
|
||||||
|
"log"
|
||||||
|
"io/ioutil"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"crypto/md5"
|
||||||
|
log "github.com/Sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func avatarLink(email string) (url string) {
|
||||||
|
data := []byte(strings.ToLower(email))
|
||||||
|
emailHash := md5.Sum(data)
|
||||||
|
avatarURL := fmt.Sprintf("http://www.gravatar.com/avatar/%s.jpg",emailHash)
|
||||||
|
log.Info(avatarURL)
|
||||||
|
return avatarURL
|
||||||
|
}
|
||||||
|
|
||||||
|
func doPut(client *http.Client, url string, body []byte) {
|
||||||
|
request, err := http.NewRequest("PUT", url, bytes.NewBuffer(body))
|
||||||
|
request.Header.Add("Content-Type","application/json")
|
||||||
|
response, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
} else {
|
||||||
|
defer response.Body.Close()
|
||||||
|
contents, err := ioutil.ReadAll(response.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
fmt.Println("The calculated length is:", len(string(contents)), "for the url:", url)
|
||||||
|
fmt.Println(" ", response.StatusCode)
|
||||||
|
hdr := response.Header
|
||||||
|
for key, value := range hdr {
|
||||||
|
fmt.Println(" ", key, ":", value)
|
||||||
|
}
|
||||||
|
fmt.Println(string(contents))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func doDelete(client *http.Client, url string) {
|
||||||
|
request, err := http.NewRequest("DELETE", url, nil)
|
||||||
|
response, err := client.Do(request)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
} else {
|
||||||
|
defer response.Body.Close()
|
||||||
|
contents, err := ioutil.ReadAll(response.Body)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
fmt.Println("The calculated length is:", len(string(contents)), "for the url:", url)
|
||||||
|
fmt.Println(" ", response.StatusCode)
|
||||||
|
hdr := response.Header
|
||||||
|
for key, value := range hdr {
|
||||||
|
fmt.Println(" ", key, ":", value)
|
||||||
|
}
|
||||||
|
fmt.Println(string(contents))
|
||||||
|
}
|
||||||
|
}
|
173
remote/bitbucketserver/types.go
Normal file
173
remote/bitbucketserver/types.go
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
package bitbucketserver
|
||||||
|
|
||||||
|
|
||||||
|
type postHook struct {
|
||||||
|
Changesets struct {
|
||||||
|
Filter interface{} `json:"filter"`
|
||||||
|
IsLastPage bool `json:"isLastPage"`
|
||||||
|
Limit int `json:"limit"`
|
||||||
|
Size int `json:"size"`
|
||||||
|
Start int `json:"start"`
|
||||||
|
Values []struct {
|
||||||
|
Changes struct {
|
||||||
|
Filter interface{} `json:"filter"`
|
||||||
|
IsLastPage bool `json:"isLastPage"`
|
||||||
|
Limit int `json:"limit"`
|
||||||
|
Size int `json:"size"`
|
||||||
|
Start int `json:"start"`
|
||||||
|
Values []struct {
|
||||||
|
ContentID string `json:"contentId"`
|
||||||
|
Executable bool `json:"executable"`
|
||||||
|
Link struct {
|
||||||
|
Rel string `json:"rel"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
} `json:"link"`
|
||||||
|
NodeType string `json:"nodeType"`
|
||||||
|
Path struct {
|
||||||
|
Components []string `json:"components"`
|
||||||
|
Extension string `json:"extension"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Parent string `json:"parent"`
|
||||||
|
ToString string `json:"toString"`
|
||||||
|
} `json:"path"`
|
||||||
|
PercentUnchanged int `json:"percentUnchanged"`
|
||||||
|
SrcExecutable bool `json:"srcExecutable"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
} `json:"values"`
|
||||||
|
} `json:"changes"`
|
||||||
|
FromCommit struct {
|
||||||
|
DisplayID string `json:"displayId"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
} `json:"fromCommit"`
|
||||||
|
Link struct {
|
||||||
|
Rel string `json:"rel"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
} `json:"link"`
|
||||||
|
ToCommit struct {
|
||||||
|
Author struct {
|
||||||
|
EmailAddress string `json:"emailAddress"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
} `json:"author"`
|
||||||
|
AuthorTimestamp int `json:"authorTimestamp"`
|
||||||
|
DisplayID string `json:"displayId"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
Parents []struct {
|
||||||
|
DisplayID string `json:"displayId"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
} `json:"parents"`
|
||||||
|
} `json:"toCommit"`
|
||||||
|
} `json:"values"`
|
||||||
|
} `json:"changesets"`
|
||||||
|
RefChanges []struct {
|
||||||
|
FromHash string `json:"fromHash"`
|
||||||
|
RefID string `json:"refId"`
|
||||||
|
ToHash string `json:"toHash"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
} `json:"refChanges"`
|
||||||
|
Repository struct {
|
||||||
|
Forkable bool `json:"forkable"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Project struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
IsPersonal bool `json:"isPersonal"`
|
||||||
|
Key string `json:"key"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Public bool `json:"public"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
} `json:"project"`
|
||||||
|
Public bool `json:"public"`
|
||||||
|
ScmID string `json:"scmId"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
|
State string `json:"state"`
|
||||||
|
StatusMessage string `json:"statusMessage"`
|
||||||
|
} `json:"repository"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Repos struct {
|
||||||
|
IsLastPage bool `json:"isLastPage"`
|
||||||
|
Limit int `json:"limit"`
|
||||||
|
Size int `json:"size"`
|
||||||
|
Start int `json:"start"`
|
||||||
|
Values []struct {
|
||||||
|
Forkable bool `json:"forkable"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
Links struct {
|
||||||
|
Clone []struct {
|
||||||
|
Href string `json:"href"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
} `json:"clone"`
|
||||||
|
Self []struct {
|
||||||
|
Href string `json:"href"`
|
||||||
|
} `json:"self"`
|
||||||
|
} `json:"links"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Project struct {
|
||||||
|
Description string `json:"description"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
Key string `json:"key"`
|
||||||
|
Links struct {
|
||||||
|
Self []struct {
|
||||||
|
Href string `json:"href"`
|
||||||
|
} `json:"self"`
|
||||||
|
} `json:"links"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Public bool `json:"public"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
} `json:"project"`
|
||||||
|
Public bool `json:"public"`
|
||||||
|
ScmID string `json:"scmId"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
|
State string `json:"state"`
|
||||||
|
StatusMessage string `json:"statusMessage"`
|
||||||
|
} `json:"values"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
Active bool `json:"active"`
|
||||||
|
DisplayName string `json:"displayName"`
|
||||||
|
EmailAddress string `json:"emailAddress"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
Links struct {
|
||||||
|
Self []struct {
|
||||||
|
Href string `json:"href"`
|
||||||
|
} `json:"self"`
|
||||||
|
} `json:"links"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type BSRepo struct {
|
||||||
|
Forkable bool `json:"forkable"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
Links struct {
|
||||||
|
Clone []struct {
|
||||||
|
Href string `json:"href"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
} `json:"clone"`
|
||||||
|
Self []struct {
|
||||||
|
Href string `json:"href"`
|
||||||
|
} `json:"self"`
|
||||||
|
} `json:"links"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Project struct {
|
||||||
|
Description string `json:"description"`
|
||||||
|
ID int `json:"id"`
|
||||||
|
Key string `json:"key"`
|
||||||
|
Links struct {
|
||||||
|
Self []struct {
|
||||||
|
Href string `json:"href"`
|
||||||
|
} `json:"self"`
|
||||||
|
} `json:"links"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Public bool `json:"public"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
} `json:"project"`
|
||||||
|
Public bool `json:"public"`
|
||||||
|
ScmID string `json:"scmId"`
|
||||||
|
Slug string `json:"slug"`
|
||||||
|
State string `json:"state"`
|
||||||
|
StatusMessage string `json:"statusMessage"`
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import (
|
||||||
|
|
||||||
"github.com/drone/drone/model"
|
"github.com/drone/drone/model"
|
||||||
"github.com/drone/drone/remote/bitbucket"
|
"github.com/drone/drone/remote/bitbucket"
|
||||||
|
"github.com/drone/drone/remote/bitbucketserver"
|
||||||
"github.com/drone/drone/remote/github"
|
"github.com/drone/drone/remote/github"
|
||||||
"github.com/drone/drone/remote/gitlab"
|
"github.com/drone/drone/remote/gitlab"
|
||||||
"github.com/drone/drone/remote/gogs"
|
"github.com/drone/drone/remote/gogs"
|
||||||
|
@ -28,6 +29,8 @@ func Load(env envconfig.Env) Remote {
|
||||||
return gitlab.Load(env)
|
return gitlab.Load(env)
|
||||||
case "gogs":
|
case "gogs":
|
||||||
return gogs.Load(env)
|
return gogs.Load(env)
|
||||||
|
case "bitbucketserver":
|
||||||
|
return bitbucketserver.Load(env)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
logrus.Fatalf("unknown remote driver %s", driver)
|
logrus.Fatalf("unknown remote driver %s", driver)
|
||||||
|
|
Loading…
Reference in a new issue