mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-02-03 05:02:23 +00:00
Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
31f1b8620c
44 changed files with 1144 additions and 97 deletions
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
FROM centurylink/ca-certs
|
FROM centurylink/ca-certs
|
||||||
EXPOSE 8000
|
EXPOSE 8000
|
||||||
|
ADD contrib/docker/etc/nsswitch.conf /etc/
|
||||||
|
|
||||||
ENV DATABASE_DRIVER=sqlite3
|
ENV DATABASE_DRIVER=sqlite3
|
||||||
ENV DATABASE_CONFIG=/var/lib/drone/drone.sqlite
|
ENV DATABASE_CONFIG=/var/lib/drone/drone.sqlite
|
||||||
|
|
4
cache/cache.go
vendored
4
cache/cache.go
vendored
|
@ -21,9 +21,9 @@ func Set(c context.Context, key string, value interface{}) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Default creates an in-memory cache with the default
|
// Default creates an in-memory cache with the default
|
||||||
// 24 hour expiration period.
|
// 30 minute expiration period.
|
||||||
func Default() Cache {
|
func Default() Cache {
|
||||||
return cache.NewMemoryWithTTL(time.Hour * 24)
|
return cache.NewMemoryWithTTL(time.Minute * 30)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewTTL returns an in-memory cache with the specified
|
// NewTTL returns an in-memory cache with the specified
|
||||||
|
|
19
contrib/docker/etc/nsswitch.conf
Normal file
19
contrib/docker/etc/nsswitch.conf
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
# /etc/nsswitch.conf
|
||||||
|
#
|
||||||
|
# Example configuration of GNU Name Service Switch functionality.
|
||||||
|
# If you have the `glibc-doc-reference' and `info' packages installed, try:
|
||||||
|
# `info libc "Name Service Switch"' for information about this file.
|
||||||
|
|
||||||
|
passwd: compat
|
||||||
|
group: compat
|
||||||
|
shadow: compat
|
||||||
|
|
||||||
|
hosts: files dns
|
||||||
|
networks: files
|
||||||
|
|
||||||
|
protocols: files
|
||||||
|
services: files
|
||||||
|
ethers: files
|
||||||
|
rpc: files
|
||||||
|
|
||||||
|
netgroup: nis
|
|
@ -1,9 +1,12 @@
|
||||||
package controller
|
package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
"github.com/drone/drone/model"
|
"github.com/drone/drone/model"
|
||||||
|
"github.com/drone/drone/shared/httputil"
|
||||||
"github.com/drone/drone/store"
|
"github.com/drone/drone/store"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -73,6 +76,7 @@ func GetCC(c *gin.Context) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cc := model.NewCC(repo, builds[0], "")
|
url := fmt.Sprintf("%s/%s/%d", httputil.GetURL(c.Request), repo.FullName, builds[0].Number)
|
||||||
|
cc := model.NewCC(repo, builds[0], url)
|
||||||
c.XML(200, cc)
|
c.XML(200, cc)
|
||||||
}
|
}
|
||||||
|
|
|
@ -267,6 +267,7 @@ func PostBuild(c *gin.Context) {
|
||||||
Link: httputil.GetURL(c.Request),
|
Link: httputil.GetURL(c.Request),
|
||||||
Plugins: strings.Split(os.Getenv("PLUGIN_FILTER"), " "),
|
Plugins: strings.Split(os.Getenv("PLUGIN_FILTER"), " "),
|
||||||
Globals: strings.Split(os.Getenv("PLUGIN_PARAMS"), " "),
|
Globals: strings.Split(os.Getenv("PLUGIN_PARAMS"), " "),
|
||||||
|
Escalates: strings.Split(os.Getenv("ESCALATE_FILTER"), " "),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -2,11 +2,12 @@ package controller
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/gin-gonic/gin"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/gin-gonic/gin"
|
||||||
|
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
"github.com/drone/drone/engine"
|
"github.com/drone/drone/engine"
|
||||||
|
@ -217,6 +218,7 @@ func PostHook(c *gin.Context) {
|
||||||
Link: httputil.GetURL(c.Request),
|
Link: httputil.GetURL(c.Request),
|
||||||
Plugins: strings.Split(os.Getenv("PLUGIN_FILTER"), " "),
|
Plugins: strings.Split(os.Getenv("PLUGIN_FILTER"), " "),
|
||||||
Globals: strings.Split(os.Getenv("PLUGIN_PARAMS"), " "),
|
Globals: strings.Split(os.Getenv("PLUGIN_PARAMS"), " "),
|
||||||
|
Escalates: strings.Split(os.Getenv("ESCALATE_FILTER"), " "),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ func GetLogin(c *gin.Context) {
|
||||||
|
|
||||||
// when dealing with redirects we may need
|
// when dealing with redirects we may need
|
||||||
// to adjust the content type. I cannot, however,
|
// to adjust the content type. I cannot, however,
|
||||||
// rememver why, so need to revisit this line.
|
// remember why, so need to revisit this line.
|
||||||
c.Writer.Header().Del("Content-Type")
|
c.Writer.Header().Del("Content-Type")
|
||||||
|
|
||||||
tmpuser, open, err := remote.Login(c.Writer, c.Request)
|
tmpuser, open, err := remote.Login(c.Writer, c.Request)
|
||||||
|
|
|
@ -12,7 +12,7 @@ REMOTE_CONFIG=https://gogs.hooli.com?open=false
|
||||||
The following is the standard URI connection scheme:
|
The following is the standard URI connection scheme:
|
||||||
|
|
||||||
```
|
```
|
||||||
scheme://host[:port][?options]
|
scheme://host[:port][/path][?options]
|
||||||
```
|
```
|
||||||
|
|
||||||
The components of this string are:
|
The components of this string are:
|
||||||
|
@ -20,6 +20,7 @@ The components of this string are:
|
||||||
* `scheme` server protocol `http` or `https`.
|
* `scheme` server protocol `http` or `https`.
|
||||||
* `host` server address to connect to. The default value is github.com if not specified.
|
* `host` server address to connect to. The default value is github.com if not specified.
|
||||||
* `:port` optional. The default value is :80 if not specified.
|
* `:port` optional. The default value is :80 if not specified.
|
||||||
|
* `/path` optional. The default value is the root directory if not specified.
|
||||||
* `?options` connection specific options.
|
* `?options` connection specific options.
|
||||||
|
|
||||||
## Gogs options
|
## Gogs options
|
||||||
|
|
|
@ -19,3 +19,13 @@ Whitelist official Drone plugins and registry user `octocat`
|
||||||
```
|
```
|
||||||
PLUGIN_FILTER=plugins/* octocat/*
|
PLUGIN_FILTER=plugins/* octocat/*
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Additionally, some plugins may require to be execute as a "privileged" container.
|
||||||
|
This mode is most common for plugins that are attempting to run docker in docker type behaviors (for example the plugins/docker requires this mode).
|
||||||
|
Drone will ship will a default pattern that will allow selected official Drone plugins to run in an privileged mode.
|
||||||
|
This whitelist can be customized by setting the `ESCALATE_FILTER` environment variable.
|
||||||
|
This is a space-separated list and includes glob matching capabilities.
|
||||||
|
|
||||||
|
```
|
||||||
|
ESCALATE_FILTER=plugins/drone-docker plugins/drone-ecr plugins/drone-gcr
|
||||||
|
```
|
||||||
|
|
|
@ -5,4 +5,5 @@ type System struct {
|
||||||
Link string `json:"link_url"`
|
Link string `json:"link_url"`
|
||||||
Plugins []string `json:"plugins"`
|
Plugins []string `json:"plugins"`
|
||||||
Globals []string `json:"globals"`
|
Globals []string `json:"globals"`
|
||||||
|
Escalates []string `json:"privileged_plugins"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -230,7 +230,7 @@ func (g *Github) Status(u *model.User, r *model.Repo, b *model.Build, link strin
|
||||||
status := getStatus(b.Status)
|
status := getStatus(b.Status)
|
||||||
desc := getDesc(b.Status)
|
desc := getDesc(b.Status)
|
||||||
data := github.RepoStatus{
|
data := github.RepoStatus{
|
||||||
Context: github.String("Drone"),
|
Context: github.String("continuous-integration/drone"),
|
||||||
State: github.String(status),
|
State: github.String(status),
|
||||||
Description: github.String(desc),
|
Description: github.String(desc),
|
||||||
TargetURL: github.String(link),
|
TargetURL: github.String(link),
|
||||||
|
@ -356,10 +356,6 @@ func (g *Github) push(r *http.Request) (*model.Repo, *model.Build, error) {
|
||||||
// default gravatar?
|
// default gravatar?
|
||||||
}
|
}
|
||||||
|
|
||||||
// we should ignore github pages
|
|
||||||
if build.Ref == "refs/heads/gh-pages" {
|
|
||||||
return nil, nil, nil
|
|
||||||
}
|
|
||||||
if strings.HasPrefix(build.Ref, "refs/tags/") {
|
if strings.HasPrefix(build.Ref, "refs/tags/") {
|
||||||
// just kidding, this is actually a tag event
|
// just kidding, this is actually a tag event
|
||||||
build.Event = model.EventTag
|
build.Event = model.EventTag
|
||||||
|
|
27
remote/gitlab/client/drone.go
Normal file
27
remote/gitlab/client/drone.go
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
const (
|
||||||
|
droneServiceUrl = "/projects/:id/services/drone-ci"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *Client) AddDroneService(id string, params QMap) error {
|
||||||
|
url, opaque := c.ResourceUrl(
|
||||||
|
droneServiceUrl,
|
||||||
|
QMap{":id": id},
|
||||||
|
params,
|
||||||
|
)
|
||||||
|
|
||||||
|
_, err := c.Do("PUT", url, opaque, nil)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) DeleteDroneService(id string) error {
|
||||||
|
url, opaque := c.ResourceUrl(
|
||||||
|
droneServiceUrl,
|
||||||
|
QMap{":id": id},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
|
||||||
|
_, err := c.Do("DELETE", url, opaque, nil)
|
||||||
|
return err
|
||||||
|
}
|
96
remote/gitlab/client/gitlab.go
Normal file
96
remote/gitlab/client/gitlab.go
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
BaseUrl string
|
||||||
|
ApiPath string
|
||||||
|
Token string
|
||||||
|
Client *http.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(baseUrl, apiPath, token string, skipVerify bool) *Client {
|
||||||
|
config := &tls.Config{InsecureSkipVerify: skipVerify}
|
||||||
|
tr := &http.Transport{
|
||||||
|
Proxy: http.ProxyFromEnvironment,
|
||||||
|
TLSClientConfig: config,
|
||||||
|
}
|
||||||
|
client := &http.Client{Transport: tr}
|
||||||
|
|
||||||
|
return &Client{
|
||||||
|
BaseUrl: baseUrl,
|
||||||
|
ApiPath: apiPath,
|
||||||
|
Token: token,
|
||||||
|
Client: client,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) ResourceUrl(u string, params, query QMap) (string, string) {
|
||||||
|
if params != nil {
|
||||||
|
for key, val := range params {
|
||||||
|
u = strings.Replace(u, key, encodeParameter(val), -1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query_params := url.Values{}
|
||||||
|
|
||||||
|
if query != nil {
|
||||||
|
for key, val := range query {
|
||||||
|
query_params.Set(key, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u = c.BaseUrl + c.ApiPath + u + "?" + query_params.Encode()
|
||||||
|
p, err := url.Parse(u)
|
||||||
|
if err != nil {
|
||||||
|
return u, ""
|
||||||
|
}
|
||||||
|
|
||||||
|
opaque := "//" + p.Host + p.Path
|
||||||
|
return u, opaque
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Do(method, url, opaque string, body []byte) ([]byte, error) {
|
||||||
|
var req *http.Request
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if body != nil {
|
||||||
|
reader := bytes.NewReader(body)
|
||||||
|
req, err = http.NewRequest(method, url, reader)
|
||||||
|
} else {
|
||||||
|
req, err = http.NewRequest(method, url, nil)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Error while building gitlab request")
|
||||||
|
}
|
||||||
|
|
||||||
|
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.Token))
|
||||||
|
|
||||||
|
if len(opaque) > 0 {
|
||||||
|
req.URL.Opaque = opaque
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := c.Client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Client.Do error: %q", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
contents, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("%s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode >= 400 {
|
||||||
|
err = fmt.Errorf("*Gitlab.buildAndExecRequest failed: <%d> %s", resp.StatusCode, req.URL)
|
||||||
|
}
|
||||||
|
|
||||||
|
return contents, err
|
||||||
|
}
|
41
remote/gitlab/client/hook.go
Normal file
41
remote/gitlab/client/hook.go
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ParseHook parses hook payload from GitLab
|
||||||
|
func ParseHook(payload []byte) (*HookPayload, error) {
|
||||||
|
hp := HookPayload{}
|
||||||
|
if err := json.Unmarshal(payload, &hp); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Basic sanity check
|
||||||
|
switch {
|
||||||
|
case len(hp.ObjectKind) == 0:
|
||||||
|
// Assume this is a post-receive within repository
|
||||||
|
if len(hp.After) == 0 {
|
||||||
|
return nil, fmt.Errorf("Invalid hook received, commit hash not found.")
|
||||||
|
}
|
||||||
|
case hp.ObjectKind == "push":
|
||||||
|
if hp.Repository == nil {
|
||||||
|
return nil, fmt.Errorf("Invalid push hook received, attributes not found")
|
||||||
|
}
|
||||||
|
case hp.ObjectKind == "tag_push":
|
||||||
|
if hp.Repository == nil {
|
||||||
|
return nil, fmt.Errorf("Invalid tag push hook received, attributes not found")
|
||||||
|
}
|
||||||
|
case hp.ObjectKind == "issue":
|
||||||
|
fallthrough
|
||||||
|
case hp.ObjectKind == "merge_request":
|
||||||
|
if hp.ObjectAttributes == nil {
|
||||||
|
return nil, fmt.Errorf("Invalid hook received, attributes not found.")
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("Invalid hook received, payload format not recognized.")
|
||||||
|
}
|
||||||
|
|
||||||
|
return &hp, nil
|
||||||
|
}
|
138
remote/gitlab/client/project.go
Normal file
138
remote/gitlab/client/project.go
Normal file
|
@ -0,0 +1,138 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
searchUrl = "/projects/search/:query"
|
||||||
|
projectsUrl = "/projects"
|
||||||
|
projectUrl = "/projects/:id"
|
||||||
|
repoUrlRawFile = "/projects/:id/repository/blobs/:sha"
|
||||||
|
commitStatusUrl = "/projects/:id/statuses/:sha"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Get a list of all projects owned by the authenticated user.
|
||||||
|
func (g *Client) AllProjects() ([]*Project, error) {
|
||||||
|
var per_page = 100
|
||||||
|
var projects []*Project
|
||||||
|
|
||||||
|
for i := 1; true; i++ {
|
||||||
|
contents, err := g.Projects(i, per_page)
|
||||||
|
if err != nil {
|
||||||
|
return projects, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, value := range contents {
|
||||||
|
projects = append(projects, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(projects) == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(projects)/i < per_page {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return projects, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a list of projects owned by the authenticated user.
|
||||||
|
func (c *Client) Projects(page int, per_page int) ([]*Project, error) {
|
||||||
|
|
||||||
|
url, opaque := c.ResourceUrl(projectsUrl, nil, QMap{
|
||||||
|
"page": strconv.Itoa(page),
|
||||||
|
"per_page": strconv.Itoa(per_page),
|
||||||
|
})
|
||||||
|
|
||||||
|
var projects []*Project
|
||||||
|
|
||||||
|
contents, err := c.Do("GET", url, opaque, nil)
|
||||||
|
if err == nil {
|
||||||
|
err = json.Unmarshal(contents, &projects)
|
||||||
|
}
|
||||||
|
|
||||||
|
return projects, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a project by id
|
||||||
|
func (c *Client) Project(id string) (*Project, error) {
|
||||||
|
url, opaque := c.ResourceUrl(projectUrl, QMap{":id": id}, nil)
|
||||||
|
|
||||||
|
var project *Project
|
||||||
|
|
||||||
|
contents, err := c.Do("GET", url, opaque, nil)
|
||||||
|
if err == nil {
|
||||||
|
err = json.Unmarshal(contents, &project)
|
||||||
|
}
|
||||||
|
|
||||||
|
return project, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get Raw file content
|
||||||
|
func (c *Client) RepoRawFile(id, sha, filepath string) ([]byte, error) {
|
||||||
|
url, opaque := c.ResourceUrl(
|
||||||
|
repoUrlRawFile,
|
||||||
|
QMap{
|
||||||
|
":id": id,
|
||||||
|
":sha": sha,
|
||||||
|
},
|
||||||
|
QMap{
|
||||||
|
"filepath": filepath,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
contents, err := c.Do("GET", url, opaque, nil)
|
||||||
|
|
||||||
|
return contents, err
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
func (c *Client) SetStatus(id, sha, state, desc, ref, link string) error {
|
||||||
|
url, opaque := c.ResourceUrl(
|
||||||
|
commitStatusUrl,
|
||||||
|
QMap{
|
||||||
|
":id": id,
|
||||||
|
":sha": sha,
|
||||||
|
},
|
||||||
|
QMap{
|
||||||
|
"state": state,
|
||||||
|
"ref": ref,
|
||||||
|
"target_url": link,
|
||||||
|
"description": desc,
|
||||||
|
"context": "ci/drone",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
_, err := c.Do("POST", url, opaque, nil)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get a list of projects by query owned by the authenticated user.
|
||||||
|
func (c *Client) SearchProjectId(namespace string, name string) (id int, err error) {
|
||||||
|
|
||||||
|
url, opaque := c.ResourceUrl(searchUrl, nil, QMap{
|
||||||
|
":query": strings.ToLower(name),
|
||||||
|
})
|
||||||
|
|
||||||
|
var projects []*Project
|
||||||
|
|
||||||
|
contents, err := c.Do("GET", url, opaque, nil)
|
||||||
|
if err == nil {
|
||||||
|
err = json.Unmarshal(contents, &projects)
|
||||||
|
} else {
|
||||||
|
return id, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, project := range projects {
|
||||||
|
if project.Namespace.Name == namespace && strings.ToLower(project.Name) == strings.ToLower(name) {
|
||||||
|
id = project.Id
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return id, err
|
||||||
|
}
|
130
remote/gitlab/client/types.go
Normal file
130
remote/gitlab/client/types.go
Normal file
|
@ -0,0 +1,130 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
type QMap map[string]string
|
||||||
|
|
||||||
|
type User struct {
|
||||||
|
Id int `json:"id,omitempty"`
|
||||||
|
Username string `json:"username,omitempty"`
|
||||||
|
Email string `json:"email,omitempty"`
|
||||||
|
AvatarUrl string `json:"avatar_url,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ProjectAccess struct {
|
||||||
|
AccessLevel int `json:"access_level,omitempty"`
|
||||||
|
NotificationLevel int `json:"notification_level,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GroupAccess struct {
|
||||||
|
AccessLevel int `json:"access_level,omitempty"`
|
||||||
|
NotificationLevel int `json:"notification_level,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Permissions struct {
|
||||||
|
ProjectAccess *ProjectAccess `json:"project_access,omitempty"`
|
||||||
|
GroupAccess *GroupAccess `json:"group_access,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Member struct {
|
||||||
|
Id int
|
||||||
|
Username string
|
||||||
|
Email string
|
||||||
|
Name string
|
||||||
|
State string
|
||||||
|
CreatedAt string `json:"created_at,omitempty"`
|
||||||
|
// AccessLevel int
|
||||||
|
}
|
||||||
|
|
||||||
|
type Project struct {
|
||||||
|
Id int `json:"id,omitempty"`
|
||||||
|
Owner *Member `json:"owner,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
DefaultBranch string `json:"default_branch,omitempty"`
|
||||||
|
Public bool `json:"public,omitempty"`
|
||||||
|
Path string `json:"path,omitempty"`
|
||||||
|
PathWithNamespace string `json:"path_with_namespace,omitempty"`
|
||||||
|
Namespace *Namespace `json:"namespace,omitempty"`
|
||||||
|
SshRepoUrl string `json:"ssh_url_to_repo"`
|
||||||
|
HttpRepoUrl string `json:"http_url_to_repo"`
|
||||||
|
Url string `json:"web_url"`
|
||||||
|
Permissions *Permissions `json:"permissions,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Namespace struct {
|
||||||
|
Id int `json:"id,omitempty"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Person struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
Email string `json:"email"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type hProject struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
SshUrl string `json:"ssh_url"`
|
||||||
|
HttpUrl string `json:"http_url"`
|
||||||
|
VisibilityLevel int `json:"visibility_level"`
|
||||||
|
WebUrl string `json:"web_url"`
|
||||||
|
Namespace string `json:"namespace"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type hRepository struct {
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
URL string `json:"url,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
Homepage string `json:"homepage,omitempty"`
|
||||||
|
GitHttpUrl string `json:"git_http_url,omitempty"`
|
||||||
|
GitSshUrl string `json:"git_ssh_url,omitempty"`
|
||||||
|
VisibilityLevel int `json:"visibility_level,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type hCommit struct {
|
||||||
|
Id string `json:"id,omitempty"`
|
||||||
|
Message string `json:"message,omitempty"`
|
||||||
|
Timestamp string `json:"timestamp,omitempty"`
|
||||||
|
URL string `json:"url,omitempty"`
|
||||||
|
Author *Person `json:"author,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type HookObjAttr struct {
|
||||||
|
Id int `json:"id,omitempty"`
|
||||||
|
Title string `json:"title,omitempty"`
|
||||||
|
AssigneeId int `json:"assignee_id,omitempty"`
|
||||||
|
AuthorId int `json:"author_id,omitempty"`
|
||||||
|
ProjectId int `json:"project_id,omitempty"`
|
||||||
|
CreatedAt string `json:"created_at,omitempty"`
|
||||||
|
UpdatedAt string `json:"updated_at,omitempty"`
|
||||||
|
Position int `json:"position,omitempty"`
|
||||||
|
BranchName string `json:"branch_name,omitempty"`
|
||||||
|
Description string `json:"description,omitempty"`
|
||||||
|
MilestoneId int `json:"milestone_id,omitempty"`
|
||||||
|
State string `json:"state,omitempty"`
|
||||||
|
IId int `json:"iid,omitempty"`
|
||||||
|
TargetBranch string `json:"target_branch,omitempty"`
|
||||||
|
SourceBranch string `json:"source_branch,omitempty"`
|
||||||
|
SourceProjectId int `json:"source_project_id,omitempty"`
|
||||||
|
StCommits string `json:"st_commits,omitempty"`
|
||||||
|
StDiffs string `json:"st_diffs,omitempty"`
|
||||||
|
MergeStatus string `json:"merge_status,omitempty"`
|
||||||
|
TargetProjectId int `json:"target_project_id,omitempty"`
|
||||||
|
Url string `json:"url,omiyempty"`
|
||||||
|
Source *hProject `json:"source,omitempty"`
|
||||||
|
Target *hProject `json:"target,omitempty"`
|
||||||
|
LastCommit *hCommit `json:"last_commit,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type HookPayload struct {
|
||||||
|
Before string `json:"before,omitempty"`
|
||||||
|
After string `json:"after,omitempty"`
|
||||||
|
Ref string `json:"ref,omitempty"`
|
||||||
|
UserId int `json:"user_id,omitempty"`
|
||||||
|
UserName string `json:"user_name,omitempty"`
|
||||||
|
ProjectId int `json:"project_id,omitempty"`
|
||||||
|
Repository *hRepository `json:"repository,omitempty"`
|
||||||
|
Commits []hCommit `json:"commits,omitempty"`
|
||||||
|
TotalCommitsCount int `json:"total_commits_count,omitempty"`
|
||||||
|
ObjectKind string `json:"object_kind,omitempty"`
|
||||||
|
ObjectAttributes *HookObjAttr `json:"object_attributes,omitempty"`
|
||||||
|
}
|
21
remote/gitlab/client/user.go
Normal file
21
remote/gitlab/client/user.go
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
currentUserUrl = "/user"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *Client) CurrentUser() (User, error) {
|
||||||
|
url, opaque := c.ResourceUrl(currentUserUrl, nil, nil)
|
||||||
|
var user User
|
||||||
|
|
||||||
|
contents, err := c.Do("GET", url, opaque, nil)
|
||||||
|
if err == nil {
|
||||||
|
err = json.Unmarshal(contents, &user)
|
||||||
|
}
|
||||||
|
|
||||||
|
return user, err
|
||||||
|
}
|
33
remote/gitlab/client/util.go
Normal file
33
remote/gitlab/client/util.go
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
package client
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/url"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func encodeParameter(value string) string {
|
||||||
|
return strings.Replace(url.QueryEscape(value), "/", "%2F", 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tag returns current tag for push event hook payload
|
||||||
|
// This function returns empty string for any other events
|
||||||
|
func (h *HookPayload) Tag() string {
|
||||||
|
return strings.TrimPrefix(h.Ref, "refs/tags/")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Branch returns current branch for push event hook payload
|
||||||
|
// This function returns empty string for any other events
|
||||||
|
func (h *HookPayload) Branch() string {
|
||||||
|
return strings.TrimPrefix(h.Ref, "refs/heads/")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Head returns the latest changeset for push event hook payload
|
||||||
|
func (h *HookPayload) Head() hCommit {
|
||||||
|
c := hCommit{}
|
||||||
|
for _, cm := range h.Commits {
|
||||||
|
if h.After == cm.Id {
|
||||||
|
return cm
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
|
@ -15,7 +15,7 @@ import (
|
||||||
"github.com/drone/drone/shared/oauth2"
|
"github.com/drone/drone/shared/oauth2"
|
||||||
"github.com/drone/drone/shared/token"
|
"github.com/drone/drone/shared/token"
|
||||||
|
|
||||||
"github.com/Bugagazavr/go-gitlab-client"
|
"github.com/drone/drone/remote/gitlab/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -198,6 +198,13 @@ func (g *Gitlab) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// repo owner is granted full access
|
||||||
|
if repo.Owner != nil && repo.Owner.Username == u.Login {
|
||||||
|
return &model.Perm{true, true, true}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// check permission for current user
|
||||||
m := &model.Perm{}
|
m := &model.Perm{}
|
||||||
m.Admin = IsAdmin(repo)
|
m.Admin = IsAdmin(repo)
|
||||||
m.Pull = IsRead(repo)
|
m.Pull = IsRead(repo)
|
||||||
|
@ -229,6 +236,22 @@ func (g *Gitlab) Script(user *model.User, repo *model.Repo, build *model.Build)
|
||||||
// also if we want get MR status in gitlab we need implement a special plugin for gitlab,
|
// also if we want get MR status in gitlab we need implement a special plugin for gitlab,
|
||||||
// gitlab uses API to fetch build status on client side. But for now we skip this.
|
// gitlab uses API to fetch build status on client side. But for now we skip this.
|
||||||
func (g *Gitlab) Status(u *model.User, repo *model.Repo, b *model.Build, link string) error {
|
func (g *Gitlab) Status(u *model.User, repo *model.Repo, b *model.Build, link string) error {
|
||||||
|
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||||
|
|
||||||
|
status := getStatus(b.Status)
|
||||||
|
desc := getDesc(b.Status)
|
||||||
|
|
||||||
|
client.SetStatus(
|
||||||
|
ns(repo.Owner, repo.Name),
|
||||||
|
b.Commit,
|
||||||
|
status,
|
||||||
|
desc,
|
||||||
|
strings.Replace(b.Ref, "refs/heads/", "", -1),
|
||||||
|
link,
|
||||||
|
)
|
||||||
|
|
||||||
|
// Gitlab statuses it's a new feature, just ignore error
|
||||||
|
// if gitlab version not support this
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -296,7 +319,7 @@ func (g *Gitlab) Deactivate(user *model.User, repo *model.Repo, link string) err
|
||||||
func (g *Gitlab) Hook(req *http.Request) (*model.Repo, *model.Build, error) {
|
func (g *Gitlab) Hook(req *http.Request) (*model.Repo, *model.Build, error) {
|
||||||
defer req.Body.Close()
|
defer req.Body.Close()
|
||||||
var payload, _ = ioutil.ReadAll(req.Body)
|
var payload, _ = ioutil.ReadAll(req.Body)
|
||||||
var parsed, err = gogitlab.ParseHook(payload)
|
var parsed, err = client.ParseHook(payload)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
@ -311,7 +334,7 @@ func (g *Gitlab) Hook(req *http.Request) (*model.Repo, *model.Build, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func mergeRequest(parsed *gogitlab.HookPayload, req *http.Request) (*model.Repo, *model.Build, error) {
|
func mergeRequest(parsed *client.HookPayload, req *http.Request) (*model.Repo, *model.Build, error) {
|
||||||
|
|
||||||
repo := &model.Repo{}
|
repo := &model.Repo{}
|
||||||
repo.Owner = req.FormValue("owner")
|
repo.Owner = req.FormValue("owner")
|
||||||
|
@ -344,7 +367,7 @@ func mergeRequest(parsed *gogitlab.HookPayload, req *http.Request) (*model.Repo,
|
||||||
return repo, build, nil
|
return repo, build, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func push(parsed *gogitlab.HookPayload, req *http.Request) (*model.Repo, *model.Build, error) {
|
func push(parsed *client.HookPayload, req *http.Request) (*model.Repo, *model.Build, error) {
|
||||||
var cloneUrl = parsed.Repository.GitHttpUrl
|
var cloneUrl = parsed.Repository.GitHttpUrl
|
||||||
|
|
||||||
repo := &model.Repo{}
|
repo := &model.Repo{}
|
||||||
|
@ -431,3 +454,57 @@ func (g *Gitlab) Scope() string {
|
||||||
func (g *Gitlab) String() string {
|
func (g *Gitlab) String() string {
|
||||||
return "gitlab"
|
return "gitlab"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
StatusPending = "pending"
|
||||||
|
StatusRunning = "running"
|
||||||
|
StatusSuccess = "success"
|
||||||
|
StatusFailure = "failed"
|
||||||
|
StatusCanceled = "canceled"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
DescPending = "this build is pending"
|
||||||
|
DescRunning = "this buils is running"
|
||||||
|
DescSuccess = "the build was successful"
|
||||||
|
DescFailure = "the build failed"
|
||||||
|
DescCanceled = "the build canceled"
|
||||||
|
)
|
||||||
|
|
||||||
|
// getStatus is a helper functin that converts a Drone
|
||||||
|
// status to a GitHub status.
|
||||||
|
func getStatus(status string) string {
|
||||||
|
switch status {
|
||||||
|
case model.StatusPending:
|
||||||
|
return StatusPending
|
||||||
|
case model.StatusRunning:
|
||||||
|
return StatusRunning
|
||||||
|
case model.StatusSuccess:
|
||||||
|
return StatusSuccess
|
||||||
|
case model.StatusFailure, model.StatusError:
|
||||||
|
return StatusFailure
|
||||||
|
case model.StatusKilled:
|
||||||
|
return StatusCanceled
|
||||||
|
default:
|
||||||
|
return StatusFailure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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:
|
||||||
|
return DescPending
|
||||||
|
case model.StatusRunning:
|
||||||
|
return DescRunning
|
||||||
|
case model.StatusSuccess:
|
||||||
|
return DescSuccess
|
||||||
|
case model.StatusFailure, model.StatusError:
|
||||||
|
return DescFailure
|
||||||
|
case model.StatusKilled:
|
||||||
|
return DescCanceled
|
||||||
|
default:
|
||||||
|
return DescFailure
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -54,13 +54,18 @@ func Test_Gitlab(t *testing.T) {
|
||||||
g.Describe("Perm", func() {
|
g.Describe("Perm", func() {
|
||||||
g.It("Should return repo permissions", func() {
|
g.It("Should return repo permissions", func() {
|
||||||
perm, err := gitlab.Perm(&user, "diaspora", "diaspora-client")
|
perm, err := gitlab.Perm(&user, "diaspora", "diaspora-client")
|
||||||
|
|
||||||
g.Assert(err == nil).IsTrue()
|
g.Assert(err == nil).IsTrue()
|
||||||
g.Assert(perm.Admin).Equal(true)
|
g.Assert(perm.Admin).Equal(true)
|
||||||
g.Assert(perm.Pull).Equal(true)
|
g.Assert(perm.Pull).Equal(true)
|
||||||
g.Assert(perm.Push).Equal(true)
|
g.Assert(perm.Push).Equal(true)
|
||||||
})
|
})
|
||||||
|
g.It("Should return repo permissions when user is admin", func() {
|
||||||
|
perm, err := gitlab.Perm(&user, "brightbox", "puppet")
|
||||||
|
g.Assert(err == nil).IsTrue()
|
||||||
|
g.Assert(perm.Admin).Equal(true)
|
||||||
|
g.Assert(perm.Pull).Equal(true)
|
||||||
|
g.Assert(perm.Push).Equal(true)
|
||||||
|
})
|
||||||
g.It("Should return error, when repo is not exist", func() {
|
g.It("Should return error, when repo is not exist", func() {
|
||||||
_, err := gitlab.Perm(&user, "not-existed", "not-existed")
|
_, err := gitlab.Perm(&user, "not-existed", "not-existed")
|
||||||
|
|
||||||
|
|
|
@ -5,20 +5,19 @@ import (
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/Bugagazavr/go-gitlab-client"
|
"github.com/drone/drone/remote/gitlab/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewClient is a helper function that returns a new GitHub
|
// NewClient is a helper function that returns a new GitHub
|
||||||
// client using the provided OAuth token.
|
// client using the provided OAuth token.
|
||||||
func NewClient(url, accessToken string, skipVerify bool) *gogitlab.Gitlab {
|
func NewClient(url, accessToken string, skipVerify bool) *client.Client {
|
||||||
client := gogitlab.NewGitlabCert(url, "/api/v3", accessToken, skipVerify)
|
client := client.New(url, "/api/v3", accessToken, skipVerify)
|
||||||
client.Bearer = true
|
|
||||||
return client
|
return client
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsRead is a helper function that returns true if the
|
// IsRead is a helper function that returns true if the
|
||||||
// user has Read-only access to the repository.
|
// user has Read-only access to the repository.
|
||||||
func IsRead(proj *gogitlab.Project) bool {
|
func IsRead(proj *client.Project) bool {
|
||||||
var user = proj.Permissions.ProjectAccess
|
var user = proj.Permissions.ProjectAccess
|
||||||
var group = proj.Permissions.GroupAccess
|
var group = proj.Permissions.GroupAccess
|
||||||
|
|
||||||
|
@ -36,7 +35,7 @@ func IsRead(proj *gogitlab.Project) bool {
|
||||||
|
|
||||||
// IsWrite is a helper function that returns true if the
|
// IsWrite is a helper function that returns true if the
|
||||||
// user has Read-Write access to the repository.
|
// user has Read-Write access to the repository.
|
||||||
func IsWrite(proj *gogitlab.Project) bool {
|
func IsWrite(proj *client.Project) bool {
|
||||||
var user = proj.Permissions.ProjectAccess
|
var user = proj.Permissions.ProjectAccess
|
||||||
var group = proj.Permissions.GroupAccess
|
var group = proj.Permissions.GroupAccess
|
||||||
|
|
||||||
|
@ -52,7 +51,7 @@ func IsWrite(proj *gogitlab.Project) bool {
|
||||||
|
|
||||||
// IsAdmin is a helper function that returns true if the
|
// IsAdmin is a helper function that returns true if the
|
||||||
// user has Admin access to the repository.
|
// user has Admin access to the repository.
|
||||||
func IsAdmin(proj *gogitlab.Project) bool {
|
func IsAdmin(proj *client.Project) bool {
|
||||||
var user = proj.Permissions.ProjectAccess
|
var user = proj.Permissions.ProjectAccess
|
||||||
var group = proj.Permissions.GroupAccess
|
var group = proj.Permissions.GroupAccess
|
||||||
|
|
||||||
|
@ -80,13 +79,13 @@ func ns(owner, name string) string {
|
||||||
return fmt.Sprintf("%s%%2F%s", owner, name)
|
return fmt.Sprintf("%s%%2F%s", owner, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetUserEmail(client *gogitlab.Gitlab, defaultURL string) (*gogitlab.Gitlab, error) {
|
func GetUserEmail(c *client.Client, defaultURL string) (*client.Client, error) {
|
||||||
return client, nil
|
return c, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetProjectId(r *Gitlab, client *gogitlab.Gitlab, owner, name string) (projectId string, err error) {
|
func GetProjectId(r *Gitlab, c *client.Client, owner, name string) (projectId string, err error) {
|
||||||
if r.Search {
|
if r.Search {
|
||||||
_projectId, err := client.SearchProjectId(owner, name)
|
_projectId, err := c.SearchProjectId(owner, name)
|
||||||
if err != nil || _projectId == 0 {
|
if err != nil || _projectId == 0 {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
18
remote/gitlab/testdata/projects.go
vendored
18
remote/gitlab/testdata/projects.go
vendored
|
@ -15,6 +15,7 @@ var projectsPayload = []byte(`
|
||||||
"owner": {
|
"owner": {
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"name": "Diaspora",
|
"name": "Diaspora",
|
||||||
|
"username": "some_user",
|
||||||
"created_at": "2013-09-30T13: 46: 02Z"
|
"created_at": "2013-09-30T13: 46: 02Z"
|
||||||
},
|
},
|
||||||
"name": "Diaspora Client",
|
"name": "Diaspora Client",
|
||||||
|
@ -48,8 +49,9 @@ var projectsPayload = []byte(`
|
||||||
"http_url_to_repo": "http://example.com/brightbox/puppet.git",
|
"http_url_to_repo": "http://example.com/brightbox/puppet.git",
|
||||||
"web_url": "http://example.com/brightbox/puppet",
|
"web_url": "http://example.com/brightbox/puppet",
|
||||||
"owner": {
|
"owner": {
|
||||||
"id": 4,
|
"id": 1,
|
||||||
"name": "Brightbox",
|
"name": "Brightbox",
|
||||||
|
"username": "test_user",
|
||||||
"created_at": "2013-09-30T13:46:02Z"
|
"created_at": "2013-09-30T13:46:02Z"
|
||||||
},
|
},
|
||||||
"name": "Puppet",
|
"name": "Puppet",
|
||||||
|
@ -89,6 +91,7 @@ var project4Paylod = []byte(`
|
||||||
"owner": {
|
"owner": {
|
||||||
"id": 3,
|
"id": 3,
|
||||||
"name": "Diaspora",
|
"name": "Diaspora",
|
||||||
|
"username": "some_user",
|
||||||
"created_at": "2013-09-30T13: 46: 02Z"
|
"created_at": "2013-09-30T13: 46: 02Z"
|
||||||
},
|
},
|
||||||
"name": "Diaspora Client",
|
"name": "Diaspora Client",
|
||||||
|
@ -135,8 +138,9 @@ var project6Paylod = []byte(`
|
||||||
"http_url_to_repo": "http://example.com/brightbox/puppet.git",
|
"http_url_to_repo": "http://example.com/brightbox/puppet.git",
|
||||||
"web_url": "http://example.com/brightbox/puppet",
|
"web_url": "http://example.com/brightbox/puppet",
|
||||||
"owner": {
|
"owner": {
|
||||||
"id": 4,
|
"id": 1,
|
||||||
"name": "Brightbox",
|
"name": "Brightbox",
|
||||||
|
"username": "test_user",
|
||||||
"created_at": "2013-09-30T13:46:02Z"
|
"created_at": "2013-09-30T13:46:02Z"
|
||||||
},
|
},
|
||||||
"name": "Puppet",
|
"name": "Puppet",
|
||||||
|
@ -160,14 +164,8 @@ var project6Paylod = []byte(`
|
||||||
},
|
},
|
||||||
"archived": false,
|
"archived": false,
|
||||||
"permissions": {
|
"permissions": {
|
||||||
"project_access": {
|
"project_access": null,
|
||||||
"access_level": 10,
|
"group_access": null
|
||||||
"notification_level": 3
|
|
||||||
},
|
|
||||||
"group_access": {
|
|
||||||
"access_level": 50,
|
|
||||||
"notification_level": 3
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
`)
|
`)
|
||||||
|
|
7
remote/gitlab/testdata/testdata.go
vendored
7
remote/gitlab/testdata/testdata.go
vendored
|
@ -21,6 +21,9 @@ func NewServer() *httptest.Server {
|
||||||
case "/api/v3/projects/diaspora/diaspora-client":
|
case "/api/v3/projects/diaspora/diaspora-client":
|
||||||
w.Write(project4Paylod)
|
w.Write(project4Paylod)
|
||||||
return
|
return
|
||||||
|
case "/api/v3/projects/brightbox/puppet":
|
||||||
|
w.Write(project6Paylod)
|
||||||
|
return
|
||||||
case "/api/v3/projects/diaspora/diaspora-client/services/drone-ci":
|
case "/api/v3/projects/diaspora/diaspora-client/services/drone-ci":
|
||||||
switch r.Method {
|
switch r.Method {
|
||||||
case "PUT":
|
case "PUT":
|
||||||
|
@ -38,11 +41,7 @@ func NewServer() *httptest.Server {
|
||||||
w.Write(accessTokenPayload)
|
w.Write(accessTokenPayload)
|
||||||
return
|
return
|
||||||
case "/api/v3/user":
|
case "/api/v3/user":
|
||||||
if r.Header.Get("Authorization") == "Bearer valid_token" {
|
|
||||||
w.Write(currentUserPayload)
|
w.Write(currentUserPayload)
|
||||||
} else {
|
|
||||||
w.WriteHeader(401)
|
|
||||||
}
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package gogs
|
package gogs
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -29,7 +31,6 @@ func Load(env envconfig.Env) *Gogs {
|
||||||
log.Fatalln("unable to parse remote dsn. %s", err)
|
log.Fatalln("unable to parse remote dsn. %s", err)
|
||||||
}
|
}
|
||||||
params := url_.Query()
|
params := url_.Query()
|
||||||
url_.Path = ""
|
|
||||||
url_.RawQuery = ""
|
url_.RawQuery = ""
|
||||||
|
|
||||||
// create the Githbub remote using parameters from
|
// create the Githbub remote using parameters from
|
||||||
|
@ -58,7 +59,7 @@ func (g *Gogs) Login(res http.ResponseWriter, req *http.Request) (*model.User, b
|
||||||
return nil, false, nil
|
return nil, false, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
client := gogs.NewClient(g.URL, "")
|
client := NewGogsClient(g.URL, "", g.SkipVerify)
|
||||||
|
|
||||||
// try to fetch drone token if it exists
|
// try to fetch drone token if it exists
|
||||||
var accessToken string
|
var accessToken string
|
||||||
|
@ -82,7 +83,7 @@ func (g *Gogs) Login(res http.ResponseWriter, req *http.Request) (*model.User, b
|
||||||
accessToken = token.Sha1
|
accessToken = token.Sha1
|
||||||
}
|
}
|
||||||
|
|
||||||
client = gogs.NewClient(g.URL, accessToken)
|
client = NewGogsClient(g.URL, accessToken, g.SkipVerify)
|
||||||
userInfo, err := client.GetUserInfo(username)
|
userInfo, err := client.GetUserInfo(username)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, err
|
return nil, false, err
|
||||||
|
@ -104,7 +105,7 @@ func (g *Gogs) Auth(token, secret string) (string, error) {
|
||||||
|
|
||||||
// Repo fetches the named repository from the remote system.
|
// Repo fetches the named repository from the remote system.
|
||||||
func (g *Gogs) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
func (g *Gogs) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||||
client := gogs.NewClient(g.URL, u.Token)
|
client := NewGogsClient(g.URL, u.Token, g.SkipVerify)
|
||||||
repos_, err := client.ListMyRepos()
|
repos_, err := client.ListMyRepos()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -124,7 +125,7 @@ func (g *Gogs) Repo(u *model.User, owner, name string) (*model.Repo, error) {
|
||||||
func (g *Gogs) Repos(u *model.User) ([]*model.RepoLite, error) {
|
func (g *Gogs) Repos(u *model.User) ([]*model.RepoLite, error) {
|
||||||
repos := []*model.RepoLite{}
|
repos := []*model.RepoLite{}
|
||||||
|
|
||||||
client := gogs.NewClient(g.URL, u.Token)
|
client := NewGogsClient(g.URL, u.Token, g.SkipVerify)
|
||||||
repos_, err := client.ListMyRepos()
|
repos_, err := client.ListMyRepos()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return repos, err
|
return repos, err
|
||||||
|
@ -140,7 +141,7 @@ func (g *Gogs) Repos(u *model.User) ([]*model.RepoLite, error) {
|
||||||
// Perm fetches the named repository permissions from
|
// Perm fetches the named repository permissions from
|
||||||
// the remote system for the specified user.
|
// the remote system for the specified user.
|
||||||
func (g *Gogs) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
func (g *Gogs) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
||||||
client := gogs.NewClient(g.URL, u.Token)
|
client := NewGogsClient(g.URL, u.Token, g.SkipVerify)
|
||||||
repos_, err := client.ListMyRepos()
|
repos_, err := client.ListMyRepos()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -160,7 +161,7 @@ func (g *Gogs) Perm(u *model.User, owner, name string) (*model.Perm, error) {
|
||||||
// Script fetches the build script (.drone.yml) from the remote
|
// Script fetches the build script (.drone.yml) from the remote
|
||||||
// repository and returns in string format.
|
// repository and returns in string format.
|
||||||
func (g *Gogs) Script(u *model.User, r *model.Repo, b *model.Build) ([]byte, []byte, error) {
|
func (g *Gogs) Script(u *model.User, r *model.Repo, b *model.Build) ([]byte, []byte, error) {
|
||||||
client := gogs.NewClient(g.URL, u.Token)
|
client := NewGogsClient(g.URL, u.Token, g.SkipVerify)
|
||||||
cfg, err := client.GetFile(r.Owner, r.Name, b.Commit, ".drone.yml")
|
cfg, err := client.GetFile(r.Owner, r.Name, b.Commit, ".drone.yml")
|
||||||
sec, _ := client.GetFile(r.Owner, r.Name, b.Commit, ".drone.sec")
|
sec, _ := client.GetFile(r.Owner, r.Name, b.Commit, ".drone.sec")
|
||||||
return cfg, sec, err
|
return cfg, sec, err
|
||||||
|
@ -179,6 +180,10 @@ func (g *Gogs) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
host, _, err := net.SplitHostPort(url_.Host)
|
||||||
|
if err == nil {
|
||||||
|
url_.Host=host
|
||||||
|
}
|
||||||
return &model.Netrc{
|
return &model.Netrc{
|
||||||
Login: u.Token,
|
Login: u.Token,
|
||||||
Password: "x-oauth-basic",
|
Password: "x-oauth-basic",
|
||||||
|
@ -200,7 +205,7 @@ func (g *Gogs) Activate(u *model.User, r *model.Repo, k *model.Key, link string)
|
||||||
Active: true,
|
Active: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
client := gogs.NewClient(g.URL, u.Token)
|
client := NewGogsClient(g.URL, u.Token, g.SkipVerify)
|
||||||
_, err := client.CreateRepoHook(r.Owner, r.Name, hook)
|
_, err := client.CreateRepoHook(r.Owner, r.Name, hook)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -232,6 +237,20 @@ func (g *Gogs) Hook(r *http.Request) (*model.Repo, *model.Build, error) {
|
||||||
return repo, build, err
|
return repo, build, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewClient initializes and returns a API client.
|
||||||
|
func NewGogsClient(url, token string, skipVerify bool) *gogs.Client {
|
||||||
|
sslClient := &http.Client{}
|
||||||
|
c := gogs.NewClient(url, token)
|
||||||
|
|
||||||
|
if skipVerify {
|
||||||
|
sslClient.Transport = &http.Transport{
|
||||||
|
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||||
|
}
|
||||||
|
c.SetHTTPClient(sslClient)
|
||||||
|
}
|
||||||
|
return c
|
||||||
|
}
|
||||||
|
|
||||||
func (g *Gogs) String() string {
|
func (g *Gogs) String() string {
|
||||||
return "gogs"
|
return "gogs"
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,11 @@ html
|
||||||
meta[http-equiv="x-ua-compatible"][content="ie=edge"]
|
meta[http-equiv="x-ua-compatible"][content="ie=edge"]
|
||||||
link[rel="icon"][type="image/x-icon"][href="/static/images/favicon.ico"]
|
link[rel="icon"][type="image/x-icon"][href="/static/images/favicon.ico"]
|
||||||
|
|
||||||
link[rel="stylesheet"][href="https://fonts.googleapis.com/icon?family=Material+Icons"]
|
link[rel="stylesheet"][href="//fonts.googleapis.com/icon?family=Material+Icons"]
|
||||||
link[rel="stylesheet"][href="https://fonts.googleapis.com/css?family=Roboto+Mono"]
|
link[rel="stylesheet"][href="//fonts.googleapis.com/css?family=Roboto+Mono"]
|
||||||
link[rel="stylesheet"][href="https://fonts.googleapis.com/css?family=Roboto"]
|
link[rel="stylesheet"][href="//fonts.googleapis.com/css?family=Roboto"]
|
||||||
link[rel="stylesheet"][href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.min.css"]
|
link[rel="stylesheet"][href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.min.css"]
|
||||||
link[rel="stylesheet"][href="https://cdnjs.cloudflare.com/ajax/libs/octicons/3.1.0/octicons.min.css"]
|
link[rel="stylesheet"][href="//cdnjs.cloudflare.com/ajax/libs/octicons/3.1.0/octicons.min.css"]
|
||||||
link[rel="stylesheet"][href="/static/styles_gen/style.css"]
|
link[rel="stylesheet"][href="/static/styles_gen/style.css"]
|
||||||
|
|
||||||
if Csrf
|
if Csrf
|
||||||
|
@ -48,10 +48,10 @@ html
|
||||||
block content
|
block content
|
||||||
|
|
||||||
block scripts
|
block scripts
|
||||||
script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"]
|
script[type="text/javascript"][src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"]
|
||||||
script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"]
|
script[type="text/javascript"][src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.6/moment.min.js"]
|
||||||
script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/jquery-searcher/0.2.0/jquery.searcher.min.js"]
|
script[type="text/javascript"][src="//cdnjs.cloudflare.com/ajax/libs/jquery-searcher/0.2.0/jquery.searcher.min.js"]
|
||||||
script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/js/bootstrap.min.js"]
|
script[type="text/javascript"][src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/js/bootstrap.min.js"]
|
||||||
script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.min.js"]
|
script[type="text/javascript"][src="//cdnjs.cloudflare.com/ajax/libs/typeahead.js/0.11.1/typeahead.bundle.min.js"]
|
||||||
script[text="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/stickyfill/1.1.2/stickyfill.js"]
|
script[text="text/javascript"][src="//cdnjs.cloudflare.com/ajax/libs/stickyfill/1.1.2/stickyfill.js"]
|
||||||
script[type="text/javascript"][src="/static/scripts_gen/drone.min.js"]
|
script[type="text/javascript"][src="/static/scripts_gen/drone.min.js"]
|
||||||
|
|
|
@ -36,5 +36,5 @@ block content
|
||||||
#{Page.HTML}
|
#{Page.HTML}
|
||||||
|
|
||||||
block scripts
|
block scripts
|
||||||
script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"]
|
script[type="text/javascript"][src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"]
|
||||||
script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/js/bootstrap.min.js"]
|
script[type="text/javascript"][src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/js/bootstrap.min.js"]
|
||||||
|
|
|
@ -7,10 +7,10 @@ html
|
||||||
meta[http-equiv="x-ua-compatible"][content="ie=edge"]
|
meta[http-equiv="x-ua-compatible"][content="ie=edge"]
|
||||||
link[rel="icon"][type="image/x-icon"][href="/static/images/favicon.ico"]
|
link[rel="icon"][type="image/x-icon"][href="/static/images/favicon.ico"]
|
||||||
|
|
||||||
link[rel="stylesheet"][href="https://fonts.googleapis.com/icon?family=Material+Icons"]
|
link[rel="stylesheet"][href="//fonts.googleapis.com/icon?family=Material+Icons"]
|
||||||
link[rel="stylesheet"][href="https://fonts.googleapis.com/css?family=Roboto+Mono"]
|
link[rel="stylesheet"][href="//fonts.googleapis.com/css?family=Roboto+Mono"]
|
||||||
link[rel="stylesheet"][href="https://fonts.googleapis.com/css?family=Roboto"]
|
link[rel="stylesheet"][href="//fonts.googleapis.com/css?family=Roboto"]
|
||||||
link[rel="stylesheet"][href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.min.css"]
|
link[rel="stylesheet"][href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.min.css"]
|
||||||
link[rel="stylesheet"][href="/static/styles_gen/style.css"]
|
link[rel="stylesheet"][href="/static/styles_gen/style.css"]
|
||||||
style
|
style
|
||||||
html { height: 100%; overflow: hidden; }
|
html { height: 100%; overflow: hidden; }
|
||||||
|
@ -33,4 +33,3 @@ html
|
||||||
div.alert.alert-danger
|
div.alert.alert-danger
|
||||||
| We encountered an unexpected error. Please contact your
|
| We encountered an unexpected error. Please contact your
|
||||||
| system administrator to check the logs and see what went wrong.
|
| system administrator to check the logs and see what went wrong.
|
||||||
|
|
||||||
|
|
|
@ -7,10 +7,10 @@ html
|
||||||
meta[http-equiv="x-ua-compatible"][content="ie=edge"]
|
meta[http-equiv="x-ua-compatible"][content="ie=edge"]
|
||||||
link[rel="icon"][type="image/x-icon"][href="/static/images/favicon.ico"]
|
link[rel="icon"][type="image/x-icon"][href="/static/images/favicon.ico"]
|
||||||
|
|
||||||
link[rel="stylesheet"][href="https://fonts.googleapis.com/icon?family=Material+Icons"]
|
link[rel="stylesheet"][href="//fonts.googleapis.com/icon?family=Material+Icons"]
|
||||||
link[rel="stylesheet"][href="https://fonts.googleapis.com/css?family=Roboto+Mono"]
|
link[rel="stylesheet"][href="//fonts.googleapis.com/css?family=Roboto+Mono"]
|
||||||
link[rel="stylesheet"][href="https://fonts.googleapis.com/css?family=Roboto"]
|
link[rel="stylesheet"][href="//fonts.googleapis.com/css?family=Roboto"]
|
||||||
link[rel="stylesheet"][href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.min.css"]
|
link[rel="stylesheet"][href="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/css/bootstrap.min.css"]
|
||||||
link[rel="stylesheet"][href="/static/styles_gen/style.css"]
|
link[rel="stylesheet"][href="/static/styles_gen/style.css"]
|
||||||
style
|
style
|
||||||
html { height: 100%; overflow: hidden; }
|
html { height: 100%; overflow: hidden; }
|
||||||
|
|
|
@ -68,7 +68,7 @@ block content
|
||||||
div.row
|
div.row
|
||||||
div.col-md-3 Public Key
|
div.col-md-3 Public Key
|
||||||
div.col-md-9
|
div.col-md-9
|
||||||
pre #{Key.Public}
|
pre #{Key.Public} #{Repo.Owner}-#{Repo.Name}@drone
|
||||||
div.row
|
div.row
|
||||||
div.col-md-12
|
div.col-md-12
|
||||||
div.alert.alert-danger
|
div.alert.alert-danger
|
||||||
|
|
|
@ -72,5 +72,5 @@ block content
|
||||||
pre #{$res.Example}
|
pre #{$res.Example}
|
||||||
|
|
||||||
block scripts
|
block scripts
|
||||||
script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"]
|
script[type="text/javascript"][src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"]
|
||||||
script[type="text/javascript"][src="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/js/bootstrap.min.js"]
|
script[type="text/javascript"][src="//cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha/js/bootstrap.min.js"]
|
||||||
|
|
30
vendor/github.com/gogits/go-gogs-client/admin_orgs.go
generated
vendored
Normal file
30
vendor/github.com/gogits/go-gogs-client/admin_orgs.go
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gogs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateOrgOption struct {
|
||||||
|
UserName string `json:"username" binding:"Required"`
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Website string `json:"website"`
|
||||||
|
Location string `json:"location"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) AdminCreateOrg(user string, opt CreateOrgOption) (*Organization, error) {
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
org := new(Organization)
|
||||||
|
return org, c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/orgs", user),
|
||||||
|
http.Header{"content-type": []string{"application/json"}}, bytes.NewReader(body), org)
|
||||||
|
}
|
22
vendor/github.com/gogits/go-gogs-client/admin_repos.go
generated
vendored
Normal file
22
vendor/github.com/gogits/go-gogs-client/admin_repos.go
generated
vendored
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gogs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *Client) AdminCreateRepo(user string, opt CreateRepoOption) (*Repository, error) {
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
repo := new(Repository)
|
||||||
|
return repo, c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/repos", user),
|
||||||
|
http.Header{"content-type": []string{"application/json"}}, bytes.NewReader(body), repo)
|
||||||
|
}
|
70
vendor/github.com/gogits/go-gogs-client/admin_users.go
generated
vendored
Normal file
70
vendor/github.com/gogits/go-gogs-client/admin_users.go
generated
vendored
Normal file
|
@ -0,0 +1,70 @@
|
||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gogs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateUserOption struct {
|
||||||
|
SourceID int64 `json:"source_id"`
|
||||||
|
LoginName string `json:"login_name"`
|
||||||
|
Username string `json:"username" binding:"Required;AlphaDashDot;MaxSize(35)"`
|
||||||
|
Email string `json:"email" binding:"Required;Email;MaxSize(254)"`
|
||||||
|
Password string `json:"password" binding:"MaxSize(255)"`
|
||||||
|
SendNotify bool `json:"send_notify"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) AdminCreateUser(opt CreateUserOption) (*User, error) {
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
user := new(User)
|
||||||
|
return user, c.getParsedResponse("POST", "/admin/users",
|
||||||
|
http.Header{"content-type": []string{"application/json"}}, bytes.NewReader(body), user)
|
||||||
|
}
|
||||||
|
|
||||||
|
type EditUserOption struct {
|
||||||
|
SourceID int64 `json:"source_id"`
|
||||||
|
LoginName string `json:"login_name"`
|
||||||
|
FullName string `json:"full_name" binding:"MaxSize(100)"`
|
||||||
|
Email string `json:"email" binding:"Required;Email;MaxSize(254)"`
|
||||||
|
Password string `json:"password" binding:"MaxSize(255)"`
|
||||||
|
Website string `json:"website" binding:"MaxSize(50)"`
|
||||||
|
Location string `json:"location" binding:"MaxSize(50)"`
|
||||||
|
Active *bool `json:"active"`
|
||||||
|
Admin *bool `json:"admin"`
|
||||||
|
AllowGitHook *bool `json:"allow_git_hook"`
|
||||||
|
AllowImportLocal *bool `json:"allow_import_local"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) AdminEditUser(user string, opt EditUserOption) error {
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = c.getResponse("PATCH", fmt.Sprintf("/admin/users/%s", user),
|
||||||
|
http.Header{"content-type": []string{"application/json"}}, bytes.NewReader(body))
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) AdminDeleteUser(user string) error {
|
||||||
|
_, err := c.getResponse("DELETE", fmt.Sprintf("/admin/users/%s", user), nil, nil)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) AdminCreateUserPublicKey(user string, opt CreateKeyOption) (*PublicKey, error) {
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
key := new(PublicKey)
|
||||||
|
return key, c.getParsedResponse("POST", fmt.Sprintf("/admin/users/%s/keys", user),
|
||||||
|
http.Header{"content-type": []string{"application/json"}}, bytes.NewReader(body), key)
|
||||||
|
}
|
9
vendor/github.com/gogits/go-gogs-client/gogs.go
generated
vendored
9
vendor/github.com/gogits/go-gogs-client/gogs.go
generated
vendored
|
@ -14,7 +14,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func Version() string {
|
func Version() string {
|
||||||
return "0.0.2"
|
return "0.7.2"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Client represents a Gogs API client.
|
// Client represents a Gogs API client.
|
||||||
|
@ -33,6 +33,11 @@ func NewClient(url, token string) *Client {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetHTTPClient replaces default http.Client with user given one.
|
||||||
|
func (c *Client) SetHTTPClient(client *http.Client) {
|
||||||
|
c.client = client
|
||||||
|
}
|
||||||
|
|
||||||
func (c *Client) getResponse(method, path string, header http.Header, body io.Reader) ([]byte, error) {
|
func (c *Client) getResponse(method, path string, header http.Header, body io.Reader) ([]byte, error) {
|
||||||
req, err := http.NewRequest(method, c.url+"/api/v1"+path, body)
|
req, err := http.NewRequest(method, c.url+"/api/v1"+path, body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -61,7 +66,7 @@ func (c *Client) getResponse(method, path string, header http.Header, body io.Re
|
||||||
return nil, errors.New("404 Not Found")
|
return nil, errors.New("404 Not Found")
|
||||||
}
|
}
|
||||||
|
|
||||||
if resp.StatusCode != 200 && resp.StatusCode != 201 {
|
if resp.StatusCode/100 != 2 {
|
||||||
errMap := make(map[string]interface{})
|
errMap := make(map[string]interface{})
|
||||||
if err = json.Unmarshal(data, &errMap); err != nil {
|
if err = json.Unmarshal(data, &errMap); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
11
vendor/github.com/gogits/go-gogs-client/miscellaneous.go
generated
vendored
Normal file
11
vendor/github.com/gogits/go-gogs-client/miscellaneous.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gogs
|
||||||
|
|
||||||
|
type MarkdownOption struct {
|
||||||
|
Text string
|
||||||
|
Mode string
|
||||||
|
Context string
|
||||||
|
}
|
54
vendor/github.com/gogits/go-gogs-client/org.go
generated
vendored
Normal file
54
vendor/github.com/gogits/go-gogs-client/org.go
generated
vendored
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gogs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Organization struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
UserName string `json:"username"`
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
AvatarUrl string `json:"avatar_url"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Website string `json:"website"`
|
||||||
|
Location string `json:"location"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) ListMyOrgs() ([]*Organization, error) {
|
||||||
|
orgs := make([]*Organization, 0, 5)
|
||||||
|
return orgs, c.getParsedResponse("GET", "/user/orgs", nil, nil, &orgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) ListUserOrgs(user string) ([]*Organization, error) {
|
||||||
|
orgs := make([]*Organization, 0, 5)
|
||||||
|
return orgs, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/orgs", user), nil, nil, &orgs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) GetOrg(orgname string) (*Organization, error) {
|
||||||
|
org := new(Organization)
|
||||||
|
return org, c.getParsedResponse("GET", fmt.Sprintf("/orgs/%s", orgname), nil, nil, org)
|
||||||
|
}
|
||||||
|
|
||||||
|
type EditOrgOption struct {
|
||||||
|
FullName string `json:"full_name"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
Website string `json:"website"`
|
||||||
|
Location string `json:"location"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) EditOrg(orgname string, opt EditOrgOption) error {
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = c.getResponse("PATCH", fmt.Sprintf("/orgs/%s", orgname),
|
||||||
|
http.Header{"content-type": []string{"application/json"}}, bytes.NewReader(body))
|
||||||
|
return err
|
||||||
|
}
|
37
vendor/github.com/gogits/go-gogs-client/repo.go
generated
vendored
37
vendor/github.com/gogits/go-gogs-client/repo.go
generated
vendored
|
@ -34,12 +34,11 @@ type Repository struct {
|
||||||
// ListMyRepos lists all repositories for the authenticated user that has access to.
|
// ListMyRepos lists all repositories for the authenticated user that has access to.
|
||||||
func (c *Client) ListMyRepos() ([]*Repository, error) {
|
func (c *Client) ListMyRepos() ([]*Repository, error) {
|
||||||
repos := make([]*Repository, 0, 10)
|
repos := make([]*Repository, 0, 10)
|
||||||
err := c.getParsedResponse("GET", "/user/repos", nil, nil, &repos)
|
return repos, c.getParsedResponse("GET", "/user/repos", nil, nil, &repos)
|
||||||
return repos, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateRepoOption struct {
|
type CreateRepoOption struct {
|
||||||
Name string `json:"name" binding:"Required"`
|
Name string `json:"name" binding:"Required;AlphaDashDot;MaxSize(100)"`
|
||||||
Description string `json:"description" binding:"MaxSize(255)"`
|
Description string `json:"description" binding:"MaxSize(255)"`
|
||||||
Private bool `json:"private"`
|
Private bool `json:"private"`
|
||||||
AutoInit bool `json:"auto_init"`
|
AutoInit bool `json:"auto_init"`
|
||||||
|
@ -70,8 +69,40 @@ func (c *Client) CreateOrgRepo(org string, opt CreateRepoOption) (*Repository, e
|
||||||
http.Header{"content-type": []string{"application/json"}}, bytes.NewReader(body), repo)
|
http.Header{"content-type": []string{"application/json"}}, bytes.NewReader(body), repo)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetRepo returns information of a repository of given owner.
|
||||||
|
func (c *Client) GetRepo(owner, reponame string) (*Repository, error) {
|
||||||
|
repo := new(Repository)
|
||||||
|
return repo, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s", owner, reponame), nil, nil, repo)
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteRepo deletes a repository of user or organization.
|
// DeleteRepo deletes a repository of user or organization.
|
||||||
func (c *Client) DeleteRepo(owner, repo string) error {
|
func (c *Client) DeleteRepo(owner, repo string) error {
|
||||||
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s", owner, repo), nil, nil)
|
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s", owner, repo), nil, nil)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type MigrateRepoOption struct {
|
||||||
|
CloneAddr string `json:"clone_addr" binding:"Required"`
|
||||||
|
AuthUsername string `json:"auth_username"`
|
||||||
|
AuthPassword string `json:"auth_password"`
|
||||||
|
UID int `json:"uid" binding:"Required"`
|
||||||
|
RepoName string `json:"repo_name" binding:"Required"`
|
||||||
|
Mirror bool `json:"mirror"`
|
||||||
|
Private bool `json:"private"`
|
||||||
|
Description string `json:"description"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// MigrateRepo migrates a repository from other Git hosting sources for the
|
||||||
|
// authenticated user.
|
||||||
|
//
|
||||||
|
// To migrate a repository for a organization, the authenticated user must be a
|
||||||
|
// owner of the specified organization.
|
||||||
|
func (c *Client) MigrateRepo(opt MigrateRepoOption) (*Repository, error) {
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
repo := new(Repository)
|
||||||
|
return repo, c.getParsedResponse("POST", "/repos/migrate",
|
||||||
|
http.Header{"content-type": []string{"application/json"}}, bytes.NewReader(body), repo)
|
||||||
|
}
|
||||||
|
|
2
vendor/github.com/gogits/go-gogs-client/repo_hooks.go
generated
vendored
2
vendor/github.com/gogits/go-gogs-client/repo_hooks.go
generated
vendored
|
@ -95,6 +95,8 @@ type PayloadRepo struct {
|
||||||
ID int64 `json:"id"`
|
ID int64 `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
URL string `json:"url"`
|
URL string `json:"url"`
|
||||||
|
SSHURL string `json:"ssh_url"`
|
||||||
|
CloneURL string `json:"clone_url"`
|
||||||
Description string `json:"description"`
|
Description string `json:"description"`
|
||||||
Website string `json:"website"`
|
Website string `json:"website"`
|
||||||
Watchers int `json:"watchers"`
|
Watchers int `json:"watchers"`
|
||||||
|
|
52
vendor/github.com/gogits/go-gogs-client/repo_keys.go
generated
vendored
Normal file
52
vendor/github.com/gogits/go-gogs-client/repo_keys.go
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gogs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DeployKey struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Key string `json:"key"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Title string `json:"title"`
|
||||||
|
Created time.Time `json:"created_at"`
|
||||||
|
ReadOnly bool `json:"read_only"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) ListDeployKeys(user, repo string) ([]*DeployKey, error) {
|
||||||
|
keys := make([]*DeployKey, 0, 10)
|
||||||
|
return keys, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/keys", user, repo), nil, nil, &keys)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) GetDeployKey(user, repo string, keyID int64) (*DeployKey, error) {
|
||||||
|
key := new(DeployKey)
|
||||||
|
return key, c.getParsedResponse("GET", fmt.Sprintf("/repos/%s/%s/keys/%d", user, repo, keyID), nil, nil, &key)
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateKeyOption struct {
|
||||||
|
Title string `json:"title" binding:"Required"`
|
||||||
|
Key string `json:"key" binding:"Required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) CreateDeployKey(user, repo string, opt CreateKeyOption) (*DeployKey, error) {
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
key := new(DeployKey)
|
||||||
|
return key, c.getParsedResponse("POST", fmt.Sprintf("/repos/%s/%s/keys", user, repo),
|
||||||
|
http.Header{"content-type": []string{"application/json"}}, bytes.NewReader(body), key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) DeleteDeployKey(owner, repo string, keyID int64) error {
|
||||||
|
_, err := c.getResponse("DELETE", fmt.Sprintf("/repos/%s/%s/keys/%d", owner, repo, keyID), nil, nil)
|
||||||
|
return err
|
||||||
|
}
|
2
vendor/github.com/gogits/go-gogs-client/user_app.go
generated
vendored
2
vendor/github.com/gogits/go-gogs-client/user_app.go
generated
vendored
|
@ -29,7 +29,7 @@ func (c *Client) ListAccessTokens(user, pass string) ([]*AccessToken, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateAccessTokenOption struct {
|
type CreateAccessTokenOption struct {
|
||||||
Name string `json:"name"`
|
Name string `json:"name" binding:"Required"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Client) CreateAccessToken(user, pass string, opt CreateAccessTokenOption) (*AccessToken, error) {
|
func (c *Client) CreateAccessToken(user, pass string, opt CreateAccessTokenOption) (*AccessToken, error) {
|
||||||
|
|
46
vendor/github.com/gogits/go-gogs-client/user_email.go
generated
vendored
Normal file
46
vendor/github.com/gogits/go-gogs-client/user_email.go
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gogs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Email struct {
|
||||||
|
Email string `json:"email"`
|
||||||
|
Verified bool `json:"verified"`
|
||||||
|
Primary bool `json:"primary"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) ListEmails() ([]*Email, error) {
|
||||||
|
emails := make([]*Email, 0, 3)
|
||||||
|
return emails, c.getParsedResponse("GET", "/user/emails", nil, nil, &emails)
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateEmailOption struct {
|
||||||
|
Emails []string `json:"emails"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) AddEmail(opt CreateEmailOption) ([]*Email, error) {
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
emails := make([]*Email, 0, 3)
|
||||||
|
return emails, c.getParsedResponse("POST", "/user/emails",
|
||||||
|
http.Header{"content-type": []string{"application/json"}}, bytes.NewReader(body), emails)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) DeleteEmail(opt CreateEmailOption) error {
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
_, err = c.getResponse("DELETE", "/user/emails",
|
||||||
|
http.Header{"content-type": []string{"application/json"}}, bytes.NewReader(body))
|
||||||
|
return err
|
||||||
|
}
|
47
vendor/github.com/gogits/go-gogs-client/user_follow.go
generated
vendored
Normal file
47
vendor/github.com/gogits/go-gogs-client/user_follow.go
generated
vendored
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gogs
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
func (c *Client) ListMyFollowers(page int) ([]*User, error) {
|
||||||
|
users := make([]*User, 0, 10)
|
||||||
|
return users, c.getParsedResponse("GET", fmt.Sprintf("/user/followers?page=%d", page), nil, nil, &users)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) ListFollowers(user string, page int) ([]*User, error) {
|
||||||
|
users := make([]*User, 0, 10)
|
||||||
|
return users, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/followers?page=%d", user, page), nil, nil, &users)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) ListMyFollowing(page int) ([]*User, error) {
|
||||||
|
users := make([]*User, 0, 10)
|
||||||
|
return users, c.getParsedResponse("GET", fmt.Sprintf("/user/following?page=%d", page), nil, nil, &users)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) ListFollowing(user string, page int) ([]*User, error) {
|
||||||
|
users := make([]*User, 0, 10)
|
||||||
|
return users, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/following?page=%d", user, page), nil, nil, &users)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) IsFollowing(target string) bool {
|
||||||
|
_, err := c.getResponse("GET", fmt.Sprintf("/user/following/%s", target), nil, nil)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) IsUserFollowing(user, target string) bool {
|
||||||
|
_, err := c.getResponse("GET", fmt.Sprintf("/users/%s/following/%s", user, target), nil, nil)
|
||||||
|
return err == nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Follow(target string) error {
|
||||||
|
_, err := c.getResponse("PUT", fmt.Sprintf("/user/following/%s", target), nil, nil)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) Unfollow(target string) error {
|
||||||
|
_, err := c.getResponse("DELETE", fmt.Sprintf("/user/following/%s", target), nil, nil)
|
||||||
|
return err
|
||||||
|
}
|
51
vendor/github.com/gogits/go-gogs-client/user_keys.go
generated
vendored
Normal file
51
vendor/github.com/gogits/go-gogs-client/user_keys.go
generated
vendored
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gogs
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PublicKey struct {
|
||||||
|
ID int64 `json:"id"`
|
||||||
|
Key string `json:"key"`
|
||||||
|
URL string `json:"url,omitempty"`
|
||||||
|
Title string `json:"title,omitempty"`
|
||||||
|
Created time.Time `json:"created_at,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) ListPublicKeys(user string) ([]*PublicKey, error) {
|
||||||
|
keys := make([]*PublicKey, 0, 10)
|
||||||
|
return keys, c.getParsedResponse("GET", fmt.Sprintf("/users/%s/keys", user), nil, nil, &keys)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) ListMyPublicKeys(user string) ([]*PublicKey, error) {
|
||||||
|
keys := make([]*PublicKey, 0, 10)
|
||||||
|
return keys, c.getParsedResponse("GET", fmt.Sprintf("/user/keys", user), nil, nil, &keys)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) GetPublicKey(keyID int64) (*PublicKey, error) {
|
||||||
|
key := new(PublicKey)
|
||||||
|
return key, c.getParsedResponse("GET", fmt.Sprintf("/user/keys/%d", keyID), nil, nil, &key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) CreatePublicKey(opt CreateKeyOption) (*PublicKey, error) {
|
||||||
|
body, err := json.Marshal(&opt)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
key := new(PublicKey)
|
||||||
|
return key, c.getParsedResponse("POST", "/user/keys",
|
||||||
|
http.Header{"content-type": []string{"application/json"}}, bytes.NewReader(body), key)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Client) DeletePublicKey(keyID int64) error {
|
||||||
|
_, err := c.getResponse("DELETE", fmt.Sprintf("/user/keys/%d", keyID), nil, nil)
|
||||||
|
return err
|
||||||
|
}
|
9
vendor/github.com/gogits/go-gogs-client/utils.go
generated
vendored
Normal file
9
vendor/github.com/gogits/go-gogs-client/utils.go
generated
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
// Copyright 2015 The Gogs Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package gogs
|
||||||
|
|
||||||
|
func Bool(v bool) *bool {
|
||||||
|
return &v
|
||||||
|
}
|
Loading…
Reference in a new issue