mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-02-16 19:35:14 +00:00
Refactor Gitlab Remote (#358)
- Replace custom client - Update Docs - Test if it works - Update Tests close #285
This commit is contained in:
parent
2f267e2a79
commit
169e7e5aa3
162 changed files with 33759 additions and 4253 deletions
|
@ -398,11 +398,6 @@ var flags = []cli.Flag{
|
|||
Name: "gitlab-private-mode",
|
||||
Usage: "gitlab is running in private mode",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
EnvVar: "WOODPECKER_GITLAB_V3_API",
|
||||
Name: "gitlab-v3-api",
|
||||
Usage: "gitlab is running the v3 api",
|
||||
},
|
||||
cli.BoolFlag{
|
||||
EnvVar: "WOODPECKER_STASH",
|
||||
Name: "stash",
|
||||
|
|
|
@ -32,7 +32,6 @@ import (
|
|||
"github.com/woodpecker-ci/woodpecker/server/remote/gitea"
|
||||
"github.com/woodpecker-ci/woodpecker/server/remote/github"
|
||||
"github.com/woodpecker-ci/woodpecker/server/remote/gitlab"
|
||||
"github.com/woodpecker-ci/woodpecker/server/remote/gitlab3"
|
||||
"github.com/woodpecker-ci/woodpecker/server/remote/gogs"
|
||||
"github.com/woodpecker-ci/woodpecker/server/store"
|
||||
"github.com/woodpecker-ci/woodpecker/server/store/datastore"
|
||||
|
@ -149,25 +148,14 @@ func setupStash(c *cli.Context) (remote.Remote, error) {
|
|||
|
||||
// helper function to setup the Gitlab remote from the CLI arguments.
|
||||
func setupGitlab(c *cli.Context) (remote.Remote, error) {
|
||||
if c.Bool("gitlab-v3-api") {
|
||||
return gitlab3.New(gitlab3.Opts{
|
||||
URL: c.String("gitlab-server"),
|
||||
Client: c.String("gitlab-client"),
|
||||
Secret: c.String("gitlab-secret"),
|
||||
Username: c.String("gitlab-git-username"),
|
||||
Password: c.String("gitlab-git-password"),
|
||||
PrivateMode: c.Bool("gitlab-private-mode"),
|
||||
SkipVerify: c.Bool("gitlab-skip-verify"),
|
||||
})
|
||||
}
|
||||
return gitlab.New(gitlab.Opts{
|
||||
URL: c.String("gitlab-server"),
|
||||
Client: c.String("gitlab-client"),
|
||||
Secret: c.String("gitlab-secret"),
|
||||
Username: c.String("gitlab-git-username"),
|
||||
Password: c.String("gitlab-git-password"),
|
||||
PrivateMode: c.Bool("gitlab-private-mode"),
|
||||
SkipVerify: c.Bool("gitlab-skip-verify"),
|
||||
URL: c.String("gitlab-server"),
|
||||
ClientID: c.String("gitlab-client"),
|
||||
ClientSecret: c.String("gitlab-secret"),
|
||||
Username: c.String("gitlab-git-username"),
|
||||
Password: c.String("gitlab-git-password"),
|
||||
PrivateMode: c.Bool("gitlab-private-mode"),
|
||||
SkipVerify: c.Bool("gitlab-skip-verify"),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Multi pipelines
|
||||
|
||||
> NOTE: This Feature is only available for GitHub & Gitea repositories. Follow [this](https://github.com/woodpecker-ci/woodpecker/issues/131) issue to support further development.
|
||||
> NOTE: This Feature is only available for GitHub, Gitea & Gitlab repositories. Follow [this](https://github.com/woodpecker-ci/woodpecker/issues/131) issue to support further development.
|
||||
|
||||
By default, Woodpecker looks for the pipeline definition in `.woodpecker.yml` in the project root.
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
|
||||
| Feature | [GitHub](github/) | [Gitea](gitea/) | [Gitlab](gitlab/) | [Bitbucket](bitbucket/) | [Bitbucket Server](bitbucket_server/) | Gogs | Coding |
|
||||
| --- | :---: | :---: | :---: | :---: | :---: | :---: | :---: |
|
||||
| Event: Push | :white_check_mark: | :white_check_mark: |
|
||||
| Event: Tag | :white_check_mark: | :white_check_mark: |
|
||||
| Event: Pull-Request | :white_check_mark: | :white_check_mark: |
|
||||
| Event: Deploy | :white_check_mark: | :white_check_mark: |
|
||||
| Event: Push | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| Event: Tag | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| Event: Pull-Request | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| Event: Deploy | :white_check_mark: | :white_check_mark: | :x: |
|
||||
| OAuth | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| [Multi pipeline](/docs/usage/multi-pipeline) | :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
|
||||
| [Multi pipeline](/docs/usage/multi-pipeline) | :white_check_mark: | :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | :x: |
|
||||
| [when-path filter](/docs/usage/pipeline-syntax#path) | :white_check_mark: | :white_check_mark: | :x: | :x: | :x: | :x: | :x: |
|
||||
|
|
1
go.mod
1
go.mod
|
@ -51,6 +51,7 @@ require (
|
|||
github.com/urfave/cli v1.22.4
|
||||
github.com/woodpecker-ci/expr v0.0.0-20210628233344-164b8b3d0915
|
||||
github.com/woodpecker-ci/togo v0.0.0-20180401185031-50a0e4726e74
|
||||
github.com/xanzy/go-gitlab v0.51.1
|
||||
github.com/xeipuuv/gojsonschema v1.2.0
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519
|
||||
golang.org/x/net v0.0.0-20210825183410-e898025ed96a
|
||||
|
|
11
go.sum
11
go.sum
|
@ -379,6 +379,7 @@ github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
|||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-github/v39 v39.1.0 h1:1vf4gM0D1e+Df2HMxaYC3+o9+Huj3ywGTtWc3VVYaDA=
|
||||
github.com/google/go-github/v39 v39.1.0/go.mod h1:C1s8C5aCC9L+JXIYpJM5GYytdX52vC1bLvHEF1IhBrE=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
|
||||
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
|
@ -414,8 +415,14 @@ github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t
|
|||
github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
|
||||
github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
|
||||
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||
github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I=
|
||||
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.8 h1:92lWxgpa+fF3FozM4B3UZtHZMJX8T5XT+TFdCxsPyWs=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
|
||||
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw=
|
||||
github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
|
@ -696,6 +703,8 @@ github.com/woodpecker-ci/expr v0.0.0-20210628233344-164b8b3d0915 h1:9zBOoKSR9CBe
|
|||
github.com/woodpecker-ci/expr v0.0.0-20210628233344-164b8b3d0915/go.mod h1:PbzlZ93HrA1cf16OUP1vckAPq57gtF+ccnwZeDkmC9s=
|
||||
github.com/woodpecker-ci/togo v0.0.0-20180401185031-50a0e4726e74 h1:q/tWgA3hMWrAQqsS4yfhc0+w4RevBGr9ghem/bFFDRY=
|
||||
github.com/woodpecker-ci/togo v0.0.0-20180401185031-50a0e4726e74/go.mod h1:lykh/ei/caPO6sv4NN+pqnDTo8kEKhZcnhafN8GhGNs=
|
||||
github.com/xanzy/go-gitlab v0.51.1 h1:wWKLalwx4omxFoHh3PLs9zDgAD4GXDP/uoxwMRCSiWM=
|
||||
github.com/xanzy/go-gitlab v0.51.1/go.mod h1:Q+hQhV508bDPoBijv7YjK/Lvlb4PhVhJdKqXVQrUoAE=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
|
||||
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
|
||||
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
|
||||
|
@ -811,6 +820,7 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b
|
|||
golang.org/x/net v0.0.0-20210825183410-e898025ed96a h1:bRuuGXV8wwSdGTB+CtJf+FjgO1APK1CoO39T4BN/XBw=
|
||||
golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
|
@ -969,6 +979,7 @@ google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/
|
|||
google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
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
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
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
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
groupsUrl = "/groups"
|
||||
)
|
||||
|
||||
// Get a list of all projects owned by the authenticated user.
|
||||
func (g *Client) AllGroups() ([]*Namespace, error) {
|
||||
var perPage = 100
|
||||
var groups []*Namespace
|
||||
|
||||
for i := 1; true; i++ {
|
||||
contents, err := g.Groups(i, perPage)
|
||||
if err != nil {
|
||||
return groups, err
|
||||
}
|
||||
|
||||
for _, value := range contents {
|
||||
groups = append(groups, value)
|
||||
}
|
||||
|
||||
if len(groups) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
if len(groups)/i < perPage {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return groups, nil
|
||||
}
|
||||
|
||||
func (g *Client) Groups(page, perPage int) ([]*Namespace, error) {
|
||||
url, opaque := g.ResourceUrl(groupsUrl, nil, QMap{
|
||||
"page": strconv.Itoa(page),
|
||||
"per_page": strconv.Itoa(perPage),
|
||||
})
|
||||
|
||||
var groups []*Namespace
|
||||
|
||||
contents, err := g.Do("GET", url, opaque, nil)
|
||||
if err == nil {
|
||||
err = json.Unmarshal(contents, &groups)
|
||||
}
|
||||
|
||||
return groups, err
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
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
|
||||
}
|
|
@ -1,168 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
projectsUrl = "/projects"
|
||||
projectUrl = "/projects/:id"
|
||||
repoUrlRawFileRef = "/projects/:id/repository/files/:filepath"
|
||||
commitStatusUrl = "/projects/:id/statuses/:sha"
|
||||
)
|
||||
|
||||
// Get a list of all projects owned by the authenticated user.
|
||||
func (g *Client) AllProjects(hide_archives bool) ([]*Project, error) {
|
||||
var per_page = 100
|
||||
var projects []*Project
|
||||
|
||||
for i := 1; true; i++ {
|
||||
contents, err := g.Projects(i, per_page, hide_archives)
|
||||
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, hide_archives bool) ([]*Project, error) {
|
||||
projectsOptions := QMap{
|
||||
"page": strconv.Itoa(page),
|
||||
"per_page": strconv.Itoa(per_page),
|
||||
"membership": "true",
|
||||
}
|
||||
|
||||
if hide_archives {
|
||||
projectsOptions["archived"] = "false"
|
||||
}
|
||||
|
||||
url, opaque := c.ResourceUrl(projectsUrl, nil, projectsOptions)
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
func (c *Client) RepoRawFileRef(id, ref, filepath string) ([]byte, error) {
|
||||
var fileRef FileRef
|
||||
url, opaque := c.ResourceUrl(
|
||||
repoUrlRawFileRef,
|
||||
QMap{
|
||||
":id": id,
|
||||
":filepath": filepath,
|
||||
},
|
||||
QMap{
|
||||
"ref": ref,
|
||||
},
|
||||
)
|
||||
|
||||
contents, err := c.Do("GET", url, opaque, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal(contents, &fileRef)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fileRawContent, err := base64.StdEncoding.DecodeString(fileRef.Content)
|
||||
return fileRawContent, 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(projectsUrl, nil, QMap{
|
||||
"query": strings.ToLower(name),
|
||||
"membership": "true",
|
||||
})
|
||||
|
||||
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
|
||||
}
|
|
@ -1,164 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
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"`
|
||||
AvatarUrl string `json:"avatar_url"`
|
||||
Permissions *Permissions `json:"permissions,omitempty"`
|
||||
}
|
||||
|
||||
type Namespace struct {
|
||||
Id int `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Path string `json:"path,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"`
|
||||
GitSshUrl string `json:"git_ssh_url"`
|
||||
GitHttpUrl string `json:"git_http_url"`
|
||||
AvatarUrl string `json:"avatar_url"`
|
||||
VisibilityLevel int `json:"visibility_level"`
|
||||
WebUrl string `json:"web_url"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
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"`
|
||||
Project *hProject `json:"project,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"`
|
||||
}
|
||||
|
||||
type FileRef struct {
|
||||
FileName string `json:"file_name,omitempty"`
|
||||
FilePath string `json:"file_path,omitempty"`
|
||||
Size int `json:"size,omitempty"`
|
||||
Encoding string `json:"encoding,omitempty"`
|
||||
Content string `json:"content"`
|
||||
Ref string `json:"ref,omitempty"`
|
||||
BlobId string `json:"blob_id,omitempty"`
|
||||
CommitId string `json:"commit_id,omitempty"`
|
||||
LastCommitId string `json:"last_commit_id,omitempty"`
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
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
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var encodeMap = map[string]string{
|
||||
".": "%252E",
|
||||
}
|
||||
|
||||
func encodeParameter(value string) string {
|
||||
value = url.QueryEscape(value)
|
||||
|
||||
for before, after := range encodeMap {
|
||||
value = strings.Replace(value, before, after, -1)
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
243
server/remote/gitlab/convert.go
Normal file
243
server/remote/gitlab/convert.go
Normal file
|
@ -0,0 +1,243 @@
|
|||
// Copyright 2021 Woodpecker Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/woodpecker-ci/woodpecker/server/model"
|
||||
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
func (g *Gitlab) convertGitlabRepo(repo_ *gitlab.Project) (*model.Repo, error) {
|
||||
parts := strings.Split(repo_.PathWithNamespace, "/")
|
||||
// TODO: save repo id (support nested repos)
|
||||
var owner = parts[0]
|
||||
var name = parts[1]
|
||||
repo := &model.Repo{
|
||||
Owner: owner,
|
||||
Name: name,
|
||||
FullName: repo_.PathWithNamespace,
|
||||
Avatar: repo_.AvatarURL,
|
||||
Link: repo_.WebURL,
|
||||
Clone: repo_.HTTPURLToRepo,
|
||||
Branch: repo_.DefaultBranch,
|
||||
Visibility: string(repo_.Visibility),
|
||||
}
|
||||
|
||||
if len(repo.Branch) == 0 { // TODO: do we need that?
|
||||
repo.Branch = "master"
|
||||
}
|
||||
|
||||
if len(repo.Avatar) != 0 && !strings.HasPrefix(repo.Avatar, "http") {
|
||||
repo.Avatar = fmt.Sprintf("%s/%s", g.URL, repo.Avatar)
|
||||
}
|
||||
|
||||
if g.PrivateMode {
|
||||
repo.IsPrivate = true
|
||||
} else {
|
||||
repo.IsPrivate = !repo_.Public
|
||||
}
|
||||
|
||||
return repo, nil
|
||||
}
|
||||
|
||||
func convertMergeRequestHock(hook *gitlab.MergeEvent, req *http.Request) (*model.Repo, *model.Build, error) {
|
||||
repo := &model.Repo{}
|
||||
build := &model.Build{}
|
||||
|
||||
target := hook.ObjectAttributes.Target
|
||||
source := hook.ObjectAttributes.Source
|
||||
obj := hook.ObjectAttributes
|
||||
|
||||
if target == nil && source == nil {
|
||||
return nil, nil, fmt.Errorf("target and source keys expected in merge request hook")
|
||||
} else if target == nil {
|
||||
return nil, nil, fmt.Errorf("target key expected in merge request hook")
|
||||
} else if source == nil {
|
||||
return nil, nil, fmt.Errorf("source key exptected in merge request hook")
|
||||
}
|
||||
|
||||
if target.PathWithNamespace != "" {
|
||||
var err error
|
||||
if repo.Owner, repo.Name, err = extractFromPath(target.PathWithNamespace); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
repo.FullName = target.PathWithNamespace
|
||||
} else {
|
||||
repo.Owner = req.FormValue("owner")
|
||||
repo.Name = req.FormValue("name")
|
||||
repo.FullName = fmt.Sprintf("%s/%s", repo.Owner, repo.Name)
|
||||
}
|
||||
|
||||
repo.Link = target.WebURL
|
||||
|
||||
if target.GitHTTPURL != "" {
|
||||
repo.Clone = target.GitHTTPURL
|
||||
} else {
|
||||
repo.Clone = target.HTTPURL
|
||||
}
|
||||
|
||||
if target.DefaultBranch != "" {
|
||||
repo.Branch = target.DefaultBranch
|
||||
} else {
|
||||
repo.Branch = "master"
|
||||
}
|
||||
|
||||
if target.AvatarURL != "" {
|
||||
repo.Avatar = target.AvatarURL
|
||||
}
|
||||
|
||||
build.Event = model.EventPull
|
||||
|
||||
lastCommit := obj.LastCommit
|
||||
|
||||
build.Message = lastCommit.Message
|
||||
build.Commit = lastCommit.ID
|
||||
build.Remote = obj.Source.HTTPURL
|
||||
|
||||
build.Ref = fmt.Sprintf("refs/merge-requests/%d/head", obj.IID)
|
||||
|
||||
build.Branch = obj.SourceBranch
|
||||
|
||||
author := lastCommit.Author
|
||||
|
||||
build.Author = author.Name
|
||||
build.Email = author.Email
|
||||
|
||||
if len(build.Email) != 0 {
|
||||
build.Avatar = getUserAvatar(build.Email)
|
||||
}
|
||||
|
||||
build.Title = obj.Title
|
||||
build.Link = obj.URL
|
||||
|
||||
return repo, build, nil
|
||||
}
|
||||
|
||||
func convertPushHock(hook *gitlab.PushEvent) (*model.Repo, *model.Build, error) {
|
||||
repo := &model.Repo{}
|
||||
build := &model.Build{}
|
||||
|
||||
var err error
|
||||
if repo.Owner, repo.Name, err = extractFromPath(hook.Project.PathWithNamespace); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
repo.Avatar = hook.Project.AvatarURL
|
||||
repo.Link = hook.Project.WebURL
|
||||
repo.Clone = hook.Project.GitHTTPURL
|
||||
repo.FullName = hook.Project.PathWithNamespace
|
||||
repo.Branch = hook.Project.DefaultBranch
|
||||
|
||||
switch hook.Project.Visibility {
|
||||
case gitlab.PrivateVisibility:
|
||||
repo.IsPrivate = true
|
||||
case gitlab.InternalVisibility:
|
||||
repo.IsPrivate = true
|
||||
case gitlab.PublicVisibility:
|
||||
repo.IsPrivate = false
|
||||
}
|
||||
|
||||
build.Event = model.EventPush
|
||||
build.Commit = hook.After
|
||||
build.Branch = strings.TrimPrefix(hook.Ref, "refs/heads/")
|
||||
build.Ref = hook.Ref
|
||||
|
||||
for _, cm := range hook.Commits {
|
||||
if hook.After == cm.ID {
|
||||
build.Author = cm.Author.Name
|
||||
build.Email = cm.Author.Email
|
||||
build.Message = cm.Message
|
||||
build.Timestamp = cm.Timestamp.Unix()
|
||||
if len(build.Email) != 0 {
|
||||
build.Avatar = getUserAvatar(build.Email)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return repo, build, nil
|
||||
}
|
||||
|
||||
func convertTagHock(hook *gitlab.TagEvent) (*model.Repo, *model.Build, error) {
|
||||
repo := &model.Repo{}
|
||||
build := &model.Build{}
|
||||
|
||||
var err error
|
||||
if repo.Owner, repo.Name, err = extractFromPath(hook.Project.PathWithNamespace); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
repo.Avatar = hook.Project.AvatarURL
|
||||
repo.Link = hook.Project.WebURL
|
||||
repo.Clone = hook.Project.GitHTTPURL
|
||||
repo.FullName = hook.Project.PathWithNamespace
|
||||
repo.Branch = hook.Project.DefaultBranch
|
||||
|
||||
switch hook.Project.Visibility {
|
||||
case gitlab.PrivateVisibility:
|
||||
repo.IsPrivate = true
|
||||
case gitlab.InternalVisibility:
|
||||
repo.IsPrivate = true
|
||||
case gitlab.PublicVisibility:
|
||||
repo.IsPrivate = false
|
||||
}
|
||||
|
||||
build.Event = model.EventTag
|
||||
build.Commit = hook.After
|
||||
build.Branch = strings.TrimPrefix(hook.Ref, "refs/heads/")
|
||||
build.Ref = hook.Ref
|
||||
|
||||
for _, cm := range hook.Commits {
|
||||
if hook.After == cm.ID {
|
||||
build.Author = cm.Author.Name
|
||||
build.Email = cm.Author.Email
|
||||
build.Message = cm.Message
|
||||
build.Timestamp = cm.Timestamp.Unix()
|
||||
if len(build.Email) != 0 {
|
||||
build.Avatar = getUserAvatar(build.Email)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return repo, build, nil
|
||||
}
|
||||
|
||||
func getUserAvatar(email string) string {
|
||||
hasher := md5.New()
|
||||
hasher.Write([]byte(email))
|
||||
|
||||
return fmt.Sprintf(
|
||||
"%s/%v.jpg?s=%s",
|
||||
gravatarBase,
|
||||
hex.EncodeToString(hasher.Sum(nil)),
|
||||
"128",
|
||||
)
|
||||
}
|
||||
|
||||
func extractFromPath(str string) (string, string, error) {
|
||||
s := strings.Split(str, "/")
|
||||
if len(s) < 2 {
|
||||
return "", "", fmt.Errorf("Minimum match not found")
|
||||
}
|
||||
return s[0], s[1], nil
|
||||
}
|
|
@ -17,12 +17,12 @@ package gitlab
|
|||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/woodpecker-ci/woodpecker/server"
|
||||
|
@ -30,20 +30,38 @@ import (
|
|||
"github.com/woodpecker-ci/woodpecker/server/remote"
|
||||
"github.com/woodpecker-ci/woodpecker/shared/oauth2"
|
||||
|
||||
"github.com/woodpecker-ci/woodpecker/server/remote/gitlab/client"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
const DefaultScope = "api"
|
||||
const (
|
||||
defaultScope = "api"
|
||||
perPage = 100
|
||||
statusContext = "ci/drone"
|
||||
)
|
||||
|
||||
// Opts defines configuration options.
|
||||
type Opts struct {
|
||||
URL string // Gogs server url.
|
||||
Client string // Oauth2 client id.
|
||||
Secret string // Oauth2 client secret.
|
||||
Username string // Optional machine account username.
|
||||
Password string // Optional machine account password.
|
||||
PrivateMode bool // Gogs is running in private mode.
|
||||
SkipVerify bool // Skip ssl verification.
|
||||
URL string // Gitlab server url.
|
||||
ClientID string // Oauth2 client id.
|
||||
ClientSecret string // Oauth2 client secret.
|
||||
Username string // Optional machine account username.
|
||||
Password string // Optional machine account password.
|
||||
PrivateMode bool // Gogs is running in private mode.
|
||||
SkipVerify bool // Skip ssl verification.
|
||||
}
|
||||
|
||||
// Gitlab implements "Remote" interface
|
||||
type Gitlab struct {
|
||||
URL string
|
||||
ClientID string
|
||||
ClientSecret string
|
||||
Machine string
|
||||
Username string
|
||||
Password string
|
||||
PrivateMode bool
|
||||
SkipVerify bool
|
||||
HideArchives bool
|
||||
Search bool
|
||||
}
|
||||
|
||||
// New returns a Remote implementation that integrates with Gitlab, an open
|
||||
|
@ -58,78 +76,29 @@ func New(opts Opts) (remote.Remote, error) {
|
|||
u.Host = host
|
||||
}
|
||||
return &Gitlab{
|
||||
URL: opts.URL,
|
||||
Client: opts.Client,
|
||||
Secret: opts.Secret,
|
||||
Machine: u.Host,
|
||||
Username: opts.Username,
|
||||
Password: opts.Password,
|
||||
PrivateMode: opts.PrivateMode,
|
||||
SkipVerify: opts.SkipVerify,
|
||||
URL: opts.URL,
|
||||
ClientID: opts.ClientID,
|
||||
ClientSecret: opts.ClientSecret,
|
||||
Machine: u.Host,
|
||||
Username: opts.Username,
|
||||
Password: opts.Password,
|
||||
PrivateMode: opts.PrivateMode,
|
||||
SkipVerify: opts.SkipVerify,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type Gitlab struct {
|
||||
URL string
|
||||
Client string
|
||||
Secret string
|
||||
Machine string
|
||||
Username string
|
||||
Password string
|
||||
PrivateMode bool
|
||||
SkipVerify bool
|
||||
HideArchives bool
|
||||
Search bool
|
||||
}
|
||||
|
||||
func Load(config string) *Gitlab {
|
||||
url_, err := url.Parse(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
params := url_.Query()
|
||||
url_.RawQuery = ""
|
||||
|
||||
gitlab := Gitlab{}
|
||||
gitlab.URL = url_.String()
|
||||
gitlab.Client = params.Get("client_id")
|
||||
gitlab.Secret = params.Get("client_secret")
|
||||
// gitlab.AllowedOrgs = params["orgs"]
|
||||
gitlab.SkipVerify, _ = strconv.ParseBool(params.Get("skip_verify"))
|
||||
gitlab.HideArchives, _ = strconv.ParseBool(params.Get("hide_archives"))
|
||||
// gitlab.Open, _ = strconv.ParseBool(params.Get("open"))
|
||||
|
||||
// switch params.Get("clone_mode") {
|
||||
// case "oauth":
|
||||
// gitlab.CloneMode = "oauth"
|
||||
// default:
|
||||
// gitlab.CloneMode = "token"
|
||||
// }
|
||||
|
||||
// this is a temp workaround
|
||||
gitlab.Search, _ = strconv.ParseBool(params.Get("search"))
|
||||
|
||||
return &gitlab
|
||||
}
|
||||
|
||||
// Login authenticates the session and returns the
|
||||
// remote user details.
|
||||
func (g *Gitlab) Login(ctx context.Context, res http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
|
||||
var config = &oauth2.Config{
|
||||
ClientId: g.Client,
|
||||
ClientSecret: g.Secret,
|
||||
Scope: DefaultScope,
|
||||
ClientId: g.ClientID,
|
||||
ClientSecret: g.ClientSecret,
|
||||
Scope: defaultScope,
|
||||
AuthURL: fmt.Sprintf("%s/oauth/authorize", g.URL),
|
||||
TokenURL: fmt.Sprintf("%s/oauth/token", g.URL),
|
||||
RedirectURL: fmt.Sprintf("%s/authorize", server.Config.Server.Host),
|
||||
}
|
||||
|
||||
trans_ := &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: g.SkipVerify},
|
||||
}
|
||||
|
||||
// get the OAuth errors
|
||||
if err := req.FormValue("error"); err != "" {
|
||||
return nil, &remote.AuthError{
|
||||
|
@ -146,248 +115,262 @@ func (g *Gitlab) Login(ctx context.Context, res http.ResponseWriter, req *http.R
|
|||
return nil, nil
|
||||
}
|
||||
|
||||
var trans = &oauth2.Transport{Config: config, Transport: trans_}
|
||||
var trans = &oauth2.Transport{Config: config, Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: g.SkipVerify},
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
}}
|
||||
var token_, err = trans.Exchange(code)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error exchanging token. %s", err)
|
||||
}
|
||||
|
||||
client := NewClient(g.URL, token_.AccessToken, g.SkipVerify)
|
||||
login, err := client.CurrentUser()
|
||||
client, err := newClient(g.URL, token_.AccessToken, g.SkipVerify)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if len(g.AllowedOrgs) != 0 {
|
||||
// groups, err := client.AllGroups()
|
||||
// if err != nil {
|
||||
// return nil, fmt.Errorf("Could not check org membership. %s", err)
|
||||
// }
|
||||
//
|
||||
// var member bool
|
||||
// for _, group := range groups {
|
||||
// for _, allowedOrg := range g.AllowedOrgs {
|
||||
// if group.Path == allowedOrg {
|
||||
// member = true
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if !member {
|
||||
// return nil, false, fmt.Errorf("User does not belong to correct group. Must belong to %v", g.AllowedOrgs)
|
||||
// }
|
||||
// }
|
||||
login, _, err := client.Users.CurrentUser(gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
user := &model.User{}
|
||||
user.Login = login.Username
|
||||
user.Email = login.Email
|
||||
user.Token = token_.AccessToken
|
||||
user.Secret = token_.RefreshToken
|
||||
|
||||
if strings.HasPrefix(login.AvatarUrl, "http") {
|
||||
user.Avatar = login.AvatarUrl
|
||||
} else {
|
||||
user.Avatar = g.URL + "/" + login.AvatarUrl
|
||||
user := &model.User{
|
||||
Login: login.Username,
|
||||
Email: login.Email,
|
||||
Avatar: login.AvatarURL,
|
||||
Token: token_.AccessToken,
|
||||
Secret: token_.RefreshToken,
|
||||
}
|
||||
if !strings.HasPrefix(user.Avatar, "http") {
|
||||
user.Avatar = g.URL + "/" + login.AvatarURL
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (g *Gitlab) Auth(ctx context.Context, token, secret string) (string, error) {
|
||||
client := NewClient(g.URL, token, g.SkipVerify)
|
||||
login, err := client.CurrentUser()
|
||||
// Auth authenticates the session and returns the remote user login for the given token
|
||||
func (g *Gitlab) Auth(ctx context.Context, token, _ string) (string, error) {
|
||||
client, err := newClient(g.URL, token, g.SkipVerify)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
login, _, err := client.Users.CurrentUser(gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return login.Username, nil
|
||||
}
|
||||
|
||||
func (g *Gitlab) Teams(ctx context.Context, u *model.User) ([]*model.Team, error) {
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
groups, err := client.AllGroups()
|
||||
// Teams fetches a list of team memberships from the remote system.
|
||||
func (g *Gitlab) Teams(ctx context.Context, user *model.User) ([]*model.Team, error) {
|
||||
client, err := newClient(g.URL, user.Token, g.SkipVerify)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var teams []*model.Team
|
||||
for _, group := range groups {
|
||||
teams = append(teams, &model.Team{
|
||||
Login: group.Name,
|
||||
})
|
||||
|
||||
teams := make([]*model.Team, 0, perPage)
|
||||
|
||||
for i := 1; true; i++ {
|
||||
batch, _, err := client.Groups.ListGroups(&gitlab.ListGroupsOptions{
|
||||
ListOptions: gitlab.ListOptions{Page: i, PerPage: perPage},
|
||||
AllAvailable: gitlab.Bool(false),
|
||||
MinAccessLevel: gitlab.AccessLevel(gitlab.DeveloperPermissions), // TODO: check whats best here
|
||||
}, gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := range batch {
|
||||
teams = append(teams, &model.Team{
|
||||
Login: batch[i].Name,
|
||||
Avatar: batch[i].AvatarURL,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
if len(batch) < perPage {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return teams, nil
|
||||
}
|
||||
|
||||
// getProject fetches the named repository from the remote system.
|
||||
func (g *Gitlab) getProject(ctx context.Context, client *gitlab.Client, owner, name string) (*gitlab.Project, error) {
|
||||
repo, _, err := client.Projects.GetProject(fmt.Sprintf("%s/%s", owner, name), nil, gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return repo, nil
|
||||
}
|
||||
|
||||
// Repo fetches the named repository from the remote system.
|
||||
func (g *Gitlab) Repo(ctx context.Context, u *model.User, owner, name string) (*model.Repo, error) {
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, owner, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
repo_, err := client.Project(id)
|
||||
func (g *Gitlab) Repo(ctx context.Context, user *model.User, owner, name string) (*model.Repo, error) {
|
||||
client, err := newClient(g.URL, user.Token, g.SkipVerify)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repo := &model.Repo{}
|
||||
repo.Owner = owner
|
||||
repo.Name = name
|
||||
repo.FullName = repo_.PathWithNamespace
|
||||
repo.Link = repo_.Url
|
||||
repo.Clone = repo_.HttpRepoUrl
|
||||
repo.Branch = "master"
|
||||
|
||||
repo.Avatar = repo_.AvatarUrl
|
||||
|
||||
if len(repo.Avatar) != 0 && !strings.HasPrefix(repo.Avatar, "http") {
|
||||
repo.Avatar = fmt.Sprintf("%s/%s", g.URL, repo.Avatar)
|
||||
repo_, err := g.getProject(ctx, client, owner, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if repo_.DefaultBranch != "" {
|
||||
repo.Branch = repo_.DefaultBranch
|
||||
}
|
||||
|
||||
if g.PrivateMode {
|
||||
repo.IsPrivate = true
|
||||
} else {
|
||||
repo.IsPrivate = !repo_.Public
|
||||
}
|
||||
|
||||
return repo, err
|
||||
return g.convertGitlabRepo(repo_)
|
||||
}
|
||||
|
||||
// Repos fetches a list of repos from the remote system.
|
||||
func (g *Gitlab) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
|
||||
var repos = []*model.Repo{}
|
||||
|
||||
all, err := client.AllProjects(g.HideArchives)
|
||||
func (g *Gitlab) Repos(ctx context.Context, user *model.User) ([]*model.Repo, error) {
|
||||
client, err := newClient(g.URL, user.Token, g.SkipVerify)
|
||||
if err != nil {
|
||||
return repos, err
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, repo_ := range all {
|
||||
var parts = strings.Split(repo_.PathWithNamespace, "/")
|
||||
var owner = parts[0]
|
||||
var name = parts[1]
|
||||
repos := make([]*model.Repo, 0, perPage)
|
||||
opts := &gitlab.ListProjectsOptions{
|
||||
ListOptions: gitlab.ListOptions{PerPage: perPage},
|
||||
MinAccessLevel: gitlab.AccessLevel(gitlab.DeveloperPermissions), // TODO: check whats best here
|
||||
}
|
||||
if g.HideArchives {
|
||||
opts.Archived = gitlab.Bool(false)
|
||||
}
|
||||
|
||||
repo := &model.Repo{}
|
||||
repo.Owner = owner
|
||||
repo.Name = name
|
||||
repo.FullName = repo_.PathWithNamespace
|
||||
repo.Link = repo_.Url
|
||||
repo.Clone = repo_.HttpRepoUrl
|
||||
repo.Branch = "master"
|
||||
|
||||
if repo_.DefaultBranch != "" {
|
||||
repo.Branch = repo_.DefaultBranch
|
||||
for i := 1; true; i++ {
|
||||
opts.Page = i
|
||||
batch, _, err := client.Projects.ListProjects(opts, gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if g.PrivateMode {
|
||||
repo.IsPrivate = true
|
||||
} else {
|
||||
repo.IsPrivate = !repo_.Public
|
||||
for i := range batch {
|
||||
repo, err := g.convertGitlabRepo(batch[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
repos = append(repos, repo)
|
||||
}
|
||||
|
||||
repos = append(repos, repo)
|
||||
if len(batch) < perPage {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return repos, err
|
||||
}
|
||||
|
||||
// Perm fetches the named repository from the remote system.
|
||||
func (g *Gitlab) Perm(ctx context.Context, u *model.User, owner, name string) (*model.Perm, error) {
|
||||
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, owner, name)
|
||||
func (g *Gitlab) Perm(ctx context.Context, user *model.User, owner, name string) (*model.Perm, error) {
|
||||
client, err := newClient(g.URL, user.Token, g.SkipVerify)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repo, err := client.Project(id)
|
||||
repo, err := g.getProject(ctx, client, owner, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// repo owner is granted full access
|
||||
if repo.Owner != nil && repo.Owner.Username == u.Login {
|
||||
if repo.Owner != nil && repo.Owner.Username == user.Login {
|
||||
return &model.Perm{Push: true, Pull: true, Admin: true}, nil
|
||||
}
|
||||
|
||||
// check permission for current user
|
||||
m := &model.Perm{}
|
||||
m.Admin = IsAdmin(repo)
|
||||
m.Pull = IsRead(repo)
|
||||
m.Push = IsWrite(repo)
|
||||
return m, nil
|
||||
// return permission for current user
|
||||
return &model.Perm{
|
||||
Pull: isRead(repo),
|
||||
Push: isWrite(repo),
|
||||
Admin: isAdmin(repo),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// File fetches a file from the remote repository and returns in string format.
|
||||
func (g *Gitlab) File(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]byte, error) {
|
||||
var client = NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, r.Owner, r.Name)
|
||||
func (g *Gitlab) File(ctx context.Context, user *model.User, repo *model.Repo, build *model.Build, fileName string) ([]byte, error) {
|
||||
client, err := newClient(g.URL, user.Token, g.SkipVerify)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
repo_, err := g.getProject(ctx, client, repo.Owner, repo.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
file, _, err := client.RepositoryFiles.GetRawFile(repo_.ID, fileName, &gitlab.GetRawFileOptions{Ref: &build.Commit}, gitlab.WithContext(ctx))
|
||||
return file, err
|
||||
}
|
||||
|
||||
// Dir fetches a folder from the remote repository
|
||||
func (g *Gitlab) Dir(ctx context.Context, user *model.User, repo *model.Repo, build *model.Build, path string) ([]*remote.FileMeta, error) {
|
||||
client, err := newClient(g.URL, user.Token, g.SkipVerify)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out, err := client.RepoRawFileRef(id, b.Commit, f)
|
||||
files := make([]*remote.FileMeta, 0, perPage)
|
||||
repo_, err := g.getProject(ctx, client, repo.Owner, repo.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, err
|
||||
opts := &gitlab.ListTreeOptions{
|
||||
ListOptions: gitlab.ListOptions{PerPage: perPage},
|
||||
Path: &path,
|
||||
Ref: &build.Commit,
|
||||
Recursive: gitlab.Bool(false),
|
||||
}
|
||||
|
||||
for i := 1; true; i++ {
|
||||
opts.Page = 1
|
||||
batch, _, err := client.Repositories.ListTree(repo_.ID, opts, gitlab.WithContext(ctx))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := range batch {
|
||||
if batch[i].Type != "blob" { // no file
|
||||
continue
|
||||
}
|
||||
data, err := g.File(ctx, user, repo, build, batch[i].Path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
files = append(files, &remote.FileMeta{
|
||||
Name: batch[i].Path,
|
||||
Data: data,
|
||||
})
|
||||
}
|
||||
|
||||
if len(batch) < perPage {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return files, nil
|
||||
}
|
||||
|
||||
func (c *Gitlab) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
return nil, fmt.Errorf("Not implemented")
|
||||
// Status sends the commit status back to gitlab.
|
||||
func (g *Gitlab) Status(ctx context.Context, user *model.User, repo *model.Repo, build *model.Build, link string, proc *model.Proc) error {
|
||||
client, err := newClient(g.URL, user.Token, g.SkipVerify)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
repo_, err := g.getProject(ctx, client, repo.Owner, repo.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
_, _, err = client.Commits.SetCommitStatus(repo_.ID, build.Commit, &gitlab.SetCommitStatusOptions{
|
||||
Ref: gitlab.String(strings.ReplaceAll(build.Ref, "refs/heads/", "")),
|
||||
State: getStatus(build.Status),
|
||||
Description: gitlab.String(getDesc(build.Status)),
|
||||
TargetURL: &link,
|
||||
Name: nil,
|
||||
Context: gitlab.String(statusContext),
|
||||
}, gitlab.WithContext(ctx))
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// NOTE Currently gitlab doesn't support status for commits and events,
|
||||
// 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.
|
||||
func (g *Gitlab) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
|
||||
status := getStatus(b.Status)
|
||||
desc := getDesc(b.Status)
|
||||
|
||||
client.SetStatus(
|
||||
ns(r.Owner, r.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
|
||||
}
|
||||
|
||||
// Netrc returns a .netrc file that can be used to clone
|
||||
// private repositories from a remote system.
|
||||
// func (g *Gitlab) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) {
|
||||
// url_, err := url.Parse(g.URL)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// netrc := &model.Netrc{}
|
||||
// netrc.Machine = url_.Host
|
||||
//
|
||||
// switch g.CloneMode {
|
||||
// case "oauth":
|
||||
// netrc.Login = "oauth2"
|
||||
// netrc.Password = u.Token
|
||||
// case "token":
|
||||
// t := token.New(token.HookToken, r.FullName)
|
||||
// netrc.Login = "drone-ci-token"
|
||||
// netrc.Password, err = t.Sign(r.Hash)
|
||||
// }
|
||||
// return netrc, err
|
||||
// }
|
||||
|
||||
// Netrc returns a netrc file capable of authenticating Gitlab requests and
|
||||
// cloning Gitlab repositories. The netrc will use the global machine account
|
||||
// when configured.
|
||||
|
@ -408,296 +391,90 @@ func (g *Gitlab) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) {
|
|||
|
||||
// Activate activates a repository by adding a Post-commit hook and
|
||||
// a Public Deploy key, if applicable.
|
||||
func (g *Gitlab) Activate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
var client = NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, r.Owner, r.Name)
|
||||
func (g *Gitlab) Activate(ctx context.Context, user *model.User, repo *model.Repo, link string) error {
|
||||
client, err := newClient(g.URL, user.Token, g.SkipVerify)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
uri, err := url.Parse(link)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
token := uri.Query().Get("access_token")
|
||||
webUrl := fmt.Sprintf("%s://%s", uri.Scheme, uri.Host)
|
||||
|
||||
droneUrl := fmt.Sprintf("%s://%s", uri.Scheme, uri.Host)
|
||||
droneToken := uri.Query().Get("access_token")
|
||||
ssl_verify := strconv.FormatBool(!g.SkipVerify)
|
||||
|
||||
return client.AddDroneService(id, map[string]string{
|
||||
"token": droneToken,
|
||||
"drone_url": droneUrl,
|
||||
"enable_ssl_verification": ssl_verify,
|
||||
})
|
||||
repo_, err := g.getProject(ctx, client, repo.Owner, repo.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO: "WoodpeckerCIService"
|
||||
_, err = client.Services.SetDroneCIService(repo_.ID, &gitlab.SetDroneCIServiceOptions{
|
||||
Token: &token,
|
||||
DroneURL: &webUrl,
|
||||
EnableSSLVerification: gitlab.Bool(!g.SkipVerify),
|
||||
}, gitlab.WithContext(ctx))
|
||||
return err
|
||||
}
|
||||
|
||||
// Deactivate removes a repository by removing all the post-commit hooks
|
||||
// which are equal to link and removing the SSH deploy key.
|
||||
func (g *Gitlab) Deactivate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
var client = NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, r.Owner, r.Name)
|
||||
func (g *Gitlab) Deactivate(ctx context.Context, user *model.User, repo *model.Repo, link string) error {
|
||||
client, err := newClient(g.URL, user.Token, g.SkipVerify)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return client.DeleteDroneService(id)
|
||||
repo_, err := g.getProject(ctx, client, repo.Owner, repo.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// TODO: "WoodpeckerCIService"
|
||||
_, err = client.Services.DeleteDroneCIService(repo_.ID, gitlab.WithContext(ctx))
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// ParseHook parses the post-commit hook from the Request body
|
||||
// Hook parses the post-commit hook from the Request body
|
||||
// and returns the required data in a standard format.
|
||||
func (g *Gitlab) Hook(req *http.Request) (*model.Repo, *model.Build, error) {
|
||||
defer req.Body.Close()
|
||||
var payload, _ = ioutil.ReadAll(req.Body)
|
||||
var parsed, err = client.ParseHook(payload)
|
||||
payload, err := ioutil.ReadAll(req.Body)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
switch parsed.ObjectKind {
|
||||
case "merge_request":
|
||||
return mergeRequest(parsed, req)
|
||||
case "tag_push", "push":
|
||||
return push(parsed, req)
|
||||
eventType := gitlab.WebhookEventType(req)
|
||||
// TODO: Fix Upstream: We get `Service Hook` - which the library do not understand
|
||||
if eventType == "Service Hook" {
|
||||
e := struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
}{}
|
||||
if err := json.Unmarshal(payload, &e); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
switch e.ObjectKind {
|
||||
case "push":
|
||||
eventType = gitlab.EventTypePush
|
||||
case "tag_push":
|
||||
eventType = gitlab.EventTypeTagPush
|
||||
case "merge_request":
|
||||
eventType = gitlab.EventTypeMergeRequest
|
||||
}
|
||||
}
|
||||
|
||||
parsed, err := gitlab.ParseWebhook(eventType, payload)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
switch event := parsed.(type) {
|
||||
case *gitlab.MergeEvent:
|
||||
return convertMergeRequestHock(event, req)
|
||||
case *gitlab.PushEvent:
|
||||
return convertPushHock(event)
|
||||
case *gitlab.TagEvent:
|
||||
return convertTagHock(event)
|
||||
default:
|
||||
return nil, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
func mergeRequest(parsed *client.HookPayload, req *http.Request) (*model.Repo, *model.Build, error) {
|
||||
|
||||
repo := &model.Repo{}
|
||||
|
||||
obj := parsed.ObjectAttributes
|
||||
if obj == nil {
|
||||
return nil, nil, fmt.Errorf("object_attributes key expected in merge request hook")
|
||||
}
|
||||
|
||||
target := obj.Target
|
||||
source := obj.Source
|
||||
|
||||
if target == nil && source == nil {
|
||||
return nil, nil, fmt.Errorf("target and source keys expected in merge request hook")
|
||||
} else if target == nil {
|
||||
return nil, nil, fmt.Errorf("target key expected in merge request hook")
|
||||
} else if source == nil {
|
||||
return nil, nil, fmt.Errorf("source key exptected in merge request hook")
|
||||
}
|
||||
|
||||
if target.PathWithNamespace != "" {
|
||||
var err error
|
||||
if repo.Owner, repo.Name, err = ExtractFromPath(target.PathWithNamespace); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
repo.FullName = target.PathWithNamespace
|
||||
} else {
|
||||
repo.Owner = req.FormValue("owner")
|
||||
repo.Name = req.FormValue("name")
|
||||
repo.FullName = fmt.Sprintf("%s/%s", repo.Owner, repo.Name)
|
||||
}
|
||||
|
||||
repo.Link = target.WebUrl
|
||||
|
||||
if target.GitHttpUrl != "" {
|
||||
repo.Clone = target.GitHttpUrl
|
||||
} else {
|
||||
repo.Clone = target.HttpUrl
|
||||
}
|
||||
|
||||
if target.DefaultBranch != "" {
|
||||
repo.Branch = target.DefaultBranch
|
||||
} else {
|
||||
repo.Branch = "master"
|
||||
}
|
||||
|
||||
if target.AvatarUrl != "" {
|
||||
repo.Avatar = target.AvatarUrl
|
||||
}
|
||||
|
||||
build := &model.Build{}
|
||||
build.Event = "pull_request"
|
||||
|
||||
lastCommit := obj.LastCommit
|
||||
if lastCommit == nil {
|
||||
return nil, nil, fmt.Errorf("last_commit key expected in merge request hook")
|
||||
}
|
||||
|
||||
build.Message = lastCommit.Message
|
||||
build.Commit = lastCommit.Id
|
||||
//build.Remote = parsed.ObjectAttributes.Source.HttpUrl
|
||||
|
||||
build.Ref = fmt.Sprintf("refs/merge-requests/%d/head", obj.IId)
|
||||
|
||||
build.Branch = obj.SourceBranch
|
||||
|
||||
author := lastCommit.Author
|
||||
if author == nil {
|
||||
return nil, nil, fmt.Errorf("author key expected in merge request hook")
|
||||
}
|
||||
|
||||
build.Author = author.Name
|
||||
build.Email = author.Email
|
||||
|
||||
if len(build.Email) != 0 {
|
||||
build.Avatar = GetUserAvatar(build.Email)
|
||||
}
|
||||
|
||||
build.Title = obj.Title
|
||||
build.Link = obj.Url
|
||||
|
||||
return repo, build, nil
|
||||
}
|
||||
|
||||
func push(parsed *client.HookPayload, req *http.Request) (*model.Repo, *model.Build, error) {
|
||||
repo := &model.Repo{}
|
||||
|
||||
// Since gitlab 8.5, used project instead repository key
|
||||
// see https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/web_hooks/web_hooks.md#web-hooks
|
||||
if project := parsed.Project; project != nil {
|
||||
var err error
|
||||
if repo.Owner, repo.Name, err = ExtractFromPath(project.PathWithNamespace); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
repo.Avatar = project.AvatarUrl
|
||||
repo.Link = project.WebUrl
|
||||
repo.Clone = project.GitHttpUrl
|
||||
repo.FullName = project.PathWithNamespace
|
||||
repo.Branch = project.DefaultBranch
|
||||
|
||||
switch project.VisibilityLevel {
|
||||
case 0:
|
||||
repo.IsPrivate = true
|
||||
case 10:
|
||||
repo.IsPrivate = true
|
||||
case 20:
|
||||
repo.IsPrivate = false
|
||||
}
|
||||
} else if repository := parsed.Repository; repository != nil {
|
||||
repo.Owner = req.FormValue("owner")
|
||||
repo.Name = req.FormValue("name")
|
||||
repo.Link = repository.URL
|
||||
repo.Clone = repository.GitHttpUrl
|
||||
repo.Branch = "master"
|
||||
repo.FullName = fmt.Sprintf("%s/%s", req.FormValue("owner"), req.FormValue("name"))
|
||||
|
||||
switch repository.VisibilityLevel {
|
||||
case 0:
|
||||
repo.IsPrivate = true
|
||||
case 10:
|
||||
repo.IsPrivate = true
|
||||
case 20:
|
||||
repo.IsPrivate = false
|
||||
}
|
||||
} else {
|
||||
return nil, nil, fmt.Errorf("No project/repository keys given")
|
||||
}
|
||||
|
||||
build := &model.Build{}
|
||||
build.Event = model.EventPush
|
||||
build.Commit = parsed.After
|
||||
build.Branch = parsed.Branch()
|
||||
build.Ref = parsed.Ref
|
||||
// hook.Commit.Remote = cloneUrl
|
||||
|
||||
var head = parsed.Head()
|
||||
build.Message = head.Message
|
||||
// build.Timestamp = head.Timestamp
|
||||
|
||||
// extracts the commit author (ideally email)
|
||||
// from the post-commit hook
|
||||
switch {
|
||||
case head.Author != nil:
|
||||
build.Email = head.Author.Email
|
||||
build.Author = parsed.UserName
|
||||
if len(build.Email) != 0 {
|
||||
build.Avatar = GetUserAvatar(build.Email)
|
||||
}
|
||||
case head.Author == nil:
|
||||
build.Author = parsed.UserName
|
||||
}
|
||||
|
||||
if strings.HasPrefix(build.Ref, "refs/tags/") {
|
||||
build.Event = model.EventTag
|
||||
}
|
||||
|
||||
return repo, build, nil
|
||||
}
|
||||
|
||||
// ¯\_(ツ)_/¯
|
||||
func (g *Gitlab) Oauth2Transport(r *http.Request) *oauth2.Transport {
|
||||
return &oauth2.Transport{
|
||||
Config: &oauth2.Config{
|
||||
ClientId: g.Client,
|
||||
ClientSecret: g.Secret,
|
||||
Scope: DefaultScope,
|
||||
AuthURL: fmt.Sprintf("%s/oauth/authorize", g.URL),
|
||||
TokenURL: fmt.Sprintf("%s/oauth/token", g.URL),
|
||||
RedirectURL: fmt.Sprintf("%s/authorize", server.Config.Server.Host),
|
||||
//settings.Server.Scheme, settings.Server.Hostname),
|
||||
},
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: g.SkipVerify},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
StatusPending = "pending"
|
||||
StatusRunning = "running"
|
||||
StatusSuccess = "success"
|
||||
StatusFailure = "failed"
|
||||
StatusCanceled = "canceled"
|
||||
)
|
||||
|
||||
const (
|
||||
DescPending = "the build is pending"
|
||||
DescRunning = "the buils is running"
|
||||
DescSuccess = "the build was successful"
|
||||
DescFailure = "the build failed"
|
||||
DescCanceled = "the build canceled"
|
||||
DescBlocked = "the build is pending approval"
|
||||
DescDeclined = "the build was rejected"
|
||||
)
|
||||
|
||||
// getStatus is a helper functin that converts a Drone
|
||||
// status to a GitHub status.
|
||||
func getStatus(status string) string {
|
||||
switch status {
|
||||
case model.StatusPending, model.StatusBlocked:
|
||||
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
|
||||
case model.StatusBlocked:
|
||||
return DescBlocked
|
||||
case model.StatusDeclined:
|
||||
return DescDeclined
|
||||
default:
|
||||
return DescFailure
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,21 +18,46 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/franela/goblin"
|
||||
"github.com/woodpecker-ci/woodpecker/server/model"
|
||||
"github.com/woodpecker-ci/woodpecker/server/remote/gitlab/testdata"
|
||||
|
||||
"github.com/franela/goblin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func load(config string) *Gitlab {
|
||||
url_, err := url.Parse(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
params := url_.Query()
|
||||
url_.RawQuery = ""
|
||||
|
||||
gitlab := Gitlab{}
|
||||
gitlab.URL = url_.String()
|
||||
gitlab.ClientID = params.Get("client_id")
|
||||
gitlab.ClientSecret = params.Get("client_secret")
|
||||
gitlab.SkipVerify, _ = strconv.ParseBool(params.Get("skip_verify"))
|
||||
gitlab.HideArchives, _ = strconv.ParseBool(params.Get("hide_archives"))
|
||||
|
||||
// this is a temp workaround
|
||||
gitlab.Search, _ = strconv.ParseBool(params.Get("search"))
|
||||
|
||||
return &gitlab
|
||||
}
|
||||
|
||||
func Test_Gitlab(t *testing.T) {
|
||||
// setup a dummy github server
|
||||
var server = testdata.NewServer()
|
||||
var server = testdata.NewServer(t)
|
||||
defer server.Close()
|
||||
|
||||
env := server.URL + "?client_id=test&client_secret=test"
|
||||
|
||||
gitlab := Load(env)
|
||||
client := load(env)
|
||||
|
||||
var user = model.User{
|
||||
Login: "test_user",
|
||||
|
@ -50,16 +75,15 @@ func Test_Gitlab(t *testing.T) {
|
|||
// Test projects method
|
||||
g.Describe("AllProjects", func() {
|
||||
g.It("Should return only non-archived projects is hidden", func() {
|
||||
gitlab.HideArchives = true
|
||||
_projects, err := gitlab.Repos(ctx, &user)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(len(_projects)).Equal(1)
|
||||
client.HideArchives = true
|
||||
_projects, err := client.Repos(ctx, &user)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, _projects, 1)
|
||||
})
|
||||
|
||||
g.It("Should return all the projects", func() {
|
||||
gitlab.HideArchives = false
|
||||
_projects, err := gitlab.Repos(ctx, &user)
|
||||
client.HideArchives = false
|
||||
_projects, err := client.Repos(ctx, &user)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(len(_projects)).Equal(2)
|
||||
|
@ -69,39 +93,37 @@ func Test_Gitlab(t *testing.T) {
|
|||
// Test repository method
|
||||
g.Describe("Repo", func() {
|
||||
g.It("Should return valid repo", func() {
|
||||
_repo, err := gitlab.Repo(ctx, &user, "diaspora", "diaspora-client")
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(_repo.Name).Equal("diaspora-client")
|
||||
g.Assert(_repo.Owner).Equal("diaspora")
|
||||
g.Assert(_repo.IsPrivate).Equal(true)
|
||||
_repo, err := client.Repo(ctx, &user, "diaspora", "diaspora-client")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "diaspora-client", _repo.Name)
|
||||
assert.Equal(t, "diaspora", _repo.Owner)
|
||||
assert.True(t, _repo.IsPrivate)
|
||||
})
|
||||
|
||||
g.It("Should return error, when repo not exist", func() {
|
||||
_, err := gitlab.Repo(ctx, &user, "not-existed", "not-existed")
|
||||
|
||||
g.Assert(err != nil).IsTrue()
|
||||
_, err := client.Repo(ctx, &user, "not-existed", "not-existed")
|
||||
assert.Error(t, err)
|
||||
})
|
||||
})
|
||||
|
||||
// Test permissions method
|
||||
g.Describe("Perm", func() {
|
||||
g.It("Should return repo permissions", func() {
|
||||
perm, err := gitlab.Perm(ctx, &user, "diaspora", "diaspora-client")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(perm.Admin).Equal(true)
|
||||
g.Assert(perm.Pull).Equal(true)
|
||||
g.Assert(perm.Push).Equal(true)
|
||||
perm, err := client.Perm(ctx, &user, "diaspora", "diaspora-client")
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, perm.Admin)
|
||||
assert.True(t, perm.Pull)
|
||||
assert.True(t, perm.Push)
|
||||
})
|
||||
g.It("Should return repo permissions when user is admin", func() {
|
||||
perm, err := gitlab.Perm(ctx, &user, "brightbox", "puppet")
|
||||
g.Assert(err == nil).IsTrue()
|
||||
perm, err := client.Perm(ctx, &user, "brightbox", "puppet")
|
||||
assert.NoError(t, err)
|
||||
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() {
|
||||
_, err := gitlab.Perm(ctx, &user, "not-existed", "not-existed")
|
||||
_, err := client.Perm(ctx, &user, "not-existed", "not-existed")
|
||||
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
|
@ -110,13 +132,12 @@ func Test_Gitlab(t *testing.T) {
|
|||
// Test activate method
|
||||
g.Describe("Activate", func() {
|
||||
g.It("Should be success", func() {
|
||||
err := gitlab.Activate(ctx, &user, &repo, "http://example.com/api/hook/test/test?access_token=token")
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
err := client.Activate(ctx, &user, &repo, "http://example.com/api/hook/test/test?access_token=token")
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
g.It("Should be failed, when token not given", func() {
|
||||
err := gitlab.Activate(ctx, &user, &repo, "http://example.com/api/hook/test/test")
|
||||
err := client.Activate(ctx, &user, &repo, "http://example.com/api/hook/test/test")
|
||||
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
|
@ -125,137 +146,75 @@ func Test_Gitlab(t *testing.T) {
|
|||
// Test deactivate method
|
||||
g.Describe("Deactivate", func() {
|
||||
g.It("Should be success", func() {
|
||||
err := gitlab.Deactivate(ctx, &user, &repo, "http://example.com/api/hook/test/test?access_token=token")
|
||||
err := client.Deactivate(ctx, &user, &repo, "http://example.com/api/hook/test/test?access_token=token")
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
// Test login method
|
||||
// g.Describe("Login", func() {
|
||||
// g.It("Should return user", func() {
|
||||
// user, err := gitlab.Login("valid_token", "")
|
||||
|
||||
// g.Assert(err == nil).IsTrue()
|
||||
// g.Assert(user == nil).IsFalse()
|
||||
// })
|
||||
|
||||
// g.It("Should return error, when token is invalid", func() {
|
||||
// _, err := gitlab.Login("invalid_token", "")
|
||||
|
||||
// g.Assert(err != nil).IsTrue()
|
||||
// })
|
||||
// })
|
||||
|
||||
// Test hook method
|
||||
g.Describe("Hook", func() {
|
||||
g.Describe("Push hook", func() {
|
||||
g.It("Should parse actual push hoook", func() {
|
||||
req, _ := http.NewRequest(
|
||||
"POST",
|
||||
"http://example.com/api/hook?owner=diaspora&name=diaspora-client",
|
||||
bytes.NewReader(testdata.PushHook),
|
||||
testdata.ServiceHookMethod,
|
||||
testdata.ServiceHookURL.String(),
|
||||
bytes.NewReader(testdata.ServiceHookPushBody),
|
||||
)
|
||||
req.Header = testdata.ServiceHookHeaders
|
||||
|
||||
repo, build, err := gitlab.Hook(req)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.Owner).Equal("mike")
|
||||
g.Assert(repo.Name).Equal("diaspora")
|
||||
g.Assert(repo.Avatar).Equal("http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg")
|
||||
g.Assert(repo.Branch).Equal("develop")
|
||||
g.Assert(build.Ref).Equal("refs/heads/master")
|
||||
|
||||
})
|
||||
|
||||
g.It("Should parse legacy push hoook", func() {
|
||||
req, _ := http.NewRequest(
|
||||
"POST",
|
||||
"http://example.com/api/hook?owner=diaspora&name=diaspora-client",
|
||||
bytes.NewReader(testdata.LegacyPushHook),
|
||||
)
|
||||
|
||||
repo, build, err := gitlab.Hook(req)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.Owner).Equal("diaspora")
|
||||
g.Assert(repo.Name).Equal("diaspora-client")
|
||||
g.Assert(repo.Avatar).Equal("")
|
||||
g.Assert(repo.Branch).Equal("master")
|
||||
g.Assert(build.Ref).Equal("refs/heads/master")
|
||||
|
||||
hookRepo, build, err := client.Hook(req)
|
||||
assert.NoError(t, err)
|
||||
if assert.NotNil(t, hookRepo) && assert.NotNil(t, build) {
|
||||
assert.Equal(t, build.Event, model.EventPush)
|
||||
assert.Equal(t, "test", hookRepo.Owner)
|
||||
assert.Equal(t, "woodpecker", hookRepo.Name)
|
||||
assert.Equal(t, "http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg", hookRepo.Avatar)
|
||||
assert.Equal(t, "develop", hookRepo.Branch)
|
||||
assert.Equal(t, "refs/heads/master", build.Ref)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("Tag push hook", func() {
|
||||
g.It("Should parse tag push hook", func() {
|
||||
req, _ := http.NewRequest(
|
||||
"POST",
|
||||
"http://example.com/api/hook?owner=diaspora&name=diaspora-client",
|
||||
bytes.NewReader(testdata.TagHook),
|
||||
testdata.ServiceHookMethod,
|
||||
testdata.ServiceHookURL.String(),
|
||||
bytes.NewReader(testdata.ServiceHookTagPushBody),
|
||||
)
|
||||
req.Header = testdata.ServiceHookHeaders
|
||||
|
||||
repo, build, err := gitlab.Hook(req)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.Owner).Equal("jsmith")
|
||||
g.Assert(repo.Name).Equal("example")
|
||||
g.Assert(repo.Avatar).Equal("http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg")
|
||||
g.Assert(repo.Branch).Equal("develop")
|
||||
g.Assert(build.Ref).Equal("refs/tags/v1.0.0")
|
||||
|
||||
})
|
||||
|
||||
g.It("Should parse legacy tag push hook", func() {
|
||||
req, _ := http.NewRequest(
|
||||
"POST",
|
||||
"http://example.com/api/hook?owner=diaspora&name=diaspora-client",
|
||||
bytes.NewReader(testdata.LegacyTagHook),
|
||||
)
|
||||
|
||||
repo, build, err := gitlab.Hook(req)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.Owner).Equal("diaspora")
|
||||
g.Assert(repo.Name).Equal("diaspora-client")
|
||||
g.Assert(build.Ref).Equal("refs/tags/v1.0.0")
|
||||
|
||||
hookRepo, build, err := client.Hook(req)
|
||||
assert.NoError(t, err)
|
||||
if assert.NotNil(t, hookRepo) && assert.NotNil(t, build) {
|
||||
assert.Equal(t, "test", hookRepo.Owner)
|
||||
assert.Equal(t, "woodpecker", hookRepo.Name)
|
||||
assert.Equal(t, "http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg", hookRepo.Avatar)
|
||||
assert.Equal(t, "develop", hookRepo.Branch)
|
||||
assert.Equal(t, "refs/tags/v22", build.Ref)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("Merge request hook", func() {
|
||||
g.It("Should parse merge request hook", func() {
|
||||
req, _ := http.NewRequest(
|
||||
"POST",
|
||||
"http://example.com/api/hook?owner=diaspora&name=diaspora-client",
|
||||
bytes.NewReader(testdata.MergeRequestHook),
|
||||
testdata.ServiceHookMethod,
|
||||
testdata.ServiceHookURL.String(),
|
||||
bytes.NewReader(testdata.ServiceHookMergeRequestBody),
|
||||
)
|
||||
req.Header = testdata.ServiceHookHeaders
|
||||
|
||||
repo, build, err := gitlab.Hook(req)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.Avatar).Equal("http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg")
|
||||
g.Assert(repo.Branch).Equal("develop")
|
||||
g.Assert(repo.Owner).Equal("awesome_space")
|
||||
g.Assert(repo.Name).Equal("awesome_project")
|
||||
|
||||
g.Assert(build.Title).Equal("MS-Viewport")
|
||||
})
|
||||
|
||||
g.It("Should parse legacy merge request hook", func() {
|
||||
req, _ := http.NewRequest(
|
||||
"POST",
|
||||
"http://example.com/api/hook?owner=diaspora&name=diaspora-client",
|
||||
bytes.NewReader(testdata.LegacyMergeRequestHook),
|
||||
)
|
||||
|
||||
repo, build, err := gitlab.Hook(req)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.Owner).Equal("diaspora")
|
||||
g.Assert(repo.Name).Equal("diaspora-client")
|
||||
|
||||
g.Assert(build.Title).Equal("MS-Viewport")
|
||||
hookRepo, build, err := client.Hook(req)
|
||||
assert.NoError(t, err)
|
||||
if assert.NotNil(t, hookRepo) && assert.NotNil(t, build) {
|
||||
assert.Equal(t, "http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg", hookRepo.Avatar)
|
||||
assert.Equal(t, "develop", hookRepo.Branch)
|
||||
assert.Equal(t, "test", hookRepo.Owner)
|
||||
assert.Equal(t, "woodpecker", hookRepo.Name)
|
||||
assert.Equal(t, "Update client.go 🎉", build.Title)
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
|
|
|
@ -15,30 +15,30 @@
|
|||
package gitlab
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
|
||||
"github.com/woodpecker-ci/woodpecker/server/remote/gitlab/client"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
const (
|
||||
gravatarBase = "https://www.gravatar.com/avatar"
|
||||
)
|
||||
|
||||
// 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.
|
||||
func NewClient(url, accessToken string, skipVerify bool) *client.Client {
|
||||
client := client.New(url, "/api/v4", accessToken, skipVerify)
|
||||
return client
|
||||
func newClient(url, accessToken string, skipVerify bool) (*gitlab.Client, error) {
|
||||
return gitlab.NewOAuthClient(accessToken, gitlab.WithBaseURL(url), gitlab.WithHTTPClient(&http.Client{
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: skipVerify},
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
// 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.
|
||||
func IsRead(proj *client.Project) bool {
|
||||
func isRead(proj *gitlab.Project) bool {
|
||||
var user = proj.Permissions.ProjectAccess
|
||||
var group = proj.Permissions.GroupAccess
|
||||
|
||||
|
@ -54,9 +54,9 @@ func IsRead(proj *client.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.
|
||||
func IsWrite(proj *client.Project) bool {
|
||||
func isWrite(proj *gitlab.Project) bool {
|
||||
var user = proj.Permissions.ProjectAccess
|
||||
var group = proj.Permissions.GroupAccess
|
||||
|
||||
|
@ -70,9 +70,9 @@ func IsWrite(proj *client.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.
|
||||
func IsAdmin(proj *client.Project) bool {
|
||||
func isAdmin(proj *gitlab.Project) bool {
|
||||
var user = proj.Permissions.ProjectAccess
|
||||
var group = proj.Permissions.GroupAccess
|
||||
|
||||
|
@ -85,55 +85,3 @@ func IsAdmin(proj *client.Project) bool {
|
|||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// GetKeyTitle is a helper function that generates a title for the
|
||||
// RSA public key based on the username and domain name.
|
||||
func GetKeyTitle(rawurl string) (string, error) {
|
||||
var uri, err = url.Parse(rawurl)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("drone@%s", uri.Host), nil
|
||||
}
|
||||
|
||||
func ns(owner, name string) string {
|
||||
return fmt.Sprintf("%s%%2F%s", owner, name)
|
||||
}
|
||||
|
||||
func GetUserAvatar(email string) string {
|
||||
hasher := md5.New()
|
||||
hasher.Write([]byte(email))
|
||||
|
||||
return fmt.Sprintf(
|
||||
"%s/%v.jpg?s=%s",
|
||||
gravatarBase,
|
||||
hex.EncodeToString(hasher.Sum(nil)),
|
||||
"128",
|
||||
)
|
||||
}
|
||||
|
||||
func ExtractFromPath(str string) (string, string, error) {
|
||||
s := strings.Split(str, "/")
|
||||
if len(s) < 2 {
|
||||
return "", "", fmt.Errorf("Minimum match not found")
|
||||
}
|
||||
return s[0], s[1], nil
|
||||
}
|
||||
|
||||
func GetUserEmail(c *client.Client, defaultURL string) (*client.Client, error) {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func GetProjectId(r *Gitlab, c *client.Client, owner, name string) (projectId string, err error) {
|
||||
if r.Search {
|
||||
_projectId, err := c.SearchProjectId(owner, name)
|
||||
if err != nil || _projectId == 0 {
|
||||
return "", err
|
||||
}
|
||||
projectId := strconv.Itoa(_projectId)
|
||||
return projectId, nil
|
||||
} else {
|
||||
projectId := ns(owner, name)
|
||||
return projectId, nil
|
||||
}
|
||||
}
|
||||
|
|
72
server/remote/gitlab/status.go
Normal file
72
server/remote/gitlab/status.go
Normal file
|
@ -0,0 +1,72 @@
|
|||
// Copyright 2021 Woodpecker Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"github.com/woodpecker-ci/woodpecker/server/model"
|
||||
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
const (
|
||||
DescPending = "the build is pending"
|
||||
DescRunning = "the buils is running"
|
||||
DescSuccess = "the build was successful"
|
||||
DescFailure = "the build failed"
|
||||
DescCanceled = "the build canceled"
|
||||
DescBlocked = "the build is pending approval"
|
||||
DescDeclined = "the build was rejected"
|
||||
)
|
||||
|
||||
// getStatus is a helper that converts a Woodpecker status to a Gitlab status.
|
||||
func getStatus(status string) gitlab.BuildStateValue {
|
||||
switch status {
|
||||
case model.StatusPending, model.StatusBlocked:
|
||||
return gitlab.Pending
|
||||
case model.StatusRunning:
|
||||
return gitlab.Running
|
||||
case model.StatusSuccess:
|
||||
return gitlab.Success
|
||||
case model.StatusFailure, model.StatusError:
|
||||
return gitlab.Failed
|
||||
case model.StatusKilled:
|
||||
return gitlab.Canceled
|
||||
default:
|
||||
return gitlab.Failed
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
case model.StatusBlocked:
|
||||
return DescBlocked
|
||||
case model.StatusDeclined:
|
||||
return DescDeclined
|
||||
default:
|
||||
return DescFailure
|
||||
}
|
||||
}
|
567
server/remote/gitlab/testdata/hooks.go
vendored
567
server/remote/gitlab/testdata/hooks.go
vendored
|
@ -1,4 +1,4 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
// Copyright 2021 Woodpecker Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
|
@ -14,335 +14,292 @@
|
|||
|
||||
package testdata
|
||||
|
||||
var TagHook = []byte(`
|
||||
{
|
||||
"object_kind": "tag_push",
|
||||
"ref": "refs/tags/v1.0.0",
|
||||
"before": "0000000000000000000000000000000000000000",
|
||||
"after": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7",
|
||||
"user_id": 1,
|
||||
"user_name": "John Smith",
|
||||
"user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s=80",
|
||||
"project_id": 1,
|
||||
"project":{
|
||||
"name":"Example",
|
||||
"description":"",
|
||||
"web_url":"http://example.com/jsmith/example",
|
||||
"avatar_url":"http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg",
|
||||
"git_ssh_url":"git@example.com:jsmith/example.git",
|
||||
"git_http_url":"http://example.com/jsmith/example.git",
|
||||
"namespace":"Jsmith",
|
||||
"visibility_level":0,
|
||||
"path_with_namespace":"jsmith/example",
|
||||
"default_branch":"develop",
|
||||
"homepage":"http://example.com/jsmith/example",
|
||||
"url":"git@example.com:jsmith/example.git",
|
||||
"ssh_url":"git@example.com:jsmith/example.git",
|
||||
"http_url":"http://example.com/jsmith/example.git"
|
||||
},
|
||||
"repository":{
|
||||
"name": "jsmith",
|
||||
"url": "ssh://git@example.com/jsmith/example.git",
|
||||
"description": "",
|
||||
"homepage": "http://example.com/jsmith/example",
|
||||
"git_http_url":"http://example.com/jsmith/example.git",
|
||||
"git_ssh_url":"git@example.com:jsmith/example.git",
|
||||
"visibility_level":0
|
||||
},
|
||||
"commits": [],
|
||||
"total_commits_count": 0
|
||||
}
|
||||
`)
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
var LegacyTagHook = []byte(`
|
||||
{
|
||||
"object_kind": "tag_push",
|
||||
"ref": "refs/tags/v1.0.0",
|
||||
"before": "0000000000000000000000000000000000000000",
|
||||
"after": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7",
|
||||
"user_id": 1,
|
||||
"user_name": "John Smith",
|
||||
"project_id": 1,
|
||||
"repository": {
|
||||
"name": "jsmith",
|
||||
"url": "ssh://git@example.com/jsmith/example.git",
|
||||
var (
|
||||
ServiceHookMethod = http.MethodPost
|
||||
ServiceHookURL, _ = url.Parse(
|
||||
"http://10.40.8.5:8000/hook?owner=test&name=woodpecker&access_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9." +
|
||||
"eyJ0ZXh0IjoidGVzdC93b29kcGVja2VyIiwidHlwZSI6Imhvb2sifQ.x3kPnmZtxZQ_9_eMhfQ1HSmj_SLhdT_Lu2hMczWjKh0")
|
||||
ServiceHookHeaders = http.Header{
|
||||
"Content-Type": []string{"application/json"},
|
||||
"User-Agent": []string{"GitLab/14.3.0"},
|
||||
"X-Gitlab-Event": []string{"Service Hook"},
|
||||
}
|
||||
)
|
||||
|
||||
// ServiceHookPushBody is payload of ServiceHook: Push
|
||||
var ServiceHookPushBody = []byte(`{
|
||||
"object_kind": "push",
|
||||
"event_name": "push",
|
||||
"before": "ffe8eb4f91d1fe6bc49f1e610e50e4b5767f0104",
|
||||
"after": "16862e368d8ab812e48833b741dad720d6e2cb7f",
|
||||
"ref": "refs/heads/master",
|
||||
"checkout_sha": "16862e368d8ab812e48833b741dad720d6e2cb7f",
|
||||
"message": null,
|
||||
"user_id": 2,
|
||||
"user_name": "te st",
|
||||
"user_username": "test",
|
||||
"user_email": "",
|
||||
"user_avatar": "https://www.gravatar.com/avatar/dd46a756faad4727fb679320751f6dea?s=80&d=identicon",
|
||||
"project_id": 2,
|
||||
"project": {
|
||||
"id": 2,
|
||||
"name": "Woodpecker",
|
||||
"description": "",
|
||||
"homepage": "http://example.com/jsmith/example",
|
||||
"git_http_url":"http://example.com/jsmith/example.git",
|
||||
"git_ssh_url":"git@example.com:jsmith/example.git",
|
||||
"visibility_level":0
|
||||
"web_url": "http://10.40.8.5:3200/test/woodpecker",
|
||||
"avatar_url": "http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg",
|
||||
"git_ssh_url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"git_http_url": "http://10.40.8.5:3200/test/woodpecker.git",
|
||||
"namespace": "te st",
|
||||
"visibility_level": 20,
|
||||
"path_with_namespace": "test/woodpecker",
|
||||
"default_branch": "develop",
|
||||
"ci_config_path": null,
|
||||
"homepage": "http://10.40.8.5:3200/test/woodpecker",
|
||||
"url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"ssh_url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"http_url": "http://10.40.8.5:3200/test/woodpecker.git"
|
||||
},
|
||||
"commits": [
|
||||
{
|
||||
"id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
|
||||
"message": "Update Catalan translation to e38cb41.",
|
||||
"timestamp": "2011-12-12T14:27:31+02:00",
|
||||
"url": "http://example.com/mike/diaspora/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
|
||||
"id": "16862e368d8ab812e48833b741dad720d6e2cb7f",
|
||||
"message": "Update main.go",
|
||||
"title": "Update main.go",
|
||||
"timestamp": "2021-09-27T04:46:14+00:00",
|
||||
"url": "http://10.40.8.5:3200/test/woodpecker/-/commit/16862e368d8ab812e48833b741dad720d6e2cb7f",
|
||||
"author": {
|
||||
"name": "Jordi Mallach",
|
||||
"email": "jordi@softcatala.org"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"message": "fixed readme",
|
||||
"timestamp": "2012-01-03T23:36:29+02:00",
|
||||
"url": "http://example.com/mike/diaspora/commit/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"author": {
|
||||
"name": "GitLab dev user",
|
||||
"email": "gitlabdev@dv6700.(none)"
|
||||
}
|
||||
"name": "te st",
|
||||
"email": "test@test.test"
|
||||
},
|
||||
"added": [
|
||||
|
||||
],
|
||||
"modified": [
|
||||
"cmd/cli/main.go"
|
||||
],
|
||||
"removed": [
|
||||
|
||||
]
|
||||
}
|
||||
],
|
||||
"total_commits_count": 4
|
||||
}
|
||||
`)
|
||||
"total_commits_count": 1,
|
||||
"push_options": {
|
||||
},
|
||||
"repository": {
|
||||
"name": "Woodpecker",
|
||||
"url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"description": "",
|
||||
"homepage": "http://10.40.8.5:3200/test/woodpecker",
|
||||
"git_http_url": "http://10.40.8.5:3200/test/woodpecker.git",
|
||||
"git_ssh_url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"visibility_level": 20
|
||||
}
|
||||
}`)
|
||||
|
||||
var MergeRequestHook = []byte(`
|
||||
{
|
||||
// ServiceHookTagPushBody is payload of ServiceHook: TagPush
|
||||
var ServiceHookTagPushBody = []byte(`{
|
||||
"object_kind": "tag_push",
|
||||
"event_name": "tag_push",
|
||||
"before": "0000000000000000000000000000000000000000",
|
||||
"after": "fabed3d94cd03e6c2b7958afa9569c18a24d301f",
|
||||
"ref": "refs/tags/v22",
|
||||
"checkout_sha": "16862e368d8ab812e48833b741dad720d6e2cb7f",
|
||||
"message": "hi",
|
||||
"user_id": 2,
|
||||
"user_name": "te st",
|
||||
"user_username": "test",
|
||||
"user_email": "",
|
||||
"user_avatar": "https://www.gravatar.com/avatar/dd46a756faad4727fb679320751f6dea?s=80&d=identicon",
|
||||
"project_id": 2,
|
||||
"project": {
|
||||
"id": 2,
|
||||
"name": "Woodpecker",
|
||||
"description": "",
|
||||
"web_url": "http://10.40.8.5:3200/test/woodpecker",
|
||||
"avatar_url": "http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg",
|
||||
"git_ssh_url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"git_http_url": "http://10.40.8.5:3200/test/woodpecker.git",
|
||||
"namespace": "te st",
|
||||
"visibility_level": 20,
|
||||
"path_with_namespace": "test/woodpecker",
|
||||
"default_branch": "develop",
|
||||
"ci_config_path": null,
|
||||
"homepage": "http://10.40.8.5:3200/test/woodpecker",
|
||||
"url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"ssh_url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"http_url": "http://10.40.8.5:3200/test/woodpecker.git"
|
||||
},
|
||||
"commits": [
|
||||
{
|
||||
"id": "16862e368d8ab812e48833b741dad720d6e2cb7f",
|
||||
"message": "Update main.go",
|
||||
"title": "Update main.go",
|
||||
"timestamp": "2021-09-27T04:46:14+00:00",
|
||||
"url": "http://10.40.8.5:3200/test/woodpecker/-/commit/16862e368d8ab812e48833b741dad720d6e2cb7f",
|
||||
"author": {
|
||||
"name": "te st",
|
||||
"email": "test@test.test"
|
||||
},
|
||||
"added": [
|
||||
|
||||
],
|
||||
"modified": [
|
||||
"cmd/cli/main.go"
|
||||
],
|
||||
"removed": [
|
||||
|
||||
]
|
||||
}
|
||||
],
|
||||
"total_commits_count": 1,
|
||||
"push_options": {
|
||||
},
|
||||
"repository": {
|
||||
"name": "Woodpecker",
|
||||
"url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"description": "",
|
||||
"homepage": "http://10.40.8.5:3200/test/woodpecker",
|
||||
"git_http_url": "http://10.40.8.5:3200/test/woodpecker.git",
|
||||
"git_ssh_url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"visibility_level": 20
|
||||
}
|
||||
}`)
|
||||
|
||||
// ServiceHookMergeRequestBody is payload of ServiceHook: MergeRequest
|
||||
var ServiceHookMergeRequestBody = []byte(`{
|
||||
"object_kind": "merge_request",
|
||||
"event_type": "merge_request",
|
||||
"user": {
|
||||
"name": "Administrator",
|
||||
"username": "root",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
|
||||
"id": 2,
|
||||
"name": "te st",
|
||||
"username": "test",
|
||||
"avatar_url": "https://www.gravatar.com/avatar/dd46a756faad4727fb679320751f6dea?s=80&d=identicon",
|
||||
"email": "test@test.test"
|
||||
},
|
||||
"project": {
|
||||
"id": 2,
|
||||
"name": "Woodpecker",
|
||||
"description": "",
|
||||
"web_url": "http://10.40.8.5:3200/test/woodpecker",
|
||||
"avatar_url": null,
|
||||
"git_ssh_url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"git_http_url": "http://10.40.8.5:3200/test/woodpecker.git",
|
||||
"namespace": "te st",
|
||||
"visibility_level": 20,
|
||||
"path_with_namespace": "test/woodpecker",
|
||||
"default_branch": "master",
|
||||
"ci_config_path": null,
|
||||
"homepage": "http://10.40.8.5:3200/test/woodpecker",
|
||||
"url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"ssh_url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"http_url": "http://10.40.8.5:3200/test/woodpecker.git"
|
||||
},
|
||||
"object_attributes": {
|
||||
"id": 99,
|
||||
"target_branch": "master",
|
||||
"source_branch": "ms-viewport",
|
||||
"source_project_id": 14,
|
||||
"author_id": 51,
|
||||
"assignee_id": 6,
|
||||
"title": "MS-Viewport",
|
||||
"created_at": "2013-12-03T17:23:34Z",
|
||||
"updated_at": "2013-12-03T17:23:34Z",
|
||||
"st_commits": null,
|
||||
"st_diffs": null,
|
||||
"milestone_id": null,
|
||||
"state": "opened",
|
||||
"merge_status": "unchecked",
|
||||
"target_project_id": 14,
|
||||
"iid": 1,
|
||||
"assignee_id": null,
|
||||
"author_id": 2,
|
||||
"created_at": "2021-09-27 05:00:01 UTC",
|
||||
"description": "",
|
||||
"source":{
|
||||
"name":"Awesome Project",
|
||||
"description":"Aut reprehenderit ut est.",
|
||||
"web_url":"http://example.com/awesome_space/awesome_project",
|
||||
"avatar_url":"http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg",
|
||||
"git_ssh_url":"git@example.com:awesome_space/awesome_project.git",
|
||||
"git_http_url":"http://example.com/awesome_space/awesome_project.git",
|
||||
"namespace":"Awesome Space",
|
||||
"visibility_level":20,
|
||||
"path_with_namespace":"awesome_space/awesome_project",
|
||||
"default_branch":"master",
|
||||
"homepage":"http://example.com/awesome_space/awesome_project",
|
||||
"url":"http://example.com/awesome_space/awesome_project.git",
|
||||
"ssh_url":"git@example.com:awesome_space/awesome_project.git",
|
||||
"http_url":"http://example.com/awesome_space/awesome_project.git"
|
||||
"head_pipeline_id": 5,
|
||||
"id": 2,
|
||||
"iid": 2,
|
||||
"last_edited_at": null,
|
||||
"last_edited_by_id": null,
|
||||
"merge_commit_sha": null,
|
||||
"merge_error": null,
|
||||
"merge_params": {
|
||||
"force_remove_source_branch": "1"
|
||||
},
|
||||
"merge_status": "unchecked",
|
||||
"merge_user_id": null,
|
||||
"merge_when_pipeline_succeeds": false,
|
||||
"milestone_id": null,
|
||||
"source_branch": "masterfdsafds",
|
||||
"source_project_id": 2,
|
||||
"state_id": 1,
|
||||
"target_branch": "master",
|
||||
"target_project_id": 2,
|
||||
"time_estimate": 0,
|
||||
"title": "Update client.go 🎉",
|
||||
"updated_at": "2021-09-27 05:01:21 UTC",
|
||||
"updated_by_id": null,
|
||||
"url": "http://10.40.8.5:3200/test/woodpecker/-/merge_requests/2",
|
||||
"source": {
|
||||
"id": 2,
|
||||
"name": "Woodpecker",
|
||||
"description": "",
|
||||
"web_url": "http://10.40.8.5:3200/test/woodpecker",
|
||||
"avatar_url": "http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg",
|
||||
"git_ssh_url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"git_http_url": "http://10.40.8.5:3200/test/woodpecker.git",
|
||||
"namespace": "te st",
|
||||
"visibility_level": 20,
|
||||
"path_with_namespace": "test/woodpecker",
|
||||
"default_branch": "develop",
|
||||
"ci_config_path": null,
|
||||
"homepage": "http://10.40.8.5:3200/test/woodpecker",
|
||||
"url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"ssh_url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"http_url": "http://10.40.8.5:3200/test/woodpecker.git"
|
||||
},
|
||||
"target": {
|
||||
"name":"Awesome Project",
|
||||
"description":"Aut reprehenderit ut est.",
|
||||
"web_url":"http://example.com/awesome_space/awesome_project",
|
||||
"avatar_url":"http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg",
|
||||
"git_ssh_url":"git@example.com:awesome_space/awesome_project.git",
|
||||
"git_http_url":"http://example.com/awesome_space/awesome_project.git",
|
||||
"namespace":"Awesome Space",
|
||||
"visibility_level":20,
|
||||
"path_with_namespace":"awesome_space/awesome_project",
|
||||
"default_branch":"develop",
|
||||
"homepage":"http://example.com/awesome_space/awesome_project",
|
||||
"url":"http://example.com/awesome_space/awesome_project.git",
|
||||
"ssh_url":"git@example.com:awesome_space/awesome_project.git",
|
||||
"http_url":"http://example.com/awesome_space/awesome_project.git"
|
||||
"id": 2,
|
||||
"name": "Woodpecker",
|
||||
"description": "",
|
||||
"web_url": "http://10.40.8.5:3200/test/woodpecker",
|
||||
"avatar_url": "http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg",
|
||||
"git_ssh_url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"git_http_url": "http://10.40.8.5:3200/test/woodpecker.git",
|
||||
"namespace": "te st",
|
||||
"visibility_level": 20,
|
||||
"path_with_namespace": "test/woodpecker",
|
||||
"default_branch": "develop",
|
||||
"ci_config_path": null,
|
||||
"homepage": "http://10.40.8.5:3200/test/woodpecker",
|
||||
"url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"ssh_url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"http_url": "http://10.40.8.5:3200/test/woodpecker.git"
|
||||
},
|
||||
"last_commit": {
|
||||
"id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"message": "fixed readme",
|
||||
"timestamp": "2012-01-03T23:36:29+02:00",
|
||||
"url": "http://example.com/awesome_space/awesome_project/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"id": "0ab96a10266b95b4b533dcfd98738015fbe70889",
|
||||
"message": "Update state.go",
|
||||
"title": "Update state.go",
|
||||
"timestamp": "2021-09-27T05:01:20+00:00",
|
||||
"url": "http://10.40.8.5:3200/test/woodpecker/-/commit/0ab96a10266b95b4b533dcfd98738015fbe70889",
|
||||
"author": {
|
||||
"name": "GitLab dev user",
|
||||
"email": "gitlabdev@dv6700.(none)"
|
||||
"name": "te st",
|
||||
"email": "test@test.test"
|
||||
}
|
||||
},
|
||||
"work_in_progress": false,
|
||||
"url": "http://example.com/diaspora/merge_requests/1",
|
||||
"action": "open",
|
||||
"assignee": {
|
||||
"name": "User1",
|
||||
"username": "user1",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
"total_time_spent": 0,
|
||||
"time_change": 0,
|
||||
"human_total_time_spent": null,
|
||||
"human_time_change": null,
|
||||
"human_time_estimate": null,
|
||||
"assignee_ids": [
|
||||
|
||||
var LegacyMergeRequestHook = []byte(`
|
||||
{
|
||||
"object_kind": "merge_request",
|
||||
"user": {
|
||||
"name": "Administrator",
|
||||
"username": "root",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
|
||||
},
|
||||
"object_attributes": {
|
||||
"id": 99,
|
||||
"target_branch": "master",
|
||||
"source_branch": "ms-viewport",
|
||||
"source_project_id": 14,
|
||||
"author_id": 51,
|
||||
"assignee_id": 6,
|
||||
"title": "MS-Viewport",
|
||||
"created_at": "2013-12-03T17:23:34Z",
|
||||
"updated_at": "2013-12-03T17:23:34Z",
|
||||
"st_commits": null,
|
||||
"st_diffs": null,
|
||||
"milestone_id": null,
|
||||
],
|
||||
"state": "opened",
|
||||
"merge_status": "unchecked",
|
||||
"target_project_id": 14,
|
||||
"iid": 1,
|
||||
"description": "",
|
||||
"source": {
|
||||
"name": "awesome_project",
|
||||
"ssh_url": "ssh://git@example.com/awesome_space/awesome_project.git",
|
||||
"http_url": "http://example.com/awesome_space/awesome_project.git",
|
||||
"visibility_level": 20,
|
||||
"namespace": "awesome_space"
|
||||
},
|
||||
"target": {
|
||||
"name": "awesome_project",
|
||||
"ssh_url": "ssh://git@example.com/awesome_space/awesome_project.git",
|
||||
"http_url": "http://example.com/awesome_space/awesome_project.git",
|
||||
"visibility_level": 20,
|
||||
"namespace": "awesome_space"
|
||||
},
|
||||
"last_commit": {
|
||||
"id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"message": "fixed readme",
|
||||
"timestamp": "2012-01-03T23:36:29+02:00",
|
||||
"url": "http://example.com/awesome_space/awesome_project/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"author": {
|
||||
"name": "GitLab dev user",
|
||||
"email": "gitlabdev@dv6700.(none)"
|
||||
}
|
||||
},
|
||||
"url": "http://example.com/diaspora/merge_requests/1",
|
||||
"action": "open"
|
||||
}
|
||||
}
|
||||
`)
|
||||
"action": "update",
|
||||
"oldrev": "6ef047571374c96a2bf13c361efd1fb008b0063e"
|
||||
},
|
||||
"labels": [
|
||||
|
||||
var PushHook = []byte(`
|
||||
{
|
||||
"object_kind": "push",
|
||||
"before": "95790bf891e76fee5e1747ab589903a6a1f80f22",
|
||||
"after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"ref": "refs/heads/master",
|
||||
"user_id": 4,
|
||||
"user_name": "John Smith",
|
||||
"user_email": "john@example.com",
|
||||
"user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80",
|
||||
"project_id": 15,
|
||||
"project":{
|
||||
"name":"Diaspora",
|
||||
"description":"",
|
||||
"web_url":"http://example.com/mike/diaspora",
|
||||
"avatar_url":"http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg",
|
||||
"git_ssh_url":"git@example.com:mike/diaspora.git",
|
||||
"git_http_url":"http://example.com/mike/diaspora.git",
|
||||
"namespace":"Mike",
|
||||
"visibility_level":0,
|
||||
"path_with_namespace":"mike/diaspora",
|
||||
"default_branch":"develop",
|
||||
"homepage":"http://example.com/mike/diaspora",
|
||||
"url":"git@example.com:mike/diasporadiaspora.git",
|
||||
"ssh_url":"git@example.com:mike/diaspora.git",
|
||||
"http_url":"http://example.com/mike/diaspora.git"
|
||||
},
|
||||
"repository":{
|
||||
"name": "Diaspora",
|
||||
"url": "git@example.com:mike/diasporadiaspora.git",
|
||||
"description": "",
|
||||
"homepage": "http://example.com/mike/diaspora",
|
||||
"git_http_url":"http://example.com/mike/diaspora.git",
|
||||
"git_ssh_url":"git@example.com:mike/diaspora.git",
|
||||
"visibility_level":0
|
||||
},
|
||||
"commits": [
|
||||
{
|
||||
"id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
|
||||
"message": "Update Catalan translation to e38cb41.",
|
||||
"timestamp": "2011-12-12T14:27:31+02:00",
|
||||
"url": "http://example.com/mike/diaspora/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
|
||||
"author": {
|
||||
"name": "Jordi Mallach",
|
||||
"email": "jordi@softcatala.org"
|
||||
},
|
||||
"added": ["CHANGELOG"],
|
||||
"modified": ["app/controller/application.rb"],
|
||||
"removed": []
|
||||
},
|
||||
{
|
||||
"id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"message": "fixed readme",
|
||||
"timestamp": "2012-01-03T23:36:29+02:00",
|
||||
"url": "http://example.com/mike/diaspora/commit/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"author": {
|
||||
"name": "GitLab dev user",
|
||||
"email": "gitlabdev@dv6700.(none)"
|
||||
},
|
||||
"added": ["CHANGELOG"],
|
||||
"modified": ["app/controller/application.rb"],
|
||||
"removed": []
|
||||
}
|
||||
],
|
||||
"total_commits_count": 4
|
||||
}
|
||||
`)
|
||||
|
||||
var LegacyPushHook = []byte(`
|
||||
{
|
||||
"object_kind": "push",
|
||||
"before": "95790bf891e76fee5e1747ab589903a6a1f80f22",
|
||||
"after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"ref": "refs/heads/master",
|
||||
"user_id": 4,
|
||||
"user_name": "John Smith",
|
||||
"user_email": "john@example.com",
|
||||
"project_id": 15,
|
||||
"changes": {
|
||||
"updated_at": {
|
||||
"previous": "2021-09-27 05:00:01 UTC",
|
||||
"current": "2021-09-27 05:01:21 UTC"
|
||||
}
|
||||
},
|
||||
"repository": {
|
||||
"name": "Diaspora",
|
||||
"url": "git@example.com:mike/diasporadiaspora.git",
|
||||
"name": "Woodpecker",
|
||||
"url": "git@10.40.8.5:test/woodpecker.git",
|
||||
"description": "",
|
||||
"homepage": "http://example.com/mike/diaspora",
|
||||
"git_http_url":"http://example.com/mike/diaspora.git",
|
||||
"git_ssh_url":"git@example.com:mike/diaspora.git",
|
||||
"visibility_level":0
|
||||
},
|
||||
"commits": [
|
||||
{
|
||||
"id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
|
||||
"message": "Update Catalan translation to e38cb41.",
|
||||
"timestamp": "2011-12-12T14:27:31+02:00",
|
||||
"url": "http://example.com/mike/diaspora/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
|
||||
"author": {
|
||||
"name": "Jordi Mallach",
|
||||
"email": "jordi@softcatala.org"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"message": "fixed readme",
|
||||
"timestamp": "2012-01-03T23:36:29+02:00",
|
||||
"url": "http://example.com/mike/diaspora/commit/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"author": {
|
||||
"name": "GitLab dev user",
|
||||
"email": "gitlabdev@dv6700.(none)"
|
||||
}
|
||||
}
|
||||
],
|
||||
"total_commits_count": 4
|
||||
}
|
||||
`)
|
||||
"homepage": "http://10.40.8.5:3200/test/woodpecker"
|
||||
}
|
||||
}`)
|
||||
|
|
30
server/remote/gitlab/testdata/projects.go
vendored
30
server/remote/gitlab/testdata/projects.go
vendored
|
@ -30,7 +30,7 @@ var allProjectsPayload = []byte(`
|
|||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"username": "some_user",
|
||||
"created_at": "2013-09-30T13: 46: 02Z"
|
||||
"created_at": "2013-09-30T13:46:02Z"
|
||||
},
|
||||
"name": "Diaspora Client",
|
||||
"name_with_namespace": "Diaspora / Diaspora Client",
|
||||
|
@ -40,16 +40,16 @@ var allProjectsPayload = []byte(`
|
|||
"merge_requests_enabled": true,
|
||||
"wiki_enabled": true,
|
||||
"snippets_enabled": false,
|
||||
"created_at": "2013-09-30T13: 46: 02Z",
|
||||
"last_activity_at": "2013-09-30T13: 46: 02Z",
|
||||
"created_at": "2013-09-30T13:46:02Z",
|
||||
"last_activity_at": "2013-09-30T13:46:02Z",
|
||||
"namespace": {
|
||||
"created_at": "2013-09-30T13: 46: 02Z",
|
||||
"created_at": "2013-09-30T13:46:02Z",
|
||||
"description": "",
|
||||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"owner_id": 1,
|
||||
"path": "diaspora",
|
||||
"updated_at": "2013-09-30T13: 46: 02Z"
|
||||
"updated_at": "2013-09-30T13:46:02Z"
|
||||
},
|
||||
"archived": false
|
||||
},
|
||||
|
@ -107,7 +107,7 @@ var notArchivedProjectsPayload = []byte(`
|
|||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"username": "some_user",
|
||||
"created_at": "2013-09-30T13: 46: 02Z"
|
||||
"created_at": "2013-09-30T13:46:02Z"
|
||||
},
|
||||
"name": "Diaspora Client",
|
||||
"name_with_namespace": "Diaspora / Diaspora Client",
|
||||
|
@ -117,16 +117,16 @@ var notArchivedProjectsPayload = []byte(`
|
|||
"merge_requests_enabled": true,
|
||||
"wiki_enabled": true,
|
||||
"snippets_enabled": false,
|
||||
"created_at": "2013-09-30T13: 46: 02Z",
|
||||
"last_activity_at": "2013-09-30T13: 46: 02Z",
|
||||
"created_at": "2013-09-30T13:46:02Z",
|
||||
"last_activity_at": "2013-09-30T13:46:02Z",
|
||||
"namespace": {
|
||||
"created_at": "2013-09-30T13: 46: 02Z",
|
||||
"created_at": "2013-09-30T13:46:02Z",
|
||||
"description": "",
|
||||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"owner_id": 1,
|
||||
"path": "diaspora",
|
||||
"updated_at": "2013-09-30T13: 46: 02Z"
|
||||
"updated_at": "2013-09-30T13:46:02Z"
|
||||
},
|
||||
"archived": false
|
||||
}
|
||||
|
@ -147,7 +147,7 @@ var project4Paylod = []byte(`
|
|||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"username": "some_user",
|
||||
"created_at": "2013-09-30T13: 46: 02Z"
|
||||
"created_at": "2013-09-30T13:46:02Z"
|
||||
},
|
||||
"name": "Diaspora Client",
|
||||
"name_with_namespace": "Diaspora / Diaspora Client",
|
||||
|
@ -157,16 +157,16 @@ var project4Paylod = []byte(`
|
|||
"merge_requests_enabled": true,
|
||||
"wiki_enabled": true,
|
||||
"snippets_enabled": false,
|
||||
"created_at": "2013-09-30T13: 46: 02Z",
|
||||
"last_activity_at": "2013-09-30T13: 46: 02Z",
|
||||
"created_at": "2013-09-30T13:46:02Z",
|
||||
"last_activity_at": "2013-09-30T13:46:02Z",
|
||||
"namespace": {
|
||||
"created_at": "2013-09-30T13: 46: 02Z",
|
||||
"created_at": "2013-09-30T13:46:02Z",
|
||||
"description": "",
|
||||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"owner_id": 1,
|
||||
"path": "diaspora",
|
||||
"updated_at": "2013-09-30T13: 46: 02Z"
|
||||
"updated_at": "2013-09-30T13:46:02Z"
|
||||
},
|
||||
"archived": false,
|
||||
"permissions": {
|
||||
|
|
26
server/remote/gitlab/testdata/testdata.go
vendored
26
server/remote/gitlab/testdata/testdata.go
vendored
|
@ -15,22 +15,31 @@
|
|||
package testdata
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// setup a mock server for testing purposes.
|
||||
func NewServer() *httptest.Server {
|
||||
// NewServer setup a mock server for testing purposes.
|
||||
func NewServer(t *testing.T) *httptest.Server {
|
||||
mux := http.NewServeMux()
|
||||
server := httptest.NewServer(mux)
|
||||
|
||||
// handle requests and serve mock data
|
||||
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
//println(r.URL.Path + " " + r.Method)
|
||||
t.Logf("gitlab remote mock server: [%s] %s", r.Method, r.URL.Path)
|
||||
// evaluate the path to serve a dummy data file
|
||||
|
||||
// TODO: find source of "/api/v4/" requests
|
||||
// assert.EqualValues(t, "go-gitlab", r.Header.Get("user-agent"), "on request: "+r.URL.Path)
|
||||
|
||||
switch r.URL.Path {
|
||||
case "/api/v4/projects":
|
||||
if r.URL.Query().Get("archived") == "false" {
|
||||
if r.FormValue("archived") == "false" {
|
||||
w.Write(notArchivedProjectsPayload)
|
||||
} else {
|
||||
w.Write(allProjectsPayload)
|
||||
|
@ -43,10 +52,15 @@ func NewServer() *httptest.Server {
|
|||
case "/api/v4/projects/brightbox/puppet":
|
||||
w.Write(project6Paylod)
|
||||
return
|
||||
case "/api/v4/projects/diaspora/diaspora-client/services/drone-ci":
|
||||
case "/api/v4/projects/4/services/drone-ci":
|
||||
switch r.Method {
|
||||
case "PUT":
|
||||
if r.FormValue("token") == "" {
|
||||
body, _ := io.ReadAll(r.Body)
|
||||
opts := make(map[string]interface{})
|
||||
assert.NoError(t, json.Unmarshal(body, &opts))
|
||||
token, ok := opts["token"].(string)
|
||||
assert.True(t, ok)
|
||||
if token == "" {
|
||||
w.WriteHeader(404)
|
||||
} else {
|
||||
w.WriteHeader(201)
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
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
|
||||
}
|
|
@ -1,110 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
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
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
groupsUrl = "/groups"
|
||||
)
|
||||
|
||||
// Get a list of all projects owned by the authenticated user.
|
||||
func (g *Client) AllGroups() ([]*Namespace, error) {
|
||||
var perPage = 100
|
||||
var groups []*Namespace
|
||||
|
||||
for i := 1; true; i++ {
|
||||
contents, err := g.Groups(i, perPage)
|
||||
if err != nil {
|
||||
return groups, err
|
||||
}
|
||||
|
||||
for _, value := range contents {
|
||||
groups = append(groups, value)
|
||||
}
|
||||
|
||||
if len(groups) == 0 {
|
||||
break
|
||||
}
|
||||
|
||||
if len(groups)/i < perPage {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return groups, nil
|
||||
}
|
||||
|
||||
func (g *Client) Groups(page, perPage int) ([]*Namespace, error) {
|
||||
url, opaque := g.ResourceUrl(groupsUrl, nil, QMap{
|
||||
"page": strconv.Itoa(page),
|
||||
"per_page": strconv.Itoa(perPage),
|
||||
})
|
||||
|
||||
var groups []*Namespace
|
||||
|
||||
contents, err := g.Do("GET", url, opaque, nil)
|
||||
if err == nil {
|
||||
err = json.Unmarshal(contents, &groups)
|
||||
}
|
||||
|
||||
return groups, err
|
||||
}
|
|
@ -1,55 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
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
|
||||
}
|
|
@ -1,175 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
searchUrl = "/projects/search/:query"
|
||||
projectsUrl = "/projects"
|
||||
projectUrl = "/projects/:id"
|
||||
repoUrlRawFile = "/projects/:id/repository/blobs/:sha"
|
||||
repoUrlRawFileRef = "/projects/:id/repository/files"
|
||||
commitStatusUrl = "/projects/:id/statuses/:sha"
|
||||
)
|
||||
|
||||
// Get a list of all projects owned by the authenticated user.
|
||||
func (g *Client) AllProjects(hide_archives bool) ([]*Project, error) {
|
||||
var per_page = 100
|
||||
var projects []*Project
|
||||
|
||||
for i := 1; true; i++ {
|
||||
contents, err := g.Projects(i, per_page, hide_archives)
|
||||
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, hide_archives bool) ([]*Project, error) {
|
||||
projectsOptions := QMap{
|
||||
"page": strconv.Itoa(page),
|
||||
"per_page": strconv.Itoa(per_page),
|
||||
}
|
||||
|
||||
if hide_archives {
|
||||
projectsOptions["archived"] = "false"
|
||||
}
|
||||
|
||||
url, opaque := c.ResourceUrl(projectsUrl, nil, projectsOptions)
|
||||
|
||||
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) RepoRawFileRef(id, ref, filepath string) ([]byte, error) {
|
||||
url, opaque := c.ResourceUrl(
|
||||
repoUrlRawFileRef,
|
||||
QMap{
|
||||
":id": id,
|
||||
},
|
||||
QMap{
|
||||
"filepath": filepath,
|
||||
"ref": ref,
|
||||
},
|
||||
)
|
||||
|
||||
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
|
||||
}
|
|
@ -1,152 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
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"`
|
||||
AvatarUrl string `json:"avatar_url"`
|
||||
Permissions *Permissions `json:"permissions,omitempty"`
|
||||
}
|
||||
|
||||
type Namespace struct {
|
||||
Id int `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Path string `json:"path,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"`
|
||||
GitSshUrl string `json:"git_ssh_url"`
|
||||
GitHttpUrl string `json:"git_http_url"`
|
||||
AvatarUrl string `json:"avatar_url"`
|
||||
VisibilityLevel int `json:"visibility_level"`
|
||||
WebUrl string `json:"web_url"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
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"`
|
||||
Project *hProject `json:"project,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"`
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
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
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package client
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var encodeMap = map[string]string{
|
||||
".": "%252E",
|
||||
}
|
||||
|
||||
func encodeParameter(value string) string {
|
||||
value = url.QueryEscape(value)
|
||||
|
||||
for before, after := range encodeMap {
|
||||
value = strings.Replace(value, before, after, -1)
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
|
@ -1,703 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gitlab3
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/woodpecker-ci/woodpecker/server"
|
||||
"github.com/woodpecker-ci/woodpecker/server/model"
|
||||
"github.com/woodpecker-ci/woodpecker/server/remote"
|
||||
"github.com/woodpecker-ci/woodpecker/shared/oauth2"
|
||||
|
||||
"github.com/woodpecker-ci/woodpecker/server/remote/gitlab3/client"
|
||||
)
|
||||
|
||||
const DefaultScope = "api"
|
||||
|
||||
// Opts defines configuration options.
|
||||
type Opts struct {
|
||||
URL string // Gogs server url.
|
||||
Client string // Oauth2 client id.
|
||||
Secret string // Oauth2 client secret.
|
||||
Username string // Optional machine account username.
|
||||
Password string // Optional machine account password.
|
||||
PrivateMode bool // Gogs is running in private mode.
|
||||
SkipVerify bool // Skip ssl verification.
|
||||
}
|
||||
|
||||
// New returns a Remote implementation that integrates with Gitlab, an open
|
||||
// source Git service. See https://gitlab.com
|
||||
func New(opts Opts) (remote.Remote, error) {
|
||||
u, err := url.Parse(opts.URL)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
host, _, err := net.SplitHostPort(u.Host)
|
||||
if err == nil {
|
||||
u.Host = host
|
||||
}
|
||||
return &Gitlab{
|
||||
URL: opts.URL,
|
||||
Client: opts.Client,
|
||||
Secret: opts.Secret,
|
||||
Machine: u.Host,
|
||||
Username: opts.Username,
|
||||
Password: opts.Password,
|
||||
PrivateMode: opts.PrivateMode,
|
||||
SkipVerify: opts.SkipVerify,
|
||||
}, nil
|
||||
}
|
||||
|
||||
type Gitlab struct {
|
||||
URL string
|
||||
Client string
|
||||
Secret string
|
||||
Machine string
|
||||
Username string
|
||||
Password string
|
||||
PrivateMode bool
|
||||
SkipVerify bool
|
||||
HideArchives bool
|
||||
Search bool
|
||||
}
|
||||
|
||||
func Load(config string) *Gitlab {
|
||||
url_, err := url.Parse(config)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
params := url_.Query()
|
||||
url_.RawQuery = ""
|
||||
|
||||
gitlab := Gitlab{}
|
||||
gitlab.URL = url_.String()
|
||||
gitlab.Client = params.Get("client_id")
|
||||
gitlab.Secret = params.Get("client_secret")
|
||||
// gitlab.AllowedOrgs = params["orgs"]
|
||||
gitlab.SkipVerify, _ = strconv.ParseBool(params.Get("skip_verify"))
|
||||
gitlab.HideArchives, _ = strconv.ParseBool(params.Get("hide_archives"))
|
||||
// gitlab.Open, _ = strconv.ParseBool(params.Get("open"))
|
||||
|
||||
// switch params.Get("clone_mode") {
|
||||
// case "oauth":
|
||||
// gitlab.CloneMode = "oauth"
|
||||
// default:
|
||||
// gitlab.CloneMode = "token"
|
||||
// }
|
||||
|
||||
// this is a temp workaround
|
||||
gitlab.Search, _ = strconv.ParseBool(params.Get("search"))
|
||||
|
||||
return &gitlab
|
||||
}
|
||||
|
||||
// Login authenticates the session and returns the
|
||||
// remote user details.
|
||||
func (g *Gitlab) Login(ctx context.Context, res http.ResponseWriter, req *http.Request) (*model.User, error) {
|
||||
|
||||
var config = &oauth2.Config{
|
||||
ClientId: g.Client,
|
||||
ClientSecret: g.Secret,
|
||||
Scope: DefaultScope,
|
||||
AuthURL: fmt.Sprintf("%s/oauth/authorize", g.URL),
|
||||
TokenURL: fmt.Sprintf("%s/oauth/token", g.URL),
|
||||
RedirectURL: fmt.Sprintf("%s/authorize", server.Config.Server.Host),
|
||||
}
|
||||
|
||||
trans_ := &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: g.SkipVerify},
|
||||
}
|
||||
|
||||
// get the OAuth errors
|
||||
if err := req.FormValue("error"); err != "" {
|
||||
return nil, &remote.AuthError{
|
||||
Err: err,
|
||||
Description: req.FormValue("error_description"),
|
||||
URI: req.FormValue("error_uri"),
|
||||
}
|
||||
}
|
||||
|
||||
// get the OAuth code
|
||||
var code = req.FormValue("code")
|
||||
if len(code) == 0 {
|
||||
http.Redirect(res, req, config.AuthCodeURL("drone"), http.StatusSeeOther)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var trans = &oauth2.Transport{Config: config, Transport: trans_}
|
||||
var token_, err = trans.Exchange(code)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Error exchanging token. %s", err)
|
||||
}
|
||||
|
||||
client := NewClient(g.URL, token_.AccessToken, g.SkipVerify)
|
||||
login, err := client.CurrentUser()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// if len(g.AllowedOrgs) != 0 {
|
||||
// groups, err := client.AllGroups()
|
||||
// if err != nil {
|
||||
// return nil, fmt.Errorf("Could not check org membership. %s", err)
|
||||
// }
|
||||
//
|
||||
// var member bool
|
||||
// for _, group := range groups {
|
||||
// for _, allowedOrg := range g.AllowedOrgs {
|
||||
// if group.Path == allowedOrg {
|
||||
// member = true
|
||||
// break
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if !member {
|
||||
// return nil, false, fmt.Errorf("User does not belong to correct group. Must belong to %v", g.AllowedOrgs)
|
||||
// }
|
||||
// }
|
||||
|
||||
user := &model.User{}
|
||||
user.Login = login.Username
|
||||
user.Email = login.Email
|
||||
user.Token = token_.AccessToken
|
||||
user.Secret = token_.RefreshToken
|
||||
|
||||
if strings.HasPrefix(login.AvatarUrl, "http") {
|
||||
user.Avatar = login.AvatarUrl
|
||||
} else {
|
||||
user.Avatar = g.URL + "/" + login.AvatarUrl
|
||||
}
|
||||
|
||||
return user, nil
|
||||
}
|
||||
|
||||
func (g *Gitlab) Auth(ctx context.Context, token, secret string) (string, error) {
|
||||
client := NewClient(g.URL, token, g.SkipVerify)
|
||||
login, err := client.CurrentUser()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return login.Username, nil
|
||||
}
|
||||
|
||||
func (g *Gitlab) Teams(ctx context.Context, u *model.User) ([]*model.Team, error) {
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
groups, err := client.AllGroups()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var teams []*model.Team
|
||||
for _, group := range groups {
|
||||
teams = append(teams, &model.Team{
|
||||
Login: group.Name,
|
||||
})
|
||||
}
|
||||
return teams, nil
|
||||
}
|
||||
|
||||
// Repo fetches the named repository from the remote system.
|
||||
func (g *Gitlab) Repo(ctx context.Context, u *model.User, owner, name string) (*model.Repo, error) {
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, owner, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
repo_, err := client.Project(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repo := &model.Repo{}
|
||||
repo.Owner = owner
|
||||
repo.Name = name
|
||||
repo.FullName = repo_.PathWithNamespace
|
||||
repo.Link = repo_.Url
|
||||
repo.Clone = repo_.HttpRepoUrl
|
||||
repo.Branch = "master"
|
||||
|
||||
repo.Avatar = repo_.AvatarUrl
|
||||
|
||||
if len(repo.Avatar) != 0 && !strings.HasPrefix(repo.Avatar, "http") {
|
||||
repo.Avatar = fmt.Sprintf("%s/%s", g.URL, repo.Avatar)
|
||||
}
|
||||
|
||||
if repo_.DefaultBranch != "" {
|
||||
repo.Branch = repo_.DefaultBranch
|
||||
}
|
||||
|
||||
if g.PrivateMode {
|
||||
repo.IsPrivate = true
|
||||
} else {
|
||||
repo.IsPrivate = !repo_.Public
|
||||
}
|
||||
|
||||
return repo, err
|
||||
}
|
||||
|
||||
// Repos fetches a list of repos from the remote system.
|
||||
func (g *Gitlab) Repos(ctx context.Context, u *model.User) ([]*model.Repo, error) {
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
|
||||
var repos = []*model.Repo{}
|
||||
|
||||
all, err := client.AllProjects(g.HideArchives)
|
||||
if err != nil {
|
||||
return repos, err
|
||||
}
|
||||
|
||||
for _, repo_ := range all {
|
||||
var parts = strings.Split(repo_.PathWithNamespace, "/")
|
||||
var owner = parts[0]
|
||||
var name = parts[1]
|
||||
|
||||
repo := &model.Repo{}
|
||||
repo.Owner = owner
|
||||
repo.Name = name
|
||||
repo.FullName = repo_.PathWithNamespace
|
||||
repo.Link = repo_.Url
|
||||
repo.Clone = repo_.HttpRepoUrl
|
||||
repo.Branch = "master"
|
||||
|
||||
if repo_.DefaultBranch != "" {
|
||||
repo.Branch = repo_.DefaultBranch
|
||||
}
|
||||
|
||||
if g.PrivateMode {
|
||||
repo.IsPrivate = true
|
||||
} else {
|
||||
repo.IsPrivate = !repo_.Public
|
||||
}
|
||||
|
||||
repos = append(repos, repo)
|
||||
}
|
||||
|
||||
return repos, err
|
||||
}
|
||||
|
||||
// Perm fetches the named repository from the remote system.
|
||||
func (g *Gitlab) Perm(ctx context.Context, u *model.User, owner, name string) (*model.Perm, error) {
|
||||
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, owner, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
repo, err := client.Project(id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// repo owner is granted full access
|
||||
if repo.Owner != nil && repo.Owner.Username == u.Login {
|
||||
return &model.Perm{Push: true, Pull: true, Admin: true}, nil
|
||||
}
|
||||
|
||||
// check permission for current user
|
||||
m := &model.Perm{}
|
||||
m.Admin = IsAdmin(repo)
|
||||
m.Pull = IsRead(repo)
|
||||
m.Push = IsWrite(repo)
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// File fetches a file from the remote repository and returns in string format.
|
||||
func (g *Gitlab) File(ctx context.Context, user *model.User, repo *model.Repo, build *model.Build, f string) ([]byte, error) {
|
||||
var client = NewClient(g.URL, user.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, repo.Owner, repo.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
out, err := client.RepoRawFile(id, build.Commit, f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, err
|
||||
}
|
||||
|
||||
func (c *Gitlab) Dir(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, f string) ([]*remote.FileMeta, error) {
|
||||
return nil, fmt.Errorf("Not implemented")
|
||||
}
|
||||
|
||||
// NOTE Currently gitlab doesn't support status for commits and events,
|
||||
// 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.
|
||||
func (g *Gitlab) Status(ctx context.Context, u *model.User, r *model.Repo, b *model.Build, link string, proc *model.Proc) error {
|
||||
client := NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
|
||||
status := getStatus(b.Status)
|
||||
desc := getDesc(b.Status)
|
||||
|
||||
client.SetStatus(
|
||||
ns(r.Owner, r.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
|
||||
}
|
||||
|
||||
// Netrc returns a .netrc file that can be used to clone
|
||||
// private repositories from a remote system.
|
||||
// func (g *Gitlab) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) {
|
||||
// url_, err := url.Parse(g.URL)
|
||||
// if err != nil {
|
||||
// return nil, err
|
||||
// }
|
||||
// netrc := &model.Netrc{}
|
||||
// netrc.Machine = url_.Host
|
||||
//
|
||||
// switch g.CloneMode {
|
||||
// case "oauth":
|
||||
// netrc.Login = "oauth2"
|
||||
// netrc.Password = u.Token
|
||||
// case "token":
|
||||
// t := token.New(token.HookToken, r.FullName)
|
||||
// netrc.Login = "drone-ci-token"
|
||||
// netrc.Password, err = t.Sign(r.Hash)
|
||||
// }
|
||||
// return netrc, err
|
||||
// }
|
||||
|
||||
// Netrc returns a netrc file capable of authenticating Gitlab requests and
|
||||
// cloning Gitlab repositories. The netrc will use the global machine account
|
||||
// when configured.
|
||||
func (g *Gitlab) Netrc(u *model.User, r *model.Repo) (*model.Netrc, error) {
|
||||
if g.Password != "" {
|
||||
return &model.Netrc{
|
||||
Login: g.Username,
|
||||
Password: g.Password,
|
||||
Machine: g.Machine,
|
||||
}, nil
|
||||
}
|
||||
return &model.Netrc{
|
||||
Login: "oauth2",
|
||||
Password: u.Token,
|
||||
Machine: g.Machine,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Activate activates a repository by adding a Post-commit hook and
|
||||
// a Public Deploy key, if applicable.
|
||||
func (g *Gitlab) Activate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
var client = NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, r.Owner, r.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
uri, err := url.Parse(link)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
droneUrl := fmt.Sprintf("%s://%s", uri.Scheme, uri.Host)
|
||||
droneToken := uri.Query().Get("access_token")
|
||||
ssl_verify := strconv.FormatBool(!g.SkipVerify)
|
||||
|
||||
return client.AddDroneService(id, map[string]string{
|
||||
"token": droneToken,
|
||||
"drone_url": droneUrl,
|
||||
"enable_ssl_verification": ssl_verify,
|
||||
})
|
||||
}
|
||||
|
||||
// Deactivate removes a repository by removing all the post-commit hooks
|
||||
// which are equal to link and removing the SSH deploy key.
|
||||
func (g *Gitlab) Deactivate(ctx context.Context, u *model.User, r *model.Repo, link string) error {
|
||||
var client = NewClient(g.URL, u.Token, g.SkipVerify)
|
||||
id, err := GetProjectId(g, client, r.Owner, r.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return client.DeleteDroneService(id)
|
||||
}
|
||||
|
||||
// ParseHook parses the post-commit hook from the Request body
|
||||
// and returns the required data in a standard format.
|
||||
func (g *Gitlab) Hook(req *http.Request) (*model.Repo, *model.Build, error) {
|
||||
defer req.Body.Close()
|
||||
var payload, _ = ioutil.ReadAll(req.Body)
|
||||
var parsed, err = client.ParseHook(payload)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
switch parsed.ObjectKind {
|
||||
case "merge_request":
|
||||
return mergeRequest(parsed, req)
|
||||
case "tag_push", "push":
|
||||
return push(parsed, req)
|
||||
default:
|
||||
return nil, nil, nil
|
||||
}
|
||||
}
|
||||
|
||||
func mergeRequest(parsed *client.HookPayload, req *http.Request) (*model.Repo, *model.Build, error) {
|
||||
|
||||
repo := &model.Repo{}
|
||||
|
||||
obj := parsed.ObjectAttributes
|
||||
if obj == nil {
|
||||
return nil, nil, fmt.Errorf("object_attributes key expected in merge request hook")
|
||||
}
|
||||
|
||||
target := obj.Target
|
||||
source := obj.Source
|
||||
|
||||
if target == nil && source == nil {
|
||||
return nil, nil, fmt.Errorf("target and source keys expected in merge request hook")
|
||||
} else if target == nil {
|
||||
return nil, nil, fmt.Errorf("target key expected in merge request hook")
|
||||
} else if source == nil {
|
||||
return nil, nil, fmt.Errorf("source key exptected in merge request hook")
|
||||
}
|
||||
|
||||
if target.PathWithNamespace != "" {
|
||||
var err error
|
||||
if repo.Owner, repo.Name, err = ExtractFromPath(target.PathWithNamespace); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
repo.FullName = target.PathWithNamespace
|
||||
} else {
|
||||
repo.Owner = req.FormValue("owner")
|
||||
repo.Name = req.FormValue("name")
|
||||
repo.FullName = fmt.Sprintf("%s/%s", repo.Owner, repo.Name)
|
||||
}
|
||||
|
||||
repo.Link = target.WebUrl
|
||||
|
||||
if target.GitHttpUrl != "" {
|
||||
repo.Clone = target.GitHttpUrl
|
||||
} else {
|
||||
repo.Clone = target.HttpUrl
|
||||
}
|
||||
|
||||
if target.DefaultBranch != "" {
|
||||
repo.Branch = target.DefaultBranch
|
||||
} else {
|
||||
repo.Branch = "master"
|
||||
}
|
||||
|
||||
if target.AvatarUrl != "" {
|
||||
repo.Avatar = target.AvatarUrl
|
||||
}
|
||||
|
||||
build := &model.Build{}
|
||||
build.Event = "pull_request"
|
||||
|
||||
lastCommit := obj.LastCommit
|
||||
if lastCommit == nil {
|
||||
return nil, nil, fmt.Errorf("last_commit key expected in merge request hook")
|
||||
}
|
||||
|
||||
build.Message = lastCommit.Message
|
||||
build.Commit = lastCommit.Id
|
||||
//build.Remote = parsed.ObjectAttributes.Source.HttpUrl
|
||||
|
||||
build.Ref = fmt.Sprintf("refs/merge-requests/%d/head", obj.IId)
|
||||
|
||||
build.Branch = obj.SourceBranch
|
||||
|
||||
author := lastCommit.Author
|
||||
if author == nil {
|
||||
return nil, nil, fmt.Errorf("author key expected in merge request hook")
|
||||
}
|
||||
|
||||
build.Author = author.Name
|
||||
build.Email = author.Email
|
||||
|
||||
if len(build.Email) != 0 {
|
||||
build.Avatar = GetUserAvatar(build.Email)
|
||||
}
|
||||
|
||||
build.Title = obj.Title
|
||||
build.Link = obj.Url
|
||||
|
||||
return repo, build, nil
|
||||
}
|
||||
|
||||
func push(parsed *client.HookPayload, req *http.Request) (*model.Repo, *model.Build, error) {
|
||||
repo := &model.Repo{}
|
||||
|
||||
// Since gitlab 8.5, used project instead repository key
|
||||
// see https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/web_hooks/web_hooks.md#web-hooks
|
||||
if project := parsed.Project; project != nil {
|
||||
var err error
|
||||
if repo.Owner, repo.Name, err = ExtractFromPath(project.PathWithNamespace); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
repo.Avatar = project.AvatarUrl
|
||||
repo.Link = project.WebUrl
|
||||
repo.Clone = project.GitHttpUrl
|
||||
repo.FullName = project.PathWithNamespace
|
||||
repo.Branch = project.DefaultBranch
|
||||
|
||||
switch project.VisibilityLevel {
|
||||
case 0:
|
||||
repo.IsPrivate = true
|
||||
case 10:
|
||||
repo.IsPrivate = true
|
||||
case 20:
|
||||
repo.IsPrivate = false
|
||||
}
|
||||
} else if repository := parsed.Repository; repository != nil {
|
||||
repo.Owner = req.FormValue("owner")
|
||||
repo.Name = req.FormValue("name")
|
||||
repo.Link = repository.URL
|
||||
repo.Clone = repository.GitHttpUrl
|
||||
repo.Branch = "master"
|
||||
repo.FullName = fmt.Sprintf("%s/%s", req.FormValue("owner"), req.FormValue("name"))
|
||||
|
||||
switch repository.VisibilityLevel {
|
||||
case 0:
|
||||
repo.IsPrivate = true
|
||||
case 10:
|
||||
repo.IsPrivate = true
|
||||
case 20:
|
||||
repo.IsPrivate = false
|
||||
}
|
||||
} else {
|
||||
return nil, nil, fmt.Errorf("No project/repository keys given")
|
||||
}
|
||||
|
||||
build := &model.Build{}
|
||||
build.Event = model.EventPush
|
||||
build.Commit = parsed.After
|
||||
build.Branch = parsed.Branch()
|
||||
build.Ref = parsed.Ref
|
||||
// hook.Commit.Remote = cloneUrl
|
||||
|
||||
var head = parsed.Head()
|
||||
build.Message = head.Message
|
||||
// build.Timestamp = head.Timestamp
|
||||
|
||||
// extracts the commit author (ideally email)
|
||||
// from the post-commit hook
|
||||
switch {
|
||||
case head.Author != nil:
|
||||
build.Email = head.Author.Email
|
||||
build.Author = parsed.UserName
|
||||
if len(build.Email) != 0 {
|
||||
build.Avatar = GetUserAvatar(build.Email)
|
||||
}
|
||||
case head.Author == nil:
|
||||
build.Author = parsed.UserName
|
||||
}
|
||||
|
||||
if strings.HasPrefix(build.Ref, "refs/tags/") {
|
||||
build.Event = model.EventTag
|
||||
}
|
||||
|
||||
return repo, build, nil
|
||||
}
|
||||
|
||||
// ¯\_(ツ)_/¯
|
||||
func (g *Gitlab) Oauth2Transport(r *http.Request) *oauth2.Transport {
|
||||
return &oauth2.Transport{
|
||||
Config: &oauth2.Config{
|
||||
ClientId: g.Client,
|
||||
ClientSecret: g.Secret,
|
||||
Scope: DefaultScope,
|
||||
AuthURL: fmt.Sprintf("%s/oauth/authorize", g.URL),
|
||||
TokenURL: fmt.Sprintf("%s/oauth/token", g.URL),
|
||||
RedirectURL: fmt.Sprintf("%s/authorize", server.Config.Server.Host),
|
||||
//settings.Server.Scheme, settings.Server.Hostname),
|
||||
},
|
||||
Transport: &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: g.SkipVerify},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
StatusPending = "pending"
|
||||
StatusRunning = "running"
|
||||
StatusSuccess = "success"
|
||||
StatusFailure = "failed"
|
||||
StatusCanceled = "canceled"
|
||||
)
|
||||
|
||||
const (
|
||||
DescPending = "the build is pending"
|
||||
DescRunning = "the buils is running"
|
||||
DescSuccess = "the build was successful"
|
||||
DescFailure = "the build failed"
|
||||
DescCanceled = "the build canceled"
|
||||
DescBlocked = "the build is pending approval"
|
||||
DescDeclined = "the build was rejected"
|
||||
)
|
||||
|
||||
// getStatus is a helper functin that converts a Drone
|
||||
// status to a GitHub status.
|
||||
func getStatus(status string) string {
|
||||
switch status {
|
||||
case model.StatusPending, model.StatusBlocked:
|
||||
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
|
||||
case model.StatusBlocked:
|
||||
return DescBlocked
|
||||
case model.StatusDeclined:
|
||||
return DescDeclined
|
||||
default:
|
||||
return DescFailure
|
||||
}
|
||||
}
|
|
@ -1,261 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gitlab3
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/franela/goblin"
|
||||
"github.com/woodpecker-ci/woodpecker/server/model"
|
||||
"github.com/woodpecker-ci/woodpecker/server/remote/gitlab3/testdata"
|
||||
)
|
||||
|
||||
func Test_Gitlab(t *testing.T) {
|
||||
// setup a dummy github server
|
||||
var server = testdata.NewServer()
|
||||
defer server.Close()
|
||||
|
||||
env := server.URL + "?client_id=test&client_secret=test"
|
||||
|
||||
gitlab := Load(env)
|
||||
|
||||
var user = model.User{
|
||||
Login: "test_user",
|
||||
Token: "e3b0c44298fc1c149afbf4c8996fb",
|
||||
}
|
||||
|
||||
var repo = model.Repo{
|
||||
Name: "diaspora-client",
|
||||
Owner: "diaspora",
|
||||
}
|
||||
|
||||
g := goblin.Goblin(t)
|
||||
g.Describe("Gitlab Plugin", func() {
|
||||
// Test projects method
|
||||
g.Describe("AllProjects", func() {
|
||||
g.It("Should return only non-archived projects is hidden", func() {
|
||||
gitlab.HideArchives = true
|
||||
_projects, err := gitlab.Repos(nil, &user)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(len(_projects)).Equal(1)
|
||||
})
|
||||
|
||||
g.It("Should return all the projects", func() {
|
||||
gitlab.HideArchives = false
|
||||
_projects, err := gitlab.Repos(nil, &user)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(len(_projects)).Equal(2)
|
||||
})
|
||||
})
|
||||
|
||||
// Test repository method
|
||||
g.Describe("Repo", func() {
|
||||
g.It("Should return valid repo", func() {
|
||||
_repo, err := gitlab.Repo(nil, &user, "diaspora", "diaspora-client")
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(_repo.Name).Equal("diaspora-client")
|
||||
g.Assert(_repo.Owner).Equal("diaspora")
|
||||
g.Assert(_repo.IsPrivate).Equal(true)
|
||||
})
|
||||
|
||||
g.It("Should return error, when repo not exist", func() {
|
||||
_, err := gitlab.Repo(nil, &user, "not-existed", "not-existed")
|
||||
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
// Test permissions method
|
||||
g.Describe("Perm", func() {
|
||||
g.It("Should return repo permissions", func() {
|
||||
perm, err := gitlab.Perm(nil, &user, "diaspora", "diaspora-client")
|
||||
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 repo permissions when user is admin", func() {
|
||||
perm, err := gitlab.Perm(nil, &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() {
|
||||
_, err := gitlab.Perm(nil, &user, "not-existed", "not-existed")
|
||||
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
// Test activate method
|
||||
g.Describe("Activate", func() {
|
||||
g.It("Should be success", func() {
|
||||
err := gitlab.Activate(nil, &user, &repo, "http://example.com/api/hook/test/test?access_token=token")
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
|
||||
g.It("Should be failed, when token not given", func() {
|
||||
err := gitlab.Activate(nil, &user, &repo, "http://example.com/api/hook/test/test")
|
||||
|
||||
g.Assert(err != nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
// Test deactivate method
|
||||
g.Describe("Deactivate", func() {
|
||||
g.It("Should be success", func() {
|
||||
err := gitlab.Deactivate(nil, &user, &repo, "http://example.com/api/hook/test/test?access_token=token")
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
})
|
||||
})
|
||||
|
||||
// Test login method
|
||||
// g.Describe("Login", func() {
|
||||
// g.It("Should return user", func() {
|
||||
// user, err := gitlab.Login("valid_token", "")
|
||||
|
||||
// g.Assert(err == nil).IsTrue()
|
||||
// g.Assert(user == nil).IsFalse()
|
||||
// })
|
||||
|
||||
// g.It("Should return error, when token is invalid", func() {
|
||||
// _, err := gitlab.Login("invalid_token", "")
|
||||
|
||||
// g.Assert(err != nil).IsTrue()
|
||||
// })
|
||||
// })
|
||||
|
||||
// Test hook method
|
||||
g.Describe("Hook", func() {
|
||||
g.Describe("Push hook", func() {
|
||||
g.It("Should parse actual push hoook", func() {
|
||||
req, _ := http.NewRequest(
|
||||
"POST",
|
||||
"http://example.com/api/hook?owner=diaspora&name=diaspora-client",
|
||||
bytes.NewReader(testdata.PushHook),
|
||||
)
|
||||
|
||||
repo, build, err := gitlab.Hook(req)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.Owner).Equal("mike")
|
||||
g.Assert(repo.Name).Equal("diaspora")
|
||||
g.Assert(repo.Avatar).Equal("http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg")
|
||||
g.Assert(repo.Branch).Equal("develop")
|
||||
g.Assert(build.Ref).Equal("refs/heads/master")
|
||||
|
||||
})
|
||||
|
||||
g.It("Should parse legacy push hoook", func() {
|
||||
req, _ := http.NewRequest(
|
||||
"POST",
|
||||
"http://example.com/api/hook?owner=diaspora&name=diaspora-client",
|
||||
bytes.NewReader(testdata.LegacyPushHook),
|
||||
)
|
||||
|
||||
repo, build, err := gitlab.Hook(req)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.Owner).Equal("diaspora")
|
||||
g.Assert(repo.Name).Equal("diaspora-client")
|
||||
g.Assert(repo.Avatar).Equal("")
|
||||
g.Assert(repo.Branch).Equal("master")
|
||||
g.Assert(build.Ref).Equal("refs/heads/master")
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("Tag push hook", func() {
|
||||
g.It("Should parse tag push hook", func() {
|
||||
req, _ := http.NewRequest(
|
||||
"POST",
|
||||
"http://example.com/api/hook?owner=diaspora&name=diaspora-client",
|
||||
bytes.NewReader(testdata.TagHook),
|
||||
)
|
||||
|
||||
repo, build, err := gitlab.Hook(req)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.Owner).Equal("jsmith")
|
||||
g.Assert(repo.Name).Equal("example")
|
||||
g.Assert(repo.Avatar).Equal("http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg")
|
||||
g.Assert(repo.Branch).Equal("develop")
|
||||
g.Assert(build.Ref).Equal("refs/tags/v1.0.0")
|
||||
|
||||
})
|
||||
|
||||
g.It("Should parse legacy tag push hook", func() {
|
||||
req, _ := http.NewRequest(
|
||||
"POST",
|
||||
"http://example.com/api/hook?owner=diaspora&name=diaspora-client",
|
||||
bytes.NewReader(testdata.LegacyTagHook),
|
||||
)
|
||||
|
||||
repo, build, err := gitlab.Hook(req)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.Owner).Equal("diaspora")
|
||||
g.Assert(repo.Name).Equal("diaspora-client")
|
||||
g.Assert(build.Ref).Equal("refs/tags/v1.0.0")
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
g.Describe("Merge request hook", func() {
|
||||
g.It("Should parse merge request hook", func() {
|
||||
req, _ := http.NewRequest(
|
||||
"POST",
|
||||
"http://example.com/api/hook?owner=diaspora&name=diaspora-client",
|
||||
bytes.NewReader(testdata.MergeRequestHook),
|
||||
)
|
||||
|
||||
repo, build, err := gitlab.Hook(req)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.Avatar).Equal("http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg")
|
||||
g.Assert(repo.Branch).Equal("develop")
|
||||
g.Assert(repo.Owner).Equal("awesome_space")
|
||||
g.Assert(repo.Name).Equal("awesome_project")
|
||||
|
||||
g.Assert(build.Title).Equal("MS-Viewport")
|
||||
})
|
||||
|
||||
g.It("Should parse legacy merge request hook", func() {
|
||||
req, _ := http.NewRequest(
|
||||
"POST",
|
||||
"http://example.com/api/hook?owner=diaspora&name=diaspora-client",
|
||||
bytes.NewReader(testdata.LegacyMergeRequestHook),
|
||||
)
|
||||
|
||||
repo, build, err := gitlab.Hook(req)
|
||||
|
||||
g.Assert(err == nil).IsTrue()
|
||||
g.Assert(repo.Owner).Equal("diaspora")
|
||||
g.Assert(repo.Name).Equal("diaspora-client")
|
||||
|
||||
g.Assert(build.Title).Equal("MS-Viewport")
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gitlab3
|
||||
|
||||
import (
|
||||
"crypto/md5"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/woodpecker-ci/woodpecker/server/remote/gitlab3/client"
|
||||
)
|
||||
|
||||
const (
|
||||
gravatarBase = "https://www.gravatar.com/avatar"
|
||||
)
|
||||
|
||||
// NewClient is a helper function that returns a new GitHub
|
||||
// client using the provided OAuth token.
|
||||
func NewClient(url, accessToken string, skipVerify bool) *client.Client {
|
||||
client := client.New(url, "/api/v3", accessToken, skipVerify)
|
||||
return client
|
||||
}
|
||||
|
||||
// IsRead is a helper function that returns true if the
|
||||
// user has Read-only access to the repository.
|
||||
func IsRead(proj *client.Project) bool {
|
||||
var user = proj.Permissions.ProjectAccess
|
||||
var group = proj.Permissions.GroupAccess
|
||||
|
||||
switch {
|
||||
case proj.Public:
|
||||
return true
|
||||
case user != nil && user.AccessLevel >= 20:
|
||||
return true
|
||||
case group != nil && group.AccessLevel >= 20:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// IsWrite is a helper function that returns true if the
|
||||
// user has Read-Write access to the repository.
|
||||
func IsWrite(proj *client.Project) bool {
|
||||
var user = proj.Permissions.ProjectAccess
|
||||
var group = proj.Permissions.GroupAccess
|
||||
|
||||
switch {
|
||||
case user != nil && user.AccessLevel >= 30:
|
||||
return true
|
||||
case group != nil && group.AccessLevel >= 30:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// IsAdmin is a helper function that returns true if the
|
||||
// user has Admin access to the repository.
|
||||
func IsAdmin(proj *client.Project) bool {
|
||||
var user = proj.Permissions.ProjectAccess
|
||||
var group = proj.Permissions.GroupAccess
|
||||
|
||||
switch {
|
||||
case user != nil && user.AccessLevel >= 40:
|
||||
return true
|
||||
case group != nil && group.AccessLevel >= 40:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// GetKeyTitle is a helper function that generates a title for the
|
||||
// RSA public key based on the username and domain name.
|
||||
func GetKeyTitle(rawurl string) (string, error) {
|
||||
var uri, err = url.Parse(rawurl)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("drone@%s", uri.Host), nil
|
||||
}
|
||||
|
||||
func ns(owner, name string) string {
|
||||
return fmt.Sprintf("%s%%2F%s", owner, name)
|
||||
}
|
||||
|
||||
func GetUserAvatar(email string) string {
|
||||
hasher := md5.New()
|
||||
hasher.Write([]byte(email))
|
||||
|
||||
return fmt.Sprintf(
|
||||
"%s/%v.jpg?s=%s",
|
||||
gravatarBase,
|
||||
hex.EncodeToString(hasher.Sum(nil)),
|
||||
"128",
|
||||
)
|
||||
}
|
||||
|
||||
func ExtractFromPath(str string) (string, string, error) {
|
||||
s := strings.Split(str, "/")
|
||||
if len(s) < 2 {
|
||||
return "", "", fmt.Errorf("Minimum match not found")
|
||||
}
|
||||
return s[0], s[1], nil
|
||||
}
|
||||
|
||||
func GetUserEmail(c *client.Client, defaultURL string) (*client.Client, error) {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func GetProjectId(r *Gitlab, c *client.Client, owner, name string) (projectId string, err error) {
|
||||
if r.Search {
|
||||
_projectId, err := c.SearchProjectId(owner, name)
|
||||
if err != nil || _projectId == 0 {
|
||||
return "", err
|
||||
}
|
||||
projectId := strconv.Itoa(_projectId)
|
||||
return projectId, nil
|
||||
} else {
|
||||
projectId := ns(owner, name)
|
||||
return projectId, nil
|
||||
}
|
||||
}
|
348
server/remote/gitlab3/testdata/hooks.go
vendored
348
server/remote/gitlab3/testdata/hooks.go
vendored
|
@ -1,348 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package testdata
|
||||
|
||||
var TagHook = []byte(`
|
||||
{
|
||||
"object_kind": "tag_push",
|
||||
"ref": "refs/tags/v1.0.0",
|
||||
"before": "0000000000000000000000000000000000000000",
|
||||
"after": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7",
|
||||
"user_id": 1,
|
||||
"user_name": "John Smith",
|
||||
"user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=8://s=80",
|
||||
"project_id": 1,
|
||||
"project":{
|
||||
"name":"Example",
|
||||
"description":"",
|
||||
"web_url":"http://example.com/jsmith/example",
|
||||
"avatar_url":"http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg",
|
||||
"git_ssh_url":"git@example.com:jsmith/example.git",
|
||||
"git_http_url":"http://example.com/jsmith/example.git",
|
||||
"namespace":"Jsmith",
|
||||
"visibility_level":0,
|
||||
"path_with_namespace":"jsmith/example",
|
||||
"default_branch":"develop",
|
||||
"homepage":"http://example.com/jsmith/example",
|
||||
"url":"git@example.com:jsmith/example.git",
|
||||
"ssh_url":"git@example.com:jsmith/example.git",
|
||||
"http_url":"http://example.com/jsmith/example.git"
|
||||
},
|
||||
"repository":{
|
||||
"name": "jsmith",
|
||||
"url": "ssh://git@example.com/jsmith/example.git",
|
||||
"description": "",
|
||||
"homepage": "http://example.com/jsmith/example",
|
||||
"git_http_url":"http://example.com/jsmith/example.git",
|
||||
"git_ssh_url":"git@example.com:jsmith/example.git",
|
||||
"visibility_level":0
|
||||
},
|
||||
"commits": [],
|
||||
"total_commits_count": 0
|
||||
}
|
||||
`)
|
||||
|
||||
var LegacyTagHook = []byte(`
|
||||
{
|
||||
"object_kind": "tag_push",
|
||||
"ref": "refs/tags/v1.0.0",
|
||||
"before": "0000000000000000000000000000000000000000",
|
||||
"after": "82b3d5ae55f7080f1e6022629cdb57bfae7cccc7",
|
||||
"user_id": 1,
|
||||
"user_name": "John Smith",
|
||||
"project_id": 1,
|
||||
"repository": {
|
||||
"name": "jsmith",
|
||||
"url": "ssh://git@example.com/jsmith/example.git",
|
||||
"description": "",
|
||||
"homepage": "http://example.com/jsmith/example",
|
||||
"git_http_url":"http://example.com/jsmith/example.git",
|
||||
"git_ssh_url":"git@example.com:jsmith/example.git",
|
||||
"visibility_level":0
|
||||
},
|
||||
"commits": [
|
||||
{
|
||||
"id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
|
||||
"message": "Update Catalan translation to e38cb41.",
|
||||
"timestamp": "2011-12-12T14:27:31+02:00",
|
||||
"url": "http://example.com/mike/diaspora/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
|
||||
"author": {
|
||||
"name": "Jordi Mallach",
|
||||
"email": "jordi@softcatala.org"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"message": "fixed readme",
|
||||
"timestamp": "2012-01-03T23:36:29+02:00",
|
||||
"url": "http://example.com/mike/diaspora/commit/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"author": {
|
||||
"name": "GitLab dev user",
|
||||
"email": "gitlabdev@dv6700.(none)"
|
||||
}
|
||||
}
|
||||
],
|
||||
"total_commits_count": 4
|
||||
}
|
||||
`)
|
||||
|
||||
var MergeRequestHook = []byte(`
|
||||
{
|
||||
"object_kind": "merge_request",
|
||||
"user": {
|
||||
"name": "Administrator",
|
||||
"username": "root",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
|
||||
},
|
||||
"object_attributes": {
|
||||
"id": 99,
|
||||
"target_branch": "master",
|
||||
"source_branch": "ms-viewport",
|
||||
"source_project_id": 14,
|
||||
"author_id": 51,
|
||||
"assignee_id": 6,
|
||||
"title": "MS-Viewport",
|
||||
"created_at": "2013-12-03T17:23:34Z",
|
||||
"updated_at": "2013-12-03T17:23:34Z",
|
||||
"st_commits": null,
|
||||
"st_diffs": null,
|
||||
"milestone_id": null,
|
||||
"state": "opened",
|
||||
"merge_status": "unchecked",
|
||||
"target_project_id": 14,
|
||||
"iid": 1,
|
||||
"description": "",
|
||||
"source":{
|
||||
"name":"Awesome Project",
|
||||
"description":"Aut reprehenderit ut est.",
|
||||
"web_url":"http://example.com/awesome_space/awesome_project",
|
||||
"avatar_url":"http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg",
|
||||
"git_ssh_url":"git@example.com:awesome_space/awesome_project.git",
|
||||
"git_http_url":"http://example.com/awesome_space/awesome_project.git",
|
||||
"namespace":"Awesome Space",
|
||||
"visibility_level":20,
|
||||
"path_with_namespace":"awesome_space/awesome_project",
|
||||
"default_branch":"master",
|
||||
"homepage":"http://example.com/awesome_space/awesome_project",
|
||||
"url":"http://example.com/awesome_space/awesome_project.git",
|
||||
"ssh_url":"git@example.com:awesome_space/awesome_project.git",
|
||||
"http_url":"http://example.com/awesome_space/awesome_project.git"
|
||||
},
|
||||
"target": {
|
||||
"name":"Awesome Project",
|
||||
"description":"Aut reprehenderit ut est.",
|
||||
"web_url":"http://example.com/awesome_space/awesome_project",
|
||||
"avatar_url":"http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg",
|
||||
"git_ssh_url":"git@example.com:awesome_space/awesome_project.git",
|
||||
"git_http_url":"http://example.com/awesome_space/awesome_project.git",
|
||||
"namespace":"Awesome Space",
|
||||
"visibility_level":20,
|
||||
"path_with_namespace":"awesome_space/awesome_project",
|
||||
"default_branch":"develop",
|
||||
"homepage":"http://example.com/awesome_space/awesome_project",
|
||||
"url":"http://example.com/awesome_space/awesome_project.git",
|
||||
"ssh_url":"git@example.com:awesome_space/awesome_project.git",
|
||||
"http_url":"http://example.com/awesome_space/awesome_project.git"
|
||||
},
|
||||
"last_commit": {
|
||||
"id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"message": "fixed readme",
|
||||
"timestamp": "2012-01-03T23:36:29+02:00",
|
||||
"url": "http://example.com/awesome_space/awesome_project/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"author": {
|
||||
"name": "GitLab dev user",
|
||||
"email": "gitlabdev@dv6700.(none)"
|
||||
}
|
||||
},
|
||||
"work_in_progress": false,
|
||||
"url": "http://example.com/diaspora/merge_requests/1",
|
||||
"action": "open",
|
||||
"assignee": {
|
||||
"name": "User1",
|
||||
"username": "user1",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
var LegacyMergeRequestHook = []byte(`
|
||||
{
|
||||
"object_kind": "merge_request",
|
||||
"user": {
|
||||
"name": "Administrator",
|
||||
"username": "root",
|
||||
"avatar_url": "http://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=40\u0026d=identicon"
|
||||
},
|
||||
"object_attributes": {
|
||||
"id": 99,
|
||||
"target_branch": "master",
|
||||
"source_branch": "ms-viewport",
|
||||
"source_project_id": 14,
|
||||
"author_id": 51,
|
||||
"assignee_id": 6,
|
||||
"title": "MS-Viewport",
|
||||
"created_at": "2013-12-03T17:23:34Z",
|
||||
"updated_at": "2013-12-03T17:23:34Z",
|
||||
"st_commits": null,
|
||||
"st_diffs": null,
|
||||
"milestone_id": null,
|
||||
"state": "opened",
|
||||
"merge_status": "unchecked",
|
||||
"target_project_id": 14,
|
||||
"iid": 1,
|
||||
"description": "",
|
||||
"source": {
|
||||
"name": "awesome_project",
|
||||
"ssh_url": "ssh://git@example.com/awesome_space/awesome_project.git",
|
||||
"http_url": "http://example.com/awesome_space/awesome_project.git",
|
||||
"visibility_level": 20,
|
||||
"namespace": "awesome_space"
|
||||
},
|
||||
"target": {
|
||||
"name": "awesome_project",
|
||||
"ssh_url": "ssh://git@example.com/awesome_space/awesome_project.git",
|
||||
"http_url": "http://example.com/awesome_space/awesome_project.git",
|
||||
"visibility_level": 20,
|
||||
"namespace": "awesome_space"
|
||||
},
|
||||
"last_commit": {
|
||||
"id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"message": "fixed readme",
|
||||
"timestamp": "2012-01-03T23:36:29+02:00",
|
||||
"url": "http://example.com/awesome_space/awesome_project/commits/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"author": {
|
||||
"name": "GitLab dev user",
|
||||
"email": "gitlabdev@dv6700.(none)"
|
||||
}
|
||||
},
|
||||
"url": "http://example.com/diaspora/merge_requests/1",
|
||||
"action": "open"
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
var PushHook = []byte(`
|
||||
{
|
||||
"object_kind": "push",
|
||||
"before": "95790bf891e76fee5e1747ab589903a6a1f80f22",
|
||||
"after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"ref": "refs/heads/master",
|
||||
"user_id": 4,
|
||||
"user_name": "John Smith",
|
||||
"user_email": "john@example.com",
|
||||
"user_avatar": "https://s.gravatar.com/avatar/d4c74594d841139328695756648b6bd6?s=80",
|
||||
"project_id": 15,
|
||||
"project":{
|
||||
"name":"Diaspora",
|
||||
"description":"",
|
||||
"web_url":"http://example.com/mike/diaspora",
|
||||
"avatar_url":"http://example.com/uploads/project/avatar/555/Outh-20-Logo.jpg",
|
||||
"git_ssh_url":"git@example.com:mike/diaspora.git",
|
||||
"git_http_url":"http://example.com/mike/diaspora.git",
|
||||
"namespace":"Mike",
|
||||
"visibility_level":0,
|
||||
"path_with_namespace":"mike/diaspora",
|
||||
"default_branch":"develop",
|
||||
"homepage":"http://example.com/mike/diaspora",
|
||||
"url":"git@example.com:mike/diasporadiaspora.git",
|
||||
"ssh_url":"git@example.com:mike/diaspora.git",
|
||||
"http_url":"http://example.com/mike/diaspora.git"
|
||||
},
|
||||
"repository":{
|
||||
"name": "Diaspora",
|
||||
"url": "git@example.com:mike/diasporadiaspora.git",
|
||||
"description": "",
|
||||
"homepage": "http://example.com/mike/diaspora",
|
||||
"git_http_url":"http://example.com/mike/diaspora.git",
|
||||
"git_ssh_url":"git@example.com:mike/diaspora.git",
|
||||
"visibility_level":0
|
||||
},
|
||||
"commits": [
|
||||
{
|
||||
"id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
|
||||
"message": "Update Catalan translation to e38cb41.",
|
||||
"timestamp": "2011-12-12T14:27:31+02:00",
|
||||
"url": "http://example.com/mike/diaspora/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
|
||||
"author": {
|
||||
"name": "Jordi Mallach",
|
||||
"email": "jordi@softcatala.org"
|
||||
},
|
||||
"added": ["CHANGELOG"],
|
||||
"modified": ["app/controller/application.rb"],
|
||||
"removed": []
|
||||
},
|
||||
{
|
||||
"id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"message": "fixed readme",
|
||||
"timestamp": "2012-01-03T23:36:29+02:00",
|
||||
"url": "http://example.com/mike/diaspora/commit/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"author": {
|
||||
"name": "GitLab dev user",
|
||||
"email": "gitlabdev@dv6700.(none)"
|
||||
},
|
||||
"added": ["CHANGELOG"],
|
||||
"modified": ["app/controller/application.rb"],
|
||||
"removed": []
|
||||
}
|
||||
],
|
||||
"total_commits_count": 4
|
||||
}
|
||||
`)
|
||||
|
||||
var LegacyPushHook = []byte(`
|
||||
{
|
||||
"object_kind": "push",
|
||||
"before": "95790bf891e76fee5e1747ab589903a6a1f80f22",
|
||||
"after": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"ref": "refs/heads/master",
|
||||
"user_id": 4,
|
||||
"user_name": "John Smith",
|
||||
"user_email": "john@example.com",
|
||||
"project_id": 15,
|
||||
"repository": {
|
||||
"name": "Diaspora",
|
||||
"url": "git@example.com:mike/diasporadiaspora.git",
|
||||
"description": "",
|
||||
"homepage": "http://example.com/mike/diaspora",
|
||||
"git_http_url":"http://example.com/mike/diaspora.git",
|
||||
"git_ssh_url":"git@example.com:mike/diaspora.git",
|
||||
"visibility_level":0
|
||||
},
|
||||
"commits": [
|
||||
{
|
||||
"id": "b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
|
||||
"message": "Update Catalan translation to e38cb41.",
|
||||
"timestamp": "2011-12-12T14:27:31+02:00",
|
||||
"url": "http://example.com/mike/diaspora/commit/b6568db1bc1dcd7f8b4d5a946b0b91f9dacd7327",
|
||||
"author": {
|
||||
"name": "Jordi Mallach",
|
||||
"email": "jordi@softcatala.org"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"message": "fixed readme",
|
||||
"timestamp": "2012-01-03T23:36:29+02:00",
|
||||
"url": "http://example.com/mike/diaspora/commit/da1560886d4f094c3e6c9ef40349f7d38b5d27d7",
|
||||
"author": {
|
||||
"name": "GitLab dev user",
|
||||
"email": "gitlabdev@dv6700.(none)"
|
||||
}
|
||||
}
|
||||
],
|
||||
"total_commits_count": 4
|
||||
}
|
||||
`)
|
17
server/remote/gitlab3/testdata/oauth.go
vendored
17
server/remote/gitlab3/testdata/oauth.go
vendored
|
@ -1,17 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package testdata
|
||||
|
||||
var accessTokenPayload = []byte(`access_token=sekret&scope=api&token_type=bearer`)
|
226
server/remote/gitlab3/testdata/projects.go
vendored
226
server/remote/gitlab3/testdata/projects.go
vendored
|
@ -1,226 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package testdata
|
||||
|
||||
// sample repository list
|
||||
var allProjectsPayload = []byte(`
|
||||
[
|
||||
{
|
||||
"id": 4,
|
||||
"description": null,
|
||||
"default_branch": "master",
|
||||
"public": false,
|
||||
"visibility_level": 0,
|
||||
"ssh_url_to_repo": "git@example.com:diaspora/diaspora-client.git",
|
||||
"http_url_to_repo": "http://example.com/diaspora/diaspora-client.git",
|
||||
"web_url": "http://example.com/diaspora/diaspora-client",
|
||||
"owner": {
|
||||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"username": "some_user",
|
||||
"created_at": "2013-09-30T13: 46: 02Z"
|
||||
},
|
||||
"name": "Diaspora Client",
|
||||
"name_with_namespace": "Diaspora / Diaspora Client",
|
||||
"path": "diaspora-client",
|
||||
"path_with_namespace": "diaspora/diaspora-client",
|
||||
"issues_enabled": true,
|
||||
"merge_requests_enabled": true,
|
||||
"wiki_enabled": true,
|
||||
"snippets_enabled": false,
|
||||
"created_at": "2013-09-30T13: 46: 02Z",
|
||||
"last_activity_at": "2013-09-30T13: 46: 02Z",
|
||||
"namespace": {
|
||||
"created_at": "2013-09-30T13: 46: 02Z",
|
||||
"description": "",
|
||||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"owner_id": 1,
|
||||
"path": "diaspora",
|
||||
"updated_at": "2013-09-30T13: 46: 02Z"
|
||||
},
|
||||
"archived": false
|
||||
},
|
||||
{
|
||||
"id": 6,
|
||||
"description": null,
|
||||
"default_branch": "master",
|
||||
"public": false,
|
||||
"visibility_level": 0,
|
||||
"ssh_url_to_repo": "git@example.com:brightbox/puppet.git",
|
||||
"http_url_to_repo": "http://example.com/brightbox/puppet.git",
|
||||
"web_url": "http://example.com/brightbox/puppet",
|
||||
"owner": {
|
||||
"id": 1,
|
||||
"name": "Brightbox",
|
||||
"username": "test_user",
|
||||
"created_at": "2013-09-30T13:46:02Z"
|
||||
},
|
||||
"name": "Puppet",
|
||||
"name_with_namespace": "Brightbox / Puppet",
|
||||
"path": "puppet",
|
||||
"path_with_namespace": "brightbox/puppet",
|
||||
"issues_enabled": true,
|
||||
"merge_requests_enabled": true,
|
||||
"wiki_enabled": true,
|
||||
"snippets_enabled": false,
|
||||
"created_at": "2013-09-30T13:46:02Z",
|
||||
"last_activity_at": "2013-09-30T13:46:02Z",
|
||||
"namespace": {
|
||||
"created_at": "2013-09-30T13:46:02Z",
|
||||
"description": "",
|
||||
"id": 4,
|
||||
"name": "Brightbox",
|
||||
"owner_id": 1,
|
||||
"path": "brightbox",
|
||||
"updated_at": "2013-09-30T13:46:02Z"
|
||||
},
|
||||
"archived": true
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
var notArchivedProjectsPayload = []byte(`
|
||||
[
|
||||
{
|
||||
"id": 4,
|
||||
"description": null,
|
||||
"default_branch": "master",
|
||||
"public": false,
|
||||
"visibility_level": 0,
|
||||
"ssh_url_to_repo": "git@example.com:diaspora/diaspora-client.git",
|
||||
"http_url_to_repo": "http://example.com/diaspora/diaspora-client.git",
|
||||
"web_url": "http://example.com/diaspora/diaspora-client",
|
||||
"owner": {
|
||||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"username": "some_user",
|
||||
"created_at": "2013-09-30T13: 46: 02Z"
|
||||
},
|
||||
"name": "Diaspora Client",
|
||||
"name_with_namespace": "Diaspora / Diaspora Client",
|
||||
"path": "diaspora-client",
|
||||
"path_with_namespace": "diaspora/diaspora-client",
|
||||
"issues_enabled": true,
|
||||
"merge_requests_enabled": true,
|
||||
"wiki_enabled": true,
|
||||
"snippets_enabled": false,
|
||||
"created_at": "2013-09-30T13: 46: 02Z",
|
||||
"last_activity_at": "2013-09-30T13: 46: 02Z",
|
||||
"namespace": {
|
||||
"created_at": "2013-09-30T13: 46: 02Z",
|
||||
"description": "",
|
||||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"owner_id": 1,
|
||||
"path": "diaspora",
|
||||
"updated_at": "2013-09-30T13: 46: 02Z"
|
||||
},
|
||||
"archived": false
|
||||
}
|
||||
]
|
||||
`)
|
||||
|
||||
var project4Paylod = []byte(`
|
||||
{
|
||||
"id": 4,
|
||||
"description": null,
|
||||
"default_branch": "master",
|
||||
"public": false,
|
||||
"visibility_level": 0,
|
||||
"ssh_url_to_repo": "git@example.com:diaspora/diaspora-client.git",
|
||||
"http_url_to_repo": "http://example.com/diaspora/diaspora-client.git",
|
||||
"web_url": "http://example.com/diaspora/diaspora-client",
|
||||
"owner": {
|
||||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"username": "some_user",
|
||||
"created_at": "2013-09-30T13: 46: 02Z"
|
||||
},
|
||||
"name": "Diaspora Client",
|
||||
"name_with_namespace": "Diaspora / Diaspora Client",
|
||||
"path": "diaspora-client",
|
||||
"path_with_namespace": "diaspora/diaspora-client",
|
||||
"issues_enabled": true,
|
||||
"merge_requests_enabled": true,
|
||||
"wiki_enabled": true,
|
||||
"snippets_enabled": false,
|
||||
"created_at": "2013-09-30T13: 46: 02Z",
|
||||
"last_activity_at": "2013-09-30T13: 46: 02Z",
|
||||
"namespace": {
|
||||
"created_at": "2013-09-30T13: 46: 02Z",
|
||||
"description": "",
|
||||
"id": 3,
|
||||
"name": "Diaspora",
|
||||
"owner_id": 1,
|
||||
"path": "diaspora",
|
||||
"updated_at": "2013-09-30T13: 46: 02Z"
|
||||
},
|
||||
"archived": false,
|
||||
"permissions": {
|
||||
"project_access": {
|
||||
"access_level": 10,
|
||||
"notification_level": 3
|
||||
},
|
||||
"group_access": {
|
||||
"access_level": 50,
|
||||
"notification_level": 3
|
||||
}
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
var project6Paylod = []byte(`
|
||||
{
|
||||
"id": 6,
|
||||
"description": null,
|
||||
"default_branch": "master",
|
||||
"public": false,
|
||||
"visibility_level": 0,
|
||||
"ssh_url_to_repo": "git@example.com:brightbox/puppet.git",
|
||||
"http_url_to_repo": "http://example.com/brightbox/puppet.git",
|
||||
"web_url": "http://example.com/brightbox/puppet",
|
||||
"owner": {
|
||||
"id": 1,
|
||||
"name": "Brightbox",
|
||||
"username": "test_user",
|
||||
"created_at": "2013-09-30T13:46:02Z"
|
||||
},
|
||||
"name": "Puppet",
|
||||
"name_with_namespace": "Brightbox / Puppet",
|
||||
"path": "puppet",
|
||||
"path_with_namespace": "brightbox/puppet",
|
||||
"issues_enabled": true,
|
||||
"merge_requests_enabled": true,
|
||||
"wiki_enabled": true,
|
||||
"snippets_enabled": false,
|
||||
"created_at": "2013-09-30T13:46:02Z",
|
||||
"last_activity_at": "2013-09-30T13:46:02Z",
|
||||
"namespace": {
|
||||
"created_at": "2013-09-30T13:46:02Z",
|
||||
"description": "",
|
||||
"id": 4,
|
||||
"name": "Brightbox",
|
||||
"owner_id": 1,
|
||||
"path": "brightbox",
|
||||
"updated_at": "2013-09-30T13:46:02Z"
|
||||
},
|
||||
"archived": false,
|
||||
"permissions": {
|
||||
"project_access": null,
|
||||
"group_access": null
|
||||
}
|
||||
}
|
||||
`)
|
74
server/remote/gitlab3/testdata/testdata.go
vendored
74
server/remote/gitlab3/testdata/testdata.go
vendored
|
@ -1,74 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package testdata
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
)
|
||||
|
||||
// setup a mock server for testing purposes.
|
||||
func NewServer() *httptest.Server {
|
||||
mux := http.NewServeMux()
|
||||
server := httptest.NewServer(mux)
|
||||
|
||||
// handle requests and serve mock data
|
||||
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||
//println(r.URL.Path + " " + r.Method)
|
||||
// evaluate the path to serve a dummy data file
|
||||
switch r.URL.Path {
|
||||
case "/api/v3/projects":
|
||||
if r.URL.Query().Get("archived") == "false" {
|
||||
w.Write(notArchivedProjectsPayload)
|
||||
} else {
|
||||
w.Write(allProjectsPayload)
|
||||
}
|
||||
|
||||
return
|
||||
case "/api/v3/projects/diaspora/diaspora-client":
|
||||
w.Write(project4Paylod)
|
||||
return
|
||||
case "/api/v3/projects/brightbox/puppet":
|
||||
w.Write(project6Paylod)
|
||||
return
|
||||
case "/api/v3/projects/diaspora/diaspora-client/services/drone-ci":
|
||||
switch r.Method {
|
||||
case "PUT":
|
||||
if r.FormValue("token") == "" {
|
||||
w.WriteHeader(404)
|
||||
} else {
|
||||
w.WriteHeader(201)
|
||||
}
|
||||
case "DELETE":
|
||||
w.WriteHeader(201)
|
||||
}
|
||||
|
||||
return
|
||||
case "/oauth/token":
|
||||
w.Write(accessTokenPayload)
|
||||
return
|
||||
case "/api/v3/user":
|
||||
w.Write(currentUserPayload)
|
||||
return
|
||||
}
|
||||
|
||||
// else return a 404
|
||||
http.NotFound(w, r)
|
||||
})
|
||||
|
||||
// return the server to the client which
|
||||
// will need to know the base URL path
|
||||
return server
|
||||
}
|
38
server/remote/gitlab3/testdata/users.go
vendored
38
server/remote/gitlab3/testdata/users.go
vendored
|
@ -1,38 +0,0 @@
|
|||
// Copyright 2018 Drone.IO Inc.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package testdata
|
||||
|
||||
var currentUserPayload = []byte(`
|
||||
{
|
||||
"id": 1,
|
||||
"username": "john_smith",
|
||||
"email": "john@example.com",
|
||||
"name": "John Smith",
|
||||
"private_token": "dd34asd13as",
|
||||
"state": "active",
|
||||
"created_at": "2012-05-23T08:00:58Z",
|
||||
"bio": null,
|
||||
"skype": "",
|
||||
"linkedin": "",
|
||||
"twitter": "",
|
||||
"website_url": "",
|
||||
"theme_id": 1,
|
||||
"color_scheme_id": 2,
|
||||
"is_admin": false,
|
||||
"can_create_group": true,
|
||||
"can_create_project": true,
|
||||
"projects_limit": 100
|
||||
}
|
||||
`)
|
363
vendor/github.com/hashicorp/go-cleanhttp/LICENSE
generated
vendored
Normal file
363
vendor/github.com/hashicorp/go-cleanhttp/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,363 @@
|
|||
Mozilla Public License, version 2.0
|
||||
|
||||
1. Definitions
|
||||
|
||||
1.1. "Contributor"
|
||||
|
||||
means each individual or legal entity that creates, contributes to the
|
||||
creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
|
||||
means the combination of the Contributions of others (if any) used by a
|
||||
Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
|
||||
means Source Code Form to which the initial Contributor has attached the
|
||||
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||
Modifications of such Source Code Form, in each case including portions
|
||||
thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
a. that the initial Contributor has attached the notice described in
|
||||
Exhibit B to the Covered Software; or
|
||||
|
||||
b. that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the terms of
|
||||
a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
|
||||
means a work that combines Covered Software with other material, in a
|
||||
separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
|
||||
means having the right to grant, to the maximum extent possible, whether
|
||||
at the time of the initial grant or subsequently, any and all of the
|
||||
rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
|
||||
means any of the following:
|
||||
|
||||
a. any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered Software; or
|
||||
|
||||
b. any new file in Source Code Form that contains any Covered Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the License,
|
||||
by the making, using, selling, offering for sale, having made, import,
|
||||
or transfer of either its Contributions or its Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
|
||||
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||
General Public License, Version 2.1, the GNU Affero General Public
|
||||
License, Version 3.0, or any later versions of those licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that controls, is
|
||||
controlled by, or is under common control with You. For purposes of this
|
||||
definition, "control" means (a) the power, direct or indirect, to cause
|
||||
the direction or management of such entity, whether by contract or
|
||||
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||
outstanding shares or beneficial ownership of such entity.
|
||||
|
||||
|
||||
2. License Grants and Conditions
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
a. under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||
sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
a. for any code that a Contributor has removed from Covered Software; or
|
||||
|
||||
b. for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
c. under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights to
|
||||
grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||
Section 2.1.
|
||||
|
||||
|
||||
3. Responsibilities
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
a. such Covered Software must also be made available in Source Code Form,
|
||||
as described in Section 3.1, and You must inform recipients of the
|
||||
Executable Form how they can obtain a copy of such Source Code Form by
|
||||
reasonable means in a timely manner, at a charge no more than the cost
|
||||
of distribution to the recipient; and
|
||||
|
||||
b. You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter the
|
||||
recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty, or
|
||||
limitations of liability) contained within the Source Code Form of the
|
||||
Covered Software, except that You may alter any license notices to the
|
||||
extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this License
|
||||
with respect to some or all of the Covered Software due to statute,
|
||||
judicial order, or regulation then You must: (a) comply with the terms of
|
||||
this License to the maximum extent possible; and (b) describe the
|
||||
limitations and the code they affect. Such description must be placed in a
|
||||
text file included with all distributions of the Covered Software under
|
||||
this License. Except to the extent prohibited by statute or regulation,
|
||||
such description must be sufficiently detailed for a recipient of ordinary
|
||||
skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically if You
|
||||
fail to comply with any of its terms. However, if You become compliant,
|
||||
then the rights granted under this License from a particular Contributor
|
||||
are reinstated (a) provisionally, unless and until such Contributor
|
||||
explicitly and finally terminates Your grants, and (b) on an ongoing
|
||||
basis, if such Contributor fails to notify You of the non-compliance by
|
||||
some reasonable means prior to 60 days after You have come back into
|
||||
compliance. Moreover, Your grants from a particular Contributor are
|
||||
reinstated on an ongoing basis if such Contributor notifies You of the
|
||||
non-compliance by some reasonable means, this is the first time You have
|
||||
received notice of non-compliance with this License from such
|
||||
Contributor, and You become compliant prior to 30 days after Your receipt
|
||||
of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||
license agreements (excluding distributors and resellers) which have been
|
||||
validly granted by You or Your distributors under this License prior to
|
||||
termination shall survive termination.
|
||||
|
||||
6. Disclaimer of Warranty
|
||||
|
||||
Covered Software is provided under this License on an "as is" basis,
|
||||
without warranty of any kind, either expressed, implied, or statutory,
|
||||
including, without limitation, warranties that the Covered Software is free
|
||||
of defects, merchantable, fit for a particular purpose or non-infringing.
|
||||
The entire risk as to the quality and performance of the Covered Software
|
||||
is with You. Should any Covered Software prove defective in any respect,
|
||||
You (not any Contributor) assume the cost of any necessary servicing,
|
||||
repair, or correction. This disclaimer of warranty constitutes an essential
|
||||
part of this License. No use of any Covered Software is authorized under
|
||||
this License except under this disclaimer.
|
||||
|
||||
7. Limitation of Liability
|
||||
|
||||
Under no circumstances and under no legal theory, whether tort (including
|
||||
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||
distributes Covered Software as permitted above, be liable to You for any
|
||||
direct, indirect, special, incidental, or consequential damages of any
|
||||
character including, without limitation, damages for lost profits, loss of
|
||||
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses, even if such party shall have been
|
||||
informed of the possibility of such damages. This limitation of liability
|
||||
shall not apply to liability for death or personal injury resulting from
|
||||
such party's negligence to the extent applicable law prohibits such
|
||||
limitation. Some jurisdictions do not allow the exclusion or limitation of
|
||||
incidental or consequential damages, so this exclusion and limitation may
|
||||
not apply to You.
|
||||
|
||||
8. Litigation
|
||||
|
||||
Any litigation relating to this License may be brought only in the courts
|
||||
of a jurisdiction where the defendant maintains its principal place of
|
||||
business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions. Nothing
|
||||
in this Section shall prevent a party's ability to bring cross-claims or
|
||||
counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides that
|
||||
the language of a contract shall be construed against the drafter shall not
|
||||
be used to construe this License against a Contributor.
|
||||
|
||||
|
||||
10. Versions of the License
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses If You choose to distribute Source Code Form that is
|
||||
Incompatible With Secondary Licenses under the terms of this version of
|
||||
the License, the notice described in Exhibit B of this License must be
|
||||
attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file,
|
||||
then You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a
|
||||
notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
|
||||
This Source Code Form is "Incompatible
|
||||
With Secondary Licenses", as defined by
|
||||
the Mozilla Public License, v. 2.0.
|
||||
|
30
vendor/github.com/hashicorp/go-cleanhttp/README.md
generated
vendored
Normal file
30
vendor/github.com/hashicorp/go-cleanhttp/README.md
generated
vendored
Normal file
|
@ -0,0 +1,30 @@
|
|||
# cleanhttp
|
||||
|
||||
Functions for accessing "clean" Go http.Client values
|
||||
|
||||
-------------
|
||||
|
||||
The Go standard library contains a default `http.Client` called
|
||||
`http.DefaultClient`. It is a common idiom in Go code to start with
|
||||
`http.DefaultClient` and tweak it as necessary, and in fact, this is
|
||||
encouraged; from the `http` package documentation:
|
||||
|
||||
> The Client's Transport typically has internal state (cached TCP connections),
|
||||
so Clients should be reused instead of created as needed. Clients are safe for
|
||||
concurrent use by multiple goroutines.
|
||||
|
||||
Unfortunately, this is a shared value, and it is not uncommon for libraries to
|
||||
assume that they are free to modify it at will. With enough dependencies, it
|
||||
can be very easy to encounter strange problems and race conditions due to
|
||||
manipulation of this shared value across libraries and goroutines (clients are
|
||||
safe for concurrent use, but writing values to the client struct itself is not
|
||||
protected).
|
||||
|
||||
Making things worse is the fact that a bare `http.Client` will use a default
|
||||
`http.Transport` called `http.DefaultTransport`, which is another global value
|
||||
that behaves the same way. So it is not simply enough to replace
|
||||
`http.DefaultClient` with `&http.Client{}`.
|
||||
|
||||
This repository provides some simple functions to get a "clean" `http.Client`
|
||||
-- one that uses the same default values as the Go standard library, but
|
||||
returns a client that does not share any state with other clients.
|
57
vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go
generated
vendored
Normal file
57
vendor/github.com/hashicorp/go-cleanhttp/cleanhttp.go
generated
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
package cleanhttp
|
||||
|
||||
import (
|
||||
"net"
|
||||
"net/http"
|
||||
"runtime"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DefaultTransport returns a new http.Transport with similar default values to
|
||||
// http.DefaultTransport, but with idle connections and keepalives disabled.
|
||||
func DefaultTransport() *http.Transport {
|
||||
transport := DefaultPooledTransport()
|
||||
transport.DisableKeepAlives = true
|
||||
transport.MaxIdleConnsPerHost = -1
|
||||
return transport
|
||||
}
|
||||
|
||||
// DefaultPooledTransport returns a new http.Transport with similar default
|
||||
// values to http.DefaultTransport. Do not use this for transient transports as
|
||||
// it can leak file descriptors over time. Only use this for transports that
|
||||
// will be re-used for the same host(s).
|
||||
func DefaultPooledTransport() *http.Transport {
|
||||
transport := &http.Transport{
|
||||
Proxy: http.ProxyFromEnvironment,
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 30 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
DualStack: true,
|
||||
}).DialContext,
|
||||
MaxIdleConns: 100,
|
||||
IdleConnTimeout: 90 * time.Second,
|
||||
TLSHandshakeTimeout: 10 * time.Second,
|
||||
ExpectContinueTimeout: 1 * time.Second,
|
||||
MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1,
|
||||
}
|
||||
return transport
|
||||
}
|
||||
|
||||
// DefaultClient returns a new http.Client with similar default values to
|
||||
// http.Client, but with a non-shared Transport, idle connections disabled, and
|
||||
// keepalives disabled.
|
||||
func DefaultClient() *http.Client {
|
||||
return &http.Client{
|
||||
Transport: DefaultTransport(),
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultPooledClient returns a new http.Client with similar default values to
|
||||
// http.Client, but with a shared Transport. Do not use this function for
|
||||
// transient clients as it can leak file descriptors over time. Only use this
|
||||
// for clients that will be re-used for the same host(s).
|
||||
func DefaultPooledClient() *http.Client {
|
||||
return &http.Client{
|
||||
Transport: DefaultPooledTransport(),
|
||||
}
|
||||
}
|
20
vendor/github.com/hashicorp/go-cleanhttp/doc.go
generated
vendored
Normal file
20
vendor/github.com/hashicorp/go-cleanhttp/doc.go
generated
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
// Package cleanhttp offers convenience utilities for acquiring "clean"
|
||||
// http.Transport and http.Client structs.
|
||||
//
|
||||
// Values set on http.DefaultClient and http.DefaultTransport affect all
|
||||
// callers. This can have detrimental effects, esepcially in TLS contexts,
|
||||
// where client or root certificates set to talk to multiple endpoints can end
|
||||
// up displacing each other, leading to hard-to-debug issues. This package
|
||||
// provides non-shared http.Client and http.Transport structs to ensure that
|
||||
// the configuration will not be overwritten by other parts of the application
|
||||
// or dependencies.
|
||||
//
|
||||
// The DefaultClient and DefaultTransport functions disable idle connections
|
||||
// and keepalives. Without ensuring that idle connections are closed before
|
||||
// garbage collection, short-term clients/transports can leak file descriptors,
|
||||
// eventually leading to "too many open files" errors. If you will be
|
||||
// connecting to the same hosts repeatedly from the same client, you can use
|
||||
// DefaultPooledClient to receive a client that has connection pooling
|
||||
// semantics similar to http.DefaultClient.
|
||||
//
|
||||
package cleanhttp
|
1
vendor/github.com/hashicorp/go-cleanhttp/go.mod
generated
vendored
Normal file
1
vendor/github.com/hashicorp/go-cleanhttp/go.mod
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
module github.com/hashicorp/go-cleanhttp
|
48
vendor/github.com/hashicorp/go-cleanhttp/handlers.go
generated
vendored
Normal file
48
vendor/github.com/hashicorp/go-cleanhttp/handlers.go
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
package cleanhttp
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// HandlerInput provides input options to cleanhttp's handlers
|
||||
type HandlerInput struct {
|
||||
ErrStatus int
|
||||
}
|
||||
|
||||
// PrintablePathCheckHandler is a middleware that ensures the request path
|
||||
// contains only printable runes.
|
||||
func PrintablePathCheckHandler(next http.Handler, input *HandlerInput) http.Handler {
|
||||
// Nil-check on input to make it optional
|
||||
if input == nil {
|
||||
input = &HandlerInput{
|
||||
ErrStatus: http.StatusBadRequest,
|
||||
}
|
||||
}
|
||||
|
||||
// Default to http.StatusBadRequest on error
|
||||
if input.ErrStatus == 0 {
|
||||
input.ErrStatus = http.StatusBadRequest
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if r != nil {
|
||||
// Check URL path for non-printable characters
|
||||
idx := strings.IndexFunc(r.URL.Path, func(c rune) bool {
|
||||
return !unicode.IsPrint(c)
|
||||
})
|
||||
|
||||
if idx != -1 {
|
||||
w.WriteHeader(input.ErrStatus)
|
||||
return
|
||||
}
|
||||
|
||||
if next != nil {
|
||||
next.ServeHTTP(w, r)
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
})
|
||||
}
|
4
vendor/github.com/hashicorp/go-retryablehttp/.gitignore
generated
vendored
Normal file
4
vendor/github.com/hashicorp/go-retryablehttp/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
.idea/
|
||||
*.iml
|
||||
*.test
|
||||
.vscode/
|
363
vendor/github.com/hashicorp/go-retryablehttp/LICENSE
generated
vendored
Normal file
363
vendor/github.com/hashicorp/go-retryablehttp/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,363 @@
|
|||
Mozilla Public License, version 2.0
|
||||
|
||||
1. Definitions
|
||||
|
||||
1.1. "Contributor"
|
||||
|
||||
means each individual or legal entity that creates, contributes to the
|
||||
creation of, or owns Covered Software.
|
||||
|
||||
1.2. "Contributor Version"
|
||||
|
||||
means the combination of the Contributions of others (if any) used by a
|
||||
Contributor and that particular Contributor's Contribution.
|
||||
|
||||
1.3. "Contribution"
|
||||
|
||||
means Covered Software of a particular Contributor.
|
||||
|
||||
1.4. "Covered Software"
|
||||
|
||||
means Source Code Form to which the initial Contributor has attached the
|
||||
notice in Exhibit A, the Executable Form of such Source Code Form, and
|
||||
Modifications of such Source Code Form, in each case including portions
|
||||
thereof.
|
||||
|
||||
1.5. "Incompatible With Secondary Licenses"
|
||||
means
|
||||
|
||||
a. that the initial Contributor has attached the notice described in
|
||||
Exhibit B to the Covered Software; or
|
||||
|
||||
b. that the Covered Software was made available under the terms of
|
||||
version 1.1 or earlier of the License, but not also under the terms of
|
||||
a Secondary License.
|
||||
|
||||
1.6. "Executable Form"
|
||||
|
||||
means any form of the work other than Source Code Form.
|
||||
|
||||
1.7. "Larger Work"
|
||||
|
||||
means a work that combines Covered Software with other material, in a
|
||||
separate file or files, that is not Covered Software.
|
||||
|
||||
1.8. "License"
|
||||
|
||||
means this document.
|
||||
|
||||
1.9. "Licensable"
|
||||
|
||||
means having the right to grant, to the maximum extent possible, whether
|
||||
at the time of the initial grant or subsequently, any and all of the
|
||||
rights conveyed by this License.
|
||||
|
||||
1.10. "Modifications"
|
||||
|
||||
means any of the following:
|
||||
|
||||
a. any file in Source Code Form that results from an addition to,
|
||||
deletion from, or modification of the contents of Covered Software; or
|
||||
|
||||
b. any new file in Source Code Form that contains any Covered Software.
|
||||
|
||||
1.11. "Patent Claims" of a Contributor
|
||||
|
||||
means any patent claim(s), including without limitation, method,
|
||||
process, and apparatus claims, in any patent Licensable by such
|
||||
Contributor that would be infringed, but for the grant of the License,
|
||||
by the making, using, selling, offering for sale, having made, import,
|
||||
or transfer of either its Contributions or its Contributor Version.
|
||||
|
||||
1.12. "Secondary License"
|
||||
|
||||
means either the GNU General Public License, Version 2.0, the GNU Lesser
|
||||
General Public License, Version 2.1, the GNU Affero General Public
|
||||
License, Version 3.0, or any later versions of those licenses.
|
||||
|
||||
1.13. "Source Code Form"
|
||||
|
||||
means the form of the work preferred for making modifications.
|
||||
|
||||
1.14. "You" (or "Your")
|
||||
|
||||
means an individual or a legal entity exercising rights under this
|
||||
License. For legal entities, "You" includes any entity that controls, is
|
||||
controlled by, or is under common control with You. For purposes of this
|
||||
definition, "control" means (a) the power, direct or indirect, to cause
|
||||
the direction or management of such entity, whether by contract or
|
||||
otherwise, or (b) ownership of more than fifty percent (50%) of the
|
||||
outstanding shares or beneficial ownership of such entity.
|
||||
|
||||
|
||||
2. License Grants and Conditions
|
||||
|
||||
2.1. Grants
|
||||
|
||||
Each Contributor hereby grants You a world-wide, royalty-free,
|
||||
non-exclusive license:
|
||||
|
||||
a. under intellectual property rights (other than patent or trademark)
|
||||
Licensable by such Contributor to use, reproduce, make available,
|
||||
modify, display, perform, distribute, and otherwise exploit its
|
||||
Contributions, either on an unmodified basis, with Modifications, or
|
||||
as part of a Larger Work; and
|
||||
|
||||
b. under Patent Claims of such Contributor to make, use, sell, offer for
|
||||
sale, have made, import, and otherwise transfer either its
|
||||
Contributions or its Contributor Version.
|
||||
|
||||
2.2. Effective Date
|
||||
|
||||
The licenses granted in Section 2.1 with respect to any Contribution
|
||||
become effective for each Contribution on the date the Contributor first
|
||||
distributes such Contribution.
|
||||
|
||||
2.3. Limitations on Grant Scope
|
||||
|
||||
The licenses granted in this Section 2 are the only rights granted under
|
||||
this License. No additional rights or licenses will be implied from the
|
||||
distribution or licensing of Covered Software under this License.
|
||||
Notwithstanding Section 2.1(b) above, no patent license is granted by a
|
||||
Contributor:
|
||||
|
||||
a. for any code that a Contributor has removed from Covered Software; or
|
||||
|
||||
b. for infringements caused by: (i) Your and any other third party's
|
||||
modifications of Covered Software, or (ii) the combination of its
|
||||
Contributions with other software (except as part of its Contributor
|
||||
Version); or
|
||||
|
||||
c. under Patent Claims infringed by Covered Software in the absence of
|
||||
its Contributions.
|
||||
|
||||
This License does not grant any rights in the trademarks, service marks,
|
||||
or logos of any Contributor (except as may be necessary to comply with
|
||||
the notice requirements in Section 3.4).
|
||||
|
||||
2.4. Subsequent Licenses
|
||||
|
||||
No Contributor makes additional grants as a result of Your choice to
|
||||
distribute the Covered Software under a subsequent version of this
|
||||
License (see Section 10.2) or under the terms of a Secondary License (if
|
||||
permitted under the terms of Section 3.3).
|
||||
|
||||
2.5. Representation
|
||||
|
||||
Each Contributor represents that the Contributor believes its
|
||||
Contributions are its original creation(s) or it has sufficient rights to
|
||||
grant the rights to its Contributions conveyed by this License.
|
||||
|
||||
2.6. Fair Use
|
||||
|
||||
This License is not intended to limit any rights You have under
|
||||
applicable copyright doctrines of fair use, fair dealing, or other
|
||||
equivalents.
|
||||
|
||||
2.7. Conditions
|
||||
|
||||
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted in
|
||||
Section 2.1.
|
||||
|
||||
|
||||
3. Responsibilities
|
||||
|
||||
3.1. Distribution of Source Form
|
||||
|
||||
All distribution of Covered Software in Source Code Form, including any
|
||||
Modifications that You create or to which You contribute, must be under
|
||||
the terms of this License. You must inform recipients that the Source
|
||||
Code Form of the Covered Software is governed by the terms of this
|
||||
License, and how they can obtain a copy of this License. You may not
|
||||
attempt to alter or restrict the recipients' rights in the Source Code
|
||||
Form.
|
||||
|
||||
3.2. Distribution of Executable Form
|
||||
|
||||
If You distribute Covered Software in Executable Form then:
|
||||
|
||||
a. such Covered Software must also be made available in Source Code Form,
|
||||
as described in Section 3.1, and You must inform recipients of the
|
||||
Executable Form how they can obtain a copy of such Source Code Form by
|
||||
reasonable means in a timely manner, at a charge no more than the cost
|
||||
of distribution to the recipient; and
|
||||
|
||||
b. You may distribute such Executable Form under the terms of this
|
||||
License, or sublicense it under different terms, provided that the
|
||||
license for the Executable Form does not attempt to limit or alter the
|
||||
recipients' rights in the Source Code Form under this License.
|
||||
|
||||
3.3. Distribution of a Larger Work
|
||||
|
||||
You may create and distribute a Larger Work under terms of Your choice,
|
||||
provided that You also comply with the requirements of this License for
|
||||
the Covered Software. If the Larger Work is a combination of Covered
|
||||
Software with a work governed by one or more Secondary Licenses, and the
|
||||
Covered Software is not Incompatible With Secondary Licenses, this
|
||||
License permits You to additionally distribute such Covered Software
|
||||
under the terms of such Secondary License(s), so that the recipient of
|
||||
the Larger Work may, at their option, further distribute the Covered
|
||||
Software under the terms of either this License or such Secondary
|
||||
License(s).
|
||||
|
||||
3.4. Notices
|
||||
|
||||
You may not remove or alter the substance of any license notices
|
||||
(including copyright notices, patent notices, disclaimers of warranty, or
|
||||
limitations of liability) contained within the Source Code Form of the
|
||||
Covered Software, except that You may alter any license notices to the
|
||||
extent required to remedy known factual inaccuracies.
|
||||
|
||||
3.5. Application of Additional Terms
|
||||
|
||||
You may choose to offer, and to charge a fee for, warranty, support,
|
||||
indemnity or liability obligations to one or more recipients of Covered
|
||||
Software. However, You may do so only on Your own behalf, and not on
|
||||
behalf of any Contributor. You must make it absolutely clear that any
|
||||
such warranty, support, indemnity, or liability obligation is offered by
|
||||
You alone, and You hereby agree to indemnify every Contributor for any
|
||||
liability incurred by such Contributor as a result of warranty, support,
|
||||
indemnity or liability terms You offer. You may include additional
|
||||
disclaimers of warranty and limitations of liability specific to any
|
||||
jurisdiction.
|
||||
|
||||
4. Inability to Comply Due to Statute or Regulation
|
||||
|
||||
If it is impossible for You to comply with any of the terms of this License
|
||||
with respect to some or all of the Covered Software due to statute,
|
||||
judicial order, or regulation then You must: (a) comply with the terms of
|
||||
this License to the maximum extent possible; and (b) describe the
|
||||
limitations and the code they affect. Such description must be placed in a
|
||||
text file included with all distributions of the Covered Software under
|
||||
this License. Except to the extent prohibited by statute or regulation,
|
||||
such description must be sufficiently detailed for a recipient of ordinary
|
||||
skill to be able to understand it.
|
||||
|
||||
5. Termination
|
||||
|
||||
5.1. The rights granted under this License will terminate automatically if You
|
||||
fail to comply with any of its terms. However, if You become compliant,
|
||||
then the rights granted under this License from a particular Contributor
|
||||
are reinstated (a) provisionally, unless and until such Contributor
|
||||
explicitly and finally terminates Your grants, and (b) on an ongoing
|
||||
basis, if such Contributor fails to notify You of the non-compliance by
|
||||
some reasonable means prior to 60 days after You have come back into
|
||||
compliance. Moreover, Your grants from a particular Contributor are
|
||||
reinstated on an ongoing basis if such Contributor notifies You of the
|
||||
non-compliance by some reasonable means, this is the first time You have
|
||||
received notice of non-compliance with this License from such
|
||||
Contributor, and You become compliant prior to 30 days after Your receipt
|
||||
of the notice.
|
||||
|
||||
5.2. If You initiate litigation against any entity by asserting a patent
|
||||
infringement claim (excluding declaratory judgment actions,
|
||||
counter-claims, and cross-claims) alleging that a Contributor Version
|
||||
directly or indirectly infringes any patent, then the rights granted to
|
||||
You by any and all Contributors for the Covered Software under Section
|
||||
2.1 of this License shall terminate.
|
||||
|
||||
5.3. In the event of termination under Sections 5.1 or 5.2 above, all end user
|
||||
license agreements (excluding distributors and resellers) which have been
|
||||
validly granted by You or Your distributors under this License prior to
|
||||
termination shall survive termination.
|
||||
|
||||
6. Disclaimer of Warranty
|
||||
|
||||
Covered Software is provided under this License on an "as is" basis,
|
||||
without warranty of any kind, either expressed, implied, or statutory,
|
||||
including, without limitation, warranties that the Covered Software is free
|
||||
of defects, merchantable, fit for a particular purpose or non-infringing.
|
||||
The entire risk as to the quality and performance of the Covered Software
|
||||
is with You. Should any Covered Software prove defective in any respect,
|
||||
You (not any Contributor) assume the cost of any necessary servicing,
|
||||
repair, or correction. This disclaimer of warranty constitutes an essential
|
||||
part of this License. No use of any Covered Software is authorized under
|
||||
this License except under this disclaimer.
|
||||
|
||||
7. Limitation of Liability
|
||||
|
||||
Under no circumstances and under no legal theory, whether tort (including
|
||||
negligence), contract, or otherwise, shall any Contributor, or anyone who
|
||||
distributes Covered Software as permitted above, be liable to You for any
|
||||
direct, indirect, special, incidental, or consequential damages of any
|
||||
character including, without limitation, damages for lost profits, loss of
|
||||
goodwill, work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses, even if such party shall have been
|
||||
informed of the possibility of such damages. This limitation of liability
|
||||
shall not apply to liability for death or personal injury resulting from
|
||||
such party's negligence to the extent applicable law prohibits such
|
||||
limitation. Some jurisdictions do not allow the exclusion or limitation of
|
||||
incidental or consequential damages, so this exclusion and limitation may
|
||||
not apply to You.
|
||||
|
||||
8. Litigation
|
||||
|
||||
Any litigation relating to this License may be brought only in the courts
|
||||
of a jurisdiction where the defendant maintains its principal place of
|
||||
business and such litigation shall be governed by laws of that
|
||||
jurisdiction, without reference to its conflict-of-law provisions. Nothing
|
||||
in this Section shall prevent a party's ability to bring cross-claims or
|
||||
counter-claims.
|
||||
|
||||
9. Miscellaneous
|
||||
|
||||
This License represents the complete agreement concerning the subject
|
||||
matter hereof. If any provision of this License is held to be
|
||||
unenforceable, such provision shall be reformed only to the extent
|
||||
necessary to make it enforceable. Any law or regulation which provides that
|
||||
the language of a contract shall be construed against the drafter shall not
|
||||
be used to construe this License against a Contributor.
|
||||
|
||||
|
||||
10. Versions of the License
|
||||
|
||||
10.1. New Versions
|
||||
|
||||
Mozilla Foundation is the license steward. Except as provided in Section
|
||||
10.3, no one other than the license steward has the right to modify or
|
||||
publish new versions of this License. Each version will be given a
|
||||
distinguishing version number.
|
||||
|
||||
10.2. Effect of New Versions
|
||||
|
||||
You may distribute the Covered Software under the terms of the version
|
||||
of the License under which You originally received the Covered Software,
|
||||
or under the terms of any subsequent version published by the license
|
||||
steward.
|
||||
|
||||
10.3. Modified Versions
|
||||
|
||||
If you create software not governed by this License, and you want to
|
||||
create a new license for such software, you may create and use a
|
||||
modified version of this License if you rename the license and remove
|
||||
any references to the name of the license steward (except to note that
|
||||
such modified license differs from this License).
|
||||
|
||||
10.4. Distributing Source Code Form that is Incompatible With Secondary
|
||||
Licenses If You choose to distribute Source Code Form that is
|
||||
Incompatible With Secondary Licenses under the terms of this version of
|
||||
the License, the notice described in Exhibit B of this License must be
|
||||
attached.
|
||||
|
||||
Exhibit A - Source Code Form License Notice
|
||||
|
||||
This Source Code Form is subject to the
|
||||
terms of the Mozilla Public License, v.
|
||||
2.0. If a copy of the MPL was not
|
||||
distributed with this file, You can
|
||||
obtain one at
|
||||
http://mozilla.org/MPL/2.0/.
|
||||
|
||||
If it is not possible or desirable to put the notice in a particular file,
|
||||
then You may include the notice in a location (such as a LICENSE file in a
|
||||
relevant directory) where a recipient would be likely to look for such a
|
||||
notice.
|
||||
|
||||
You may add additional accurate notices of copyright ownership.
|
||||
|
||||
Exhibit B - "Incompatible With Secondary Licenses" Notice
|
||||
|
||||
This Source Code Form is "Incompatible
|
||||
With Secondary Licenses", as defined by
|
||||
the Mozilla Public License, v. 2.0.
|
||||
|
11
vendor/github.com/hashicorp/go-retryablehttp/Makefile
generated
vendored
Normal file
11
vendor/github.com/hashicorp/go-retryablehttp/Makefile
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
default: test
|
||||
|
||||
test:
|
||||
go vet ./...
|
||||
go test -race ./...
|
||||
|
||||
updatedeps:
|
||||
go get -f -t -u ./...
|
||||
go get -f -u ./...
|
||||
|
||||
.PHONY: default test updatedeps
|
62
vendor/github.com/hashicorp/go-retryablehttp/README.md
generated
vendored
Normal file
62
vendor/github.com/hashicorp/go-retryablehttp/README.md
generated
vendored
Normal file
|
@ -0,0 +1,62 @@
|
|||
go-retryablehttp
|
||||
================
|
||||
|
||||
[![Build Status](http://img.shields.io/travis/hashicorp/go-retryablehttp.svg?style=flat-square)][travis]
|
||||
[![Go Documentation](http://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)][godocs]
|
||||
|
||||
[travis]: http://travis-ci.org/hashicorp/go-retryablehttp
|
||||
[godocs]: http://godoc.org/github.com/hashicorp/go-retryablehttp
|
||||
|
||||
The `retryablehttp` package provides a familiar HTTP client interface with
|
||||
automatic retries and exponential backoff. It is a thin wrapper over the
|
||||
standard `net/http` client library and exposes nearly the same public API. This
|
||||
makes `retryablehttp` very easy to drop into existing programs.
|
||||
|
||||
`retryablehttp` performs automatic retries under certain conditions. Mainly, if
|
||||
an error is returned by the client (connection errors, etc.), or if a 500-range
|
||||
response code is received (except 501), then a retry is invoked after a wait
|
||||
period. Otherwise, the response is returned and left to the caller to
|
||||
interpret.
|
||||
|
||||
The main difference from `net/http` is that requests which take a request body
|
||||
(POST/PUT et. al) can have the body provided in a number of ways (some more or
|
||||
less efficient) that allow "rewinding" the request body if the initial request
|
||||
fails so that the full request can be attempted again. See the
|
||||
[godoc](http://godoc.org/github.com/hashicorp/go-retryablehttp) for more
|
||||
details.
|
||||
|
||||
Version 0.6.0 and before are compatible with Go prior to 1.12. From 0.6.1 onward, Go 1.12+ is required.
|
||||
From 0.6.7 onward, Go 1.13+ is required.
|
||||
|
||||
Example Use
|
||||
===========
|
||||
|
||||
Using this library should look almost identical to what you would do with
|
||||
`net/http`. The most simple example of a GET request is shown below:
|
||||
|
||||
```go
|
||||
resp, err := retryablehttp.Get("/foo")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
```
|
||||
|
||||
The returned response object is an `*http.Response`, the same thing you would
|
||||
usually get from `net/http`. Had the request failed one or more times, the above
|
||||
call would block and retry with exponential backoff.
|
||||
|
||||
## Getting a stdlib `*http.Client` with retries
|
||||
|
||||
It's possible to convert a `*retryablehttp.Client` directly to a `*http.Client`.
|
||||
This makes use of retryablehttp broadly applicable with minimal effort. Simply
|
||||
configure a `*retryablehttp.Client` as you wish, and then call `StandardClient()`:
|
||||
|
||||
```go
|
||||
retryClient := retryablehttp.NewClient()
|
||||
retryClient.RetryMax = 10
|
||||
|
||||
standardClient := retryClient.StandardClient() // *http.Client
|
||||
```
|
||||
|
||||
For more usage and examples see the
|
||||
[godoc](http://godoc.org/github.com/hashicorp/go-retryablehttp).
|
774
vendor/github.com/hashicorp/go-retryablehttp/client.go
generated
vendored
Normal file
774
vendor/github.com/hashicorp/go-retryablehttp/client.go
generated
vendored
Normal file
|
@ -0,0 +1,774 @@
|
|||
// Package retryablehttp provides a familiar HTTP client interface with
|
||||
// automatic retries and exponential backoff. It is a thin wrapper over the
|
||||
// standard net/http client library and exposes nearly the same public API.
|
||||
// This makes retryablehttp very easy to drop into existing programs.
|
||||
//
|
||||
// retryablehttp performs automatic retries under certain conditions. Mainly, if
|
||||
// an error is returned by the client (connection errors etc), or if a 500-range
|
||||
// response is received, then a retry is invoked. Otherwise, the response is
|
||||
// returned and left to the caller to interpret.
|
||||
//
|
||||
// Requests which take a request body should provide a non-nil function
|
||||
// parameter. The best choice is to provide either a function satisfying
|
||||
// ReaderFunc which provides multiple io.Readers in an efficient manner, a
|
||||
// *bytes.Buffer (the underlying raw byte slice will be used) or a raw byte
|
||||
// slice. As it is a reference type, and we will wrap it as needed by readers,
|
||||
// we can efficiently re-use the request body without needing to copy it. If an
|
||||
// io.Reader (such as a *bytes.Reader) is provided, the full body will be read
|
||||
// prior to the first request, and will be efficiently re-used for any retries.
|
||||
// ReadSeeker can be used, but some users have observed occasional data races
|
||||
// between the net/http library and the Seek functionality of some
|
||||
// implementations of ReadSeeker, so should be avoided if possible.
|
||||
package retryablehttp
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/x509"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"math"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"os"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
cleanhttp "github.com/hashicorp/go-cleanhttp"
|
||||
)
|
||||
|
||||
var (
|
||||
// Default retry configuration
|
||||
defaultRetryWaitMin = 1 * time.Second
|
||||
defaultRetryWaitMax = 30 * time.Second
|
||||
defaultRetryMax = 4
|
||||
|
||||
// defaultLogger is the logger provided with defaultClient
|
||||
defaultLogger = log.New(os.Stderr, "", log.LstdFlags)
|
||||
|
||||
// defaultClient is used for performing requests without explicitly making
|
||||
// a new client. It is purposely private to avoid modifications.
|
||||
defaultClient = NewClient()
|
||||
|
||||
// We need to consume response bodies to maintain http connections, but
|
||||
// limit the size we consume to respReadLimit.
|
||||
respReadLimit = int64(4096)
|
||||
|
||||
// A regular expression to match the error returned by net/http when the
|
||||
// configured number of redirects is exhausted. This error isn't typed
|
||||
// specifically so we resort to matching on the error string.
|
||||
redirectsErrorRe = regexp.MustCompile(`stopped after \d+ redirects\z`)
|
||||
|
||||
// A regular expression to match the error returned by net/http when the
|
||||
// scheme specified in the URL is invalid. This error isn't typed
|
||||
// specifically so we resort to matching on the error string.
|
||||
schemeErrorRe = regexp.MustCompile(`unsupported protocol scheme`)
|
||||
)
|
||||
|
||||
// ReaderFunc is the type of function that can be given natively to NewRequest
|
||||
type ReaderFunc func() (io.Reader, error)
|
||||
|
||||
// LenReader is an interface implemented by many in-memory io.Reader's. Used
|
||||
// for automatically sending the right Content-Length header when possible.
|
||||
type LenReader interface {
|
||||
Len() int
|
||||
}
|
||||
|
||||
// Request wraps the metadata needed to create HTTP requests.
|
||||
type Request struct {
|
||||
// body is a seekable reader over the request body payload. This is
|
||||
// used to rewind the request data in between retries.
|
||||
body ReaderFunc
|
||||
|
||||
// Embed an HTTP request directly. This makes a *Request act exactly
|
||||
// like an *http.Request so that all meta methods are supported.
|
||||
*http.Request
|
||||
}
|
||||
|
||||
// WithContext returns wrapped Request with a shallow copy of underlying *http.Request
|
||||
// with its context changed to ctx. The provided ctx must be non-nil.
|
||||
func (r *Request) WithContext(ctx context.Context) *Request {
|
||||
r.Request = r.Request.WithContext(ctx)
|
||||
return r
|
||||
}
|
||||
|
||||
// BodyBytes allows accessing the request body. It is an analogue to
|
||||
// http.Request's Body variable, but it returns a copy of the underlying data
|
||||
// rather than consuming it.
|
||||
//
|
||||
// This function is not thread-safe; do not call it at the same time as another
|
||||
// call, or at the same time this request is being used with Client.Do.
|
||||
func (r *Request) BodyBytes() ([]byte, error) {
|
||||
if r.body == nil {
|
||||
return nil, nil
|
||||
}
|
||||
body, err := r.body()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
buf := new(bytes.Buffer)
|
||||
_, err = buf.ReadFrom(body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
// SetBody allows setting the request body.
|
||||
//
|
||||
// It is useful if a new body needs to be set without constructing a new Request.
|
||||
func (r *Request) SetBody(rawBody interface{}) error {
|
||||
bodyReader, contentLength, err := getBodyReaderAndContentLength(rawBody)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
r.body = bodyReader
|
||||
r.ContentLength = contentLength
|
||||
return nil
|
||||
}
|
||||
|
||||
// WriteTo allows copying the request body into a writer.
|
||||
//
|
||||
// It writes data to w until there's no more data to write or
|
||||
// when an error occurs. The return int64 value is the number of bytes
|
||||
// written. Any error encountered during the write is also returned.
|
||||
// The signature matches io.WriterTo interface.
|
||||
func (r *Request) WriteTo(w io.Writer) (int64, error) {
|
||||
body, err := r.body()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if c, ok := body.(io.Closer); ok {
|
||||
defer c.Close()
|
||||
}
|
||||
return io.Copy(w, body)
|
||||
}
|
||||
|
||||
func getBodyReaderAndContentLength(rawBody interface{}) (ReaderFunc, int64, error) {
|
||||
var bodyReader ReaderFunc
|
||||
var contentLength int64
|
||||
|
||||
switch body := rawBody.(type) {
|
||||
// If they gave us a function already, great! Use it.
|
||||
case ReaderFunc:
|
||||
bodyReader = body
|
||||
tmp, err := body()
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
if lr, ok := tmp.(LenReader); ok {
|
||||
contentLength = int64(lr.Len())
|
||||
}
|
||||
if c, ok := tmp.(io.Closer); ok {
|
||||
c.Close()
|
||||
}
|
||||
|
||||
case func() (io.Reader, error):
|
||||
bodyReader = body
|
||||
tmp, err := body()
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
if lr, ok := tmp.(LenReader); ok {
|
||||
contentLength = int64(lr.Len())
|
||||
}
|
||||
if c, ok := tmp.(io.Closer); ok {
|
||||
c.Close()
|
||||
}
|
||||
|
||||
// If a regular byte slice, we can read it over and over via new
|
||||
// readers
|
||||
case []byte:
|
||||
buf := body
|
||||
bodyReader = func() (io.Reader, error) {
|
||||
return bytes.NewReader(buf), nil
|
||||
}
|
||||
contentLength = int64(len(buf))
|
||||
|
||||
// If a bytes.Buffer we can read the underlying byte slice over and
|
||||
// over
|
||||
case *bytes.Buffer:
|
||||
buf := body
|
||||
bodyReader = func() (io.Reader, error) {
|
||||
return bytes.NewReader(buf.Bytes()), nil
|
||||
}
|
||||
contentLength = int64(buf.Len())
|
||||
|
||||
// We prioritize *bytes.Reader here because we don't really want to
|
||||
// deal with it seeking so want it to match here instead of the
|
||||
// io.ReadSeeker case.
|
||||
case *bytes.Reader:
|
||||
buf, err := ioutil.ReadAll(body)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
bodyReader = func() (io.Reader, error) {
|
||||
return bytes.NewReader(buf), nil
|
||||
}
|
||||
contentLength = int64(len(buf))
|
||||
|
||||
// Compat case
|
||||
case io.ReadSeeker:
|
||||
raw := body
|
||||
bodyReader = func() (io.Reader, error) {
|
||||
_, err := raw.Seek(0, 0)
|
||||
return ioutil.NopCloser(raw), err
|
||||
}
|
||||
if lr, ok := raw.(LenReader); ok {
|
||||
contentLength = int64(lr.Len())
|
||||
}
|
||||
|
||||
// Read all in so we can reset
|
||||
case io.Reader:
|
||||
buf, err := ioutil.ReadAll(body)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
bodyReader = func() (io.Reader, error) {
|
||||
return bytes.NewReader(buf), nil
|
||||
}
|
||||
contentLength = int64(len(buf))
|
||||
|
||||
// No body provided, nothing to do
|
||||
case nil:
|
||||
|
||||
// Unrecognized type
|
||||
default:
|
||||
return nil, 0, fmt.Errorf("cannot handle type %T", rawBody)
|
||||
}
|
||||
return bodyReader, contentLength, nil
|
||||
}
|
||||
|
||||
// FromRequest wraps an http.Request in a retryablehttp.Request
|
||||
func FromRequest(r *http.Request) (*Request, error) {
|
||||
bodyReader, _, err := getBodyReaderAndContentLength(r.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Could assert contentLength == r.ContentLength
|
||||
return &Request{bodyReader, r}, nil
|
||||
}
|
||||
|
||||
// NewRequest creates a new wrapped request.
|
||||
func NewRequest(method, url string, rawBody interface{}) (*Request, error) {
|
||||
bodyReader, contentLength, err := getBodyReaderAndContentLength(rawBody)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
httpReq, err := http.NewRequest(method, url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
httpReq.ContentLength = contentLength
|
||||
|
||||
return &Request{bodyReader, httpReq}, nil
|
||||
}
|
||||
|
||||
// Logger interface allows to use other loggers than
|
||||
// standard log.Logger.
|
||||
type Logger interface {
|
||||
Printf(string, ...interface{})
|
||||
}
|
||||
|
||||
// LeveledLogger is an interface that can be implemented by any logger or a
|
||||
// logger wrapper to provide leveled logging. The methods accept a message
|
||||
// string and a variadic number of key-value pairs. For log.Printf style
|
||||
// formatting where message string contains a format specifier, use Logger
|
||||
// interface.
|
||||
type LeveledLogger interface {
|
||||
Error(msg string, keysAndValues ...interface{})
|
||||
Info(msg string, keysAndValues ...interface{})
|
||||
Debug(msg string, keysAndValues ...interface{})
|
||||
Warn(msg string, keysAndValues ...interface{})
|
||||
}
|
||||
|
||||
// hookLogger adapts an LeveledLogger to Logger for use by the existing hook functions
|
||||
// without changing the API.
|
||||
type hookLogger struct {
|
||||
LeveledLogger
|
||||
}
|
||||
|
||||
func (h hookLogger) Printf(s string, args ...interface{}) {
|
||||
h.Info(fmt.Sprintf(s, args...))
|
||||
}
|
||||
|
||||
// RequestLogHook allows a function to run before each retry. The HTTP
|
||||
// request which will be made, and the retry number (0 for the initial
|
||||
// request) are available to users. The internal logger is exposed to
|
||||
// consumers.
|
||||
type RequestLogHook func(Logger, *http.Request, int)
|
||||
|
||||
// ResponseLogHook is like RequestLogHook, but allows running a function
|
||||
// on each HTTP response. This function will be invoked at the end of
|
||||
// every HTTP request executed, regardless of whether a subsequent retry
|
||||
// needs to be performed or not. If the response body is read or closed
|
||||
// from this method, this will affect the response returned from Do().
|
||||
type ResponseLogHook func(Logger, *http.Response)
|
||||
|
||||
// CheckRetry specifies a policy for handling retries. It is called
|
||||
// following each request with the response and error values returned by
|
||||
// the http.Client. If CheckRetry returns false, the Client stops retrying
|
||||
// and returns the response to the caller. If CheckRetry returns an error,
|
||||
// that error value is returned in lieu of the error from the request. The
|
||||
// Client will close any response body when retrying, but if the retry is
|
||||
// aborted it is up to the CheckRetry callback to properly close any
|
||||
// response body before returning.
|
||||
type CheckRetry func(ctx context.Context, resp *http.Response, err error) (bool, error)
|
||||
|
||||
// Backoff specifies a policy for how long to wait between retries.
|
||||
// It is called after a failing request to determine the amount of time
|
||||
// that should pass before trying again.
|
||||
type Backoff func(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration
|
||||
|
||||
// ErrorHandler is called if retries are expired, containing the last status
|
||||
// from the http library. If not specified, default behavior for the library is
|
||||
// to close the body and return an error indicating how many tries were
|
||||
// attempted. If overriding this, be sure to close the body if needed.
|
||||
type ErrorHandler func(resp *http.Response, err error, numTries int) (*http.Response, error)
|
||||
|
||||
// Client is used to make HTTP requests. It adds additional functionality
|
||||
// like automatic retries to tolerate minor outages.
|
||||
type Client struct {
|
||||
HTTPClient *http.Client // Internal HTTP client.
|
||||
Logger interface{} // Customer logger instance. Can be either Logger or LeveledLogger
|
||||
|
||||
RetryWaitMin time.Duration // Minimum time to wait
|
||||
RetryWaitMax time.Duration // Maximum time to wait
|
||||
RetryMax int // Maximum number of retries
|
||||
|
||||
// RequestLogHook allows a user-supplied function to be called
|
||||
// before each retry.
|
||||
RequestLogHook RequestLogHook
|
||||
|
||||
// ResponseLogHook allows a user-supplied function to be called
|
||||
// with the response from each HTTP request executed.
|
||||
ResponseLogHook ResponseLogHook
|
||||
|
||||
// CheckRetry specifies the policy for handling retries, and is called
|
||||
// after each request. The default policy is DefaultRetryPolicy.
|
||||
CheckRetry CheckRetry
|
||||
|
||||
// Backoff specifies the policy for how long to wait between retries
|
||||
Backoff Backoff
|
||||
|
||||
// ErrorHandler specifies the custom error handler to use, if any
|
||||
ErrorHandler ErrorHandler
|
||||
|
||||
loggerInit sync.Once
|
||||
clientInit sync.Once
|
||||
}
|
||||
|
||||
// NewClient creates a new Client with default settings.
|
||||
func NewClient() *Client {
|
||||
return &Client{
|
||||
HTTPClient: cleanhttp.DefaultPooledClient(),
|
||||
Logger: defaultLogger,
|
||||
RetryWaitMin: defaultRetryWaitMin,
|
||||
RetryWaitMax: defaultRetryWaitMax,
|
||||
RetryMax: defaultRetryMax,
|
||||
CheckRetry: DefaultRetryPolicy,
|
||||
Backoff: DefaultBackoff,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) logger() interface{} {
|
||||
c.loggerInit.Do(func() {
|
||||
if c.Logger == nil {
|
||||
return
|
||||
}
|
||||
|
||||
switch c.Logger.(type) {
|
||||
case Logger, LeveledLogger:
|
||||
// ok
|
||||
default:
|
||||
// This should happen in dev when they are setting Logger and work on code, not in prod.
|
||||
panic(fmt.Sprintf("invalid logger type passed, must be Logger or LeveledLogger, was %T", c.Logger))
|
||||
}
|
||||
})
|
||||
|
||||
return c.Logger
|
||||
}
|
||||
|
||||
// DefaultRetryPolicy provides a default callback for Client.CheckRetry, which
|
||||
// will retry on connection errors and server errors.
|
||||
func DefaultRetryPolicy(ctx context.Context, resp *http.Response, err error) (bool, error) {
|
||||
// do not retry on context.Canceled or context.DeadlineExceeded
|
||||
if ctx.Err() != nil {
|
||||
return false, ctx.Err()
|
||||
}
|
||||
|
||||
// don't propagate other errors
|
||||
shouldRetry, _ := baseRetryPolicy(resp, err)
|
||||
return shouldRetry, nil
|
||||
}
|
||||
|
||||
// ErrorPropagatedRetryPolicy is the same as DefaultRetryPolicy, except it
|
||||
// propagates errors back instead of returning nil. This allows you to inspect
|
||||
// why it decided to retry or not.
|
||||
func ErrorPropagatedRetryPolicy(ctx context.Context, resp *http.Response, err error) (bool, error) {
|
||||
// do not retry on context.Canceled or context.DeadlineExceeded
|
||||
if ctx.Err() != nil {
|
||||
return false, ctx.Err()
|
||||
}
|
||||
|
||||
return baseRetryPolicy(resp, err)
|
||||
}
|
||||
|
||||
func baseRetryPolicy(resp *http.Response, err error) (bool, error) {
|
||||
if err != nil {
|
||||
if v, ok := err.(*url.Error); ok {
|
||||
// Don't retry if the error was due to too many redirects.
|
||||
if redirectsErrorRe.MatchString(v.Error()) {
|
||||
return false, v
|
||||
}
|
||||
|
||||
// Don't retry if the error was due to an invalid protocol scheme.
|
||||
if schemeErrorRe.MatchString(v.Error()) {
|
||||
return false, v
|
||||
}
|
||||
|
||||
// Don't retry if the error was due to TLS cert verification failure.
|
||||
if _, ok := v.Err.(x509.UnknownAuthorityError); ok {
|
||||
return false, v
|
||||
}
|
||||
}
|
||||
|
||||
// The error is likely recoverable so retry.
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// 429 Too Many Requests is recoverable. Sometimes the server puts
|
||||
// a Retry-After response header to indicate when the server is
|
||||
// available to start processing request from client.
|
||||
if resp.StatusCode == http.StatusTooManyRequests {
|
||||
return true, nil
|
||||
}
|
||||
|
||||
// Check the response code. We retry on 500-range responses to allow
|
||||
// the server time to recover, as 500's are typically not permanent
|
||||
// errors and may relate to outages on the server side. This will catch
|
||||
// invalid response codes as well, like 0 and 999.
|
||||
if resp.StatusCode == 0 || (resp.StatusCode >= 500 && resp.StatusCode != 501) {
|
||||
return true, fmt.Errorf("unexpected HTTP status %s", resp.Status)
|
||||
}
|
||||
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// DefaultBackoff provides a default callback for Client.Backoff which
|
||||
// will perform exponential backoff based on the attempt number and limited
|
||||
// by the provided minimum and maximum durations.
|
||||
//
|
||||
// It also tries to parse Retry-After response header when a http.StatusTooManyRequests
|
||||
// (HTTP Code 429) is found in the resp parameter. Hence it will return the number of
|
||||
// seconds the server states it may be ready to process more requests from this client.
|
||||
func DefaultBackoff(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration {
|
||||
if resp != nil {
|
||||
if resp.StatusCode == http.StatusTooManyRequests {
|
||||
if s, ok := resp.Header["Retry-After"]; ok {
|
||||
if sleep, err := strconv.ParseInt(s[0], 10, 64); err == nil {
|
||||
return time.Second * time.Duration(sleep)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
mult := math.Pow(2, float64(attemptNum)) * float64(min)
|
||||
sleep := time.Duration(mult)
|
||||
if float64(sleep) != mult || sleep > max {
|
||||
sleep = max
|
||||
}
|
||||
return sleep
|
||||
}
|
||||
|
||||
// LinearJitterBackoff provides a callback for Client.Backoff which will
|
||||
// perform linear backoff based on the attempt number and with jitter to
|
||||
// prevent a thundering herd.
|
||||
//
|
||||
// min and max here are *not* absolute values. The number to be multiplied by
|
||||
// the attempt number will be chosen at random from between them, thus they are
|
||||
// bounding the jitter.
|
||||
//
|
||||
// For instance:
|
||||
// * To get strictly linear backoff of one second increasing each retry, set
|
||||
// both to one second (1s, 2s, 3s, 4s, ...)
|
||||
// * To get a small amount of jitter centered around one second increasing each
|
||||
// retry, set to around one second, such as a min of 800ms and max of 1200ms
|
||||
// (892ms, 2102ms, 2945ms, 4312ms, ...)
|
||||
// * To get extreme jitter, set to a very wide spread, such as a min of 100ms
|
||||
// and a max of 20s (15382ms, 292ms, 51321ms, 35234ms, ...)
|
||||
func LinearJitterBackoff(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration {
|
||||
// attemptNum always starts at zero but we want to start at 1 for multiplication
|
||||
attemptNum++
|
||||
|
||||
if max <= min {
|
||||
// Unclear what to do here, or they are the same, so return min *
|
||||
// attemptNum
|
||||
return min * time.Duration(attemptNum)
|
||||
}
|
||||
|
||||
// Seed rand; doing this every time is fine
|
||||
rand := rand.New(rand.NewSource(int64(time.Now().Nanosecond())))
|
||||
|
||||
// Pick a random number that lies somewhere between the min and max and
|
||||
// multiply by the attemptNum. attemptNum starts at zero so we always
|
||||
// increment here. We first get a random percentage, then apply that to the
|
||||
// difference between min and max, and add to min.
|
||||
jitter := rand.Float64() * float64(max-min)
|
||||
jitterMin := int64(jitter) + int64(min)
|
||||
return time.Duration(jitterMin * int64(attemptNum))
|
||||
}
|
||||
|
||||
// PassthroughErrorHandler is an ErrorHandler that directly passes through the
|
||||
// values from the net/http library for the final request. The body is not
|
||||
// closed.
|
||||
func PassthroughErrorHandler(resp *http.Response, err error, _ int) (*http.Response, error) {
|
||||
return resp, err
|
||||
}
|
||||
|
||||
// Do wraps calling an HTTP method with retries.
|
||||
func (c *Client) Do(req *Request) (*http.Response, error) {
|
||||
c.clientInit.Do(func() {
|
||||
if c.HTTPClient == nil {
|
||||
c.HTTPClient = cleanhttp.DefaultPooledClient()
|
||||
}
|
||||
})
|
||||
|
||||
logger := c.logger()
|
||||
|
||||
if logger != nil {
|
||||
switch v := logger.(type) {
|
||||
case LeveledLogger:
|
||||
v.Debug("performing request", "method", req.Method, "url", req.URL)
|
||||
case Logger:
|
||||
v.Printf("[DEBUG] %s %s", req.Method, req.URL)
|
||||
}
|
||||
}
|
||||
|
||||
var resp *http.Response
|
||||
var attempt int
|
||||
var shouldRetry bool
|
||||
var doErr, checkErr error
|
||||
|
||||
for i := 0; ; i++ {
|
||||
attempt++
|
||||
|
||||
var code int // HTTP response code
|
||||
|
||||
// Always rewind the request body when non-nil.
|
||||
if req.body != nil {
|
||||
body, err := req.body()
|
||||
if err != nil {
|
||||
c.HTTPClient.CloseIdleConnections()
|
||||
return resp, err
|
||||
}
|
||||
if c, ok := body.(io.ReadCloser); ok {
|
||||
req.Body = c
|
||||
} else {
|
||||
req.Body = ioutil.NopCloser(body)
|
||||
}
|
||||
}
|
||||
|
||||
if c.RequestLogHook != nil {
|
||||
switch v := logger.(type) {
|
||||
case LeveledLogger:
|
||||
c.RequestLogHook(hookLogger{v}, req.Request, i)
|
||||
case Logger:
|
||||
c.RequestLogHook(v, req.Request, i)
|
||||
default:
|
||||
c.RequestLogHook(nil, req.Request, i)
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt the request
|
||||
resp, doErr = c.HTTPClient.Do(req.Request)
|
||||
if resp != nil {
|
||||
code = resp.StatusCode
|
||||
}
|
||||
|
||||
// Check if we should continue with retries.
|
||||
shouldRetry, checkErr = c.CheckRetry(req.Context(), resp, doErr)
|
||||
|
||||
if doErr != nil {
|
||||
switch v := logger.(type) {
|
||||
case LeveledLogger:
|
||||
v.Error("request failed", "error", doErr, "method", req.Method, "url", req.URL)
|
||||
case Logger:
|
||||
v.Printf("[ERR] %s %s request failed: %v", req.Method, req.URL, doErr)
|
||||
}
|
||||
} else {
|
||||
// Call this here to maintain the behavior of logging all requests,
|
||||
// even if CheckRetry signals to stop.
|
||||
if c.ResponseLogHook != nil {
|
||||
// Call the response logger function if provided.
|
||||
switch v := logger.(type) {
|
||||
case LeveledLogger:
|
||||
c.ResponseLogHook(hookLogger{v}, resp)
|
||||
case Logger:
|
||||
c.ResponseLogHook(v, resp)
|
||||
default:
|
||||
c.ResponseLogHook(nil, resp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !shouldRetry {
|
||||
break
|
||||
}
|
||||
|
||||
// We do this before drainBody because there's no need for the I/O if
|
||||
// we're breaking out
|
||||
remain := c.RetryMax - i
|
||||
if remain <= 0 {
|
||||
break
|
||||
}
|
||||
|
||||
// We're going to retry, consume any response to reuse the connection.
|
||||
if doErr == nil {
|
||||
c.drainBody(resp.Body)
|
||||
}
|
||||
|
||||
wait := c.Backoff(c.RetryWaitMin, c.RetryWaitMax, i, resp)
|
||||
desc := fmt.Sprintf("%s %s", req.Method, req.URL)
|
||||
if code > 0 {
|
||||
desc = fmt.Sprintf("%s (status: %d)", desc, code)
|
||||
}
|
||||
if logger != nil {
|
||||
switch v := logger.(type) {
|
||||
case LeveledLogger:
|
||||
v.Debug("retrying request", "request", desc, "timeout", wait, "remaining", remain)
|
||||
case Logger:
|
||||
v.Printf("[DEBUG] %s: retrying in %s (%d left)", desc, wait, remain)
|
||||
}
|
||||
}
|
||||
select {
|
||||
case <-req.Context().Done():
|
||||
c.HTTPClient.CloseIdleConnections()
|
||||
return nil, req.Context().Err()
|
||||
case <-time.After(wait):
|
||||
}
|
||||
|
||||
// Make shallow copy of http Request so that we can modify its body
|
||||
// without racing against the closeBody call in persistConn.writeLoop.
|
||||
httpreq := *req.Request
|
||||
req.Request = &httpreq
|
||||
}
|
||||
|
||||
// this is the closest we have to success criteria
|
||||
if doErr == nil && checkErr == nil && !shouldRetry {
|
||||
return resp, nil
|
||||
}
|
||||
|
||||
defer c.HTTPClient.CloseIdleConnections()
|
||||
|
||||
err := doErr
|
||||
if checkErr != nil {
|
||||
err = checkErr
|
||||
}
|
||||
|
||||
if c.ErrorHandler != nil {
|
||||
return c.ErrorHandler(resp, err, attempt)
|
||||
}
|
||||
|
||||
// By default, we close the response body and return an error without
|
||||
// returning the response
|
||||
if resp != nil {
|
||||
c.drainBody(resp.Body)
|
||||
}
|
||||
|
||||
// this means CheckRetry thought the request was a failure, but didn't
|
||||
// communicate why
|
||||
if err == nil {
|
||||
return nil, fmt.Errorf("%s %s giving up after %d attempt(s)",
|
||||
req.Method, req.URL, attempt)
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("%s %s giving up after %d attempt(s): %w",
|
||||
req.Method, req.URL, attempt, err)
|
||||
}
|
||||
|
||||
// Try to read the response body so we can reuse this connection.
|
||||
func (c *Client) drainBody(body io.ReadCloser) {
|
||||
defer body.Close()
|
||||
_, err := io.Copy(ioutil.Discard, io.LimitReader(body, respReadLimit))
|
||||
if err != nil {
|
||||
if c.logger() != nil {
|
||||
switch v := c.logger().(type) {
|
||||
case LeveledLogger:
|
||||
v.Error("error reading response body", "error", err)
|
||||
case Logger:
|
||||
v.Printf("[ERR] error reading response body: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get is a shortcut for doing a GET request without making a new client.
|
||||
func Get(url string) (*http.Response, error) {
|
||||
return defaultClient.Get(url)
|
||||
}
|
||||
|
||||
// Get is a convenience helper for doing simple GET requests.
|
||||
func (c *Client) Get(url string) (*http.Response, error) {
|
||||
req, err := NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.Do(req)
|
||||
}
|
||||
|
||||
// Head is a shortcut for doing a HEAD request without making a new client.
|
||||
func Head(url string) (*http.Response, error) {
|
||||
return defaultClient.Head(url)
|
||||
}
|
||||
|
||||
// Head is a convenience method for doing simple HEAD requests.
|
||||
func (c *Client) Head(url string) (*http.Response, error) {
|
||||
req, err := NewRequest("HEAD", url, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.Do(req)
|
||||
}
|
||||
|
||||
// Post is a shortcut for doing a POST request without making a new client.
|
||||
func Post(url, bodyType string, body interface{}) (*http.Response, error) {
|
||||
return defaultClient.Post(url, bodyType, body)
|
||||
}
|
||||
|
||||
// Post is a convenience method for doing simple POST requests.
|
||||
func (c *Client) Post(url, bodyType string, body interface{}) (*http.Response, error) {
|
||||
req, err := NewRequest("POST", url, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Set("Content-Type", bodyType)
|
||||
return c.Do(req)
|
||||
}
|
||||
|
||||
// PostForm is a shortcut to perform a POST with form data without creating
|
||||
// a new client.
|
||||
func PostForm(url string, data url.Values) (*http.Response, error) {
|
||||
return defaultClient.PostForm(url, data)
|
||||
}
|
||||
|
||||
// PostForm is a convenience method for doing simple POST operations using
|
||||
// pre-filled url.Values form data.
|
||||
func (c *Client) PostForm(url string, data url.Values) (*http.Response, error) {
|
||||
return c.Post(url, "application/x-www-form-urlencoded", strings.NewReader(data.Encode()))
|
||||
}
|
||||
|
||||
// StandardClient returns a stdlib *http.Client with a custom Transport, which
|
||||
// shims in a *retryablehttp.Client for added retries.
|
||||
func (c *Client) StandardClient() *http.Client {
|
||||
return &http.Client{
|
||||
Transport: &RoundTripper{Client: c},
|
||||
}
|
||||
}
|
8
vendor/github.com/hashicorp/go-retryablehttp/go.mod
generated
vendored
Normal file
8
vendor/github.com/hashicorp/go-retryablehttp/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
module github.com/hashicorp/go-retryablehttp
|
||||
|
||||
require (
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1
|
||||
github.com/hashicorp/go-hclog v0.9.2
|
||||
)
|
||||
|
||||
go 1.13
|
10
vendor/github.com/hashicorp/go-retryablehttp/go.sum
generated
vendored
Normal file
10
vendor/github.com/hashicorp/go-retryablehttp/go.sum
generated
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
|
||||
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
52
vendor/github.com/hashicorp/go-retryablehttp/roundtripper.go
generated
vendored
Normal file
52
vendor/github.com/hashicorp/go-retryablehttp/roundtripper.go
generated
vendored
Normal file
|
@ -0,0 +1,52 @@
|
|||
package retryablehttp
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// RoundTripper implements the http.RoundTripper interface, using a retrying
|
||||
// HTTP client to execute requests.
|
||||
//
|
||||
// It is important to note that retryablehttp doesn't always act exactly as a
|
||||
// RoundTripper should. This is highly dependent on the retryable client's
|
||||
// configuration.
|
||||
type RoundTripper struct {
|
||||
// The client to use during requests. If nil, the default retryablehttp
|
||||
// client and settings will be used.
|
||||
Client *Client
|
||||
|
||||
// once ensures that the logic to initialize the default client runs at
|
||||
// most once, in a single thread.
|
||||
once sync.Once
|
||||
}
|
||||
|
||||
// init initializes the underlying retryable client.
|
||||
func (rt *RoundTripper) init() {
|
||||
if rt.Client == nil {
|
||||
rt.Client = NewClient()
|
||||
}
|
||||
}
|
||||
|
||||
// RoundTrip satisfies the http.RoundTripper interface.
|
||||
func (rt *RoundTripper) RoundTrip(req *http.Request) (*http.Response, error) {
|
||||
rt.once.Do(rt.init)
|
||||
|
||||
// Convert the request to be retryable.
|
||||
retryableReq, err := FromRequest(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Execute the request.
|
||||
resp, err := rt.Client.Do(retryableReq)
|
||||
// If we got an error returned by standard library's `Do` method, unwrap it
|
||||
// otherwise we will wind up erroneously re-nesting the error.
|
||||
if _, ok := err.(*url.Error); ok {
|
||||
return resp, errors.Unwrap(err)
|
||||
}
|
||||
|
||||
return resp, err
|
||||
}
|
28
vendor/github.com/xanzy/go-gitlab/.gitignore
generated
vendored
Normal file
28
vendor/github.com/xanzy/go-gitlab/.gitignore
generated
vendored
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Compiled Object files, Static and Dynamic libs (Shared Objects)
|
||||
*.o
|
||||
*.a
|
||||
*.so
|
||||
|
||||
# Folders
|
||||
_obj
|
||||
_test
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
[568vq].out
|
||||
|
||||
*.cgo1.go
|
||||
*.cgo2.c
|
||||
_cgo_defun.c
|
||||
_cgo_gotypes.go
|
||||
_cgo_export.*
|
||||
|
||||
_testmain.go
|
||||
|
||||
*.exe
|
||||
*.test
|
||||
*.prof
|
||||
|
||||
# IDE specific files and folders
|
||||
.idea
|
||||
*.iml
|
59
vendor/github.com/xanzy/go-gitlab/.golangci.yml
generated
vendored
Normal file
59
vendor/github.com/xanzy/go-gitlab/.golangci.yml
generated
vendored
Normal file
|
@ -0,0 +1,59 @@
|
|||
# This file contains all available configuration options
|
||||
# with their default values.
|
||||
|
||||
# Options for analysis running
|
||||
run:
|
||||
concurrency: 4
|
||||
timeout: 10m
|
||||
issues-exit-code: 1
|
||||
# Include test files or not, default is true
|
||||
tests: true
|
||||
|
||||
# Output configuration options
|
||||
output:
|
||||
format: line-number
|
||||
|
||||
# All available settings of specific linters
|
||||
linters-settings:
|
||||
misspell:
|
||||
locale: US
|
||||
ignore-words:
|
||||
- noteable
|
||||
unused:
|
||||
# Treat code as a program (not a library) and report unused exported identifiers
|
||||
check-exported: false
|
||||
|
||||
linters:
|
||||
enable:
|
||||
- asciicheck
|
||||
- deadcode
|
||||
- dogsled
|
||||
- errorlint
|
||||
- exportloopref
|
||||
- goconst
|
||||
- golint
|
||||
- gosimple
|
||||
- govet
|
||||
- ineffassign
|
||||
- megacheck
|
||||
- misspell
|
||||
- nakedret
|
||||
- nolintlint
|
||||
- staticcheck
|
||||
- structcheck
|
||||
- typecheck
|
||||
- unconvert
|
||||
- unused
|
||||
- varcheck
|
||||
- whitespace
|
||||
disable:
|
||||
- errcheck
|
||||
disable-all: false
|
||||
fast: false
|
||||
|
||||
issues:
|
||||
# Maximum issues count per one linter (set to 0 to disable)
|
||||
max-issues-per-linter: 0
|
||||
|
||||
# Maximum count of issues with the same text (set to 0 to disable)
|
||||
max-same-issues: 0
|
201
vendor/github.com/xanzy/go-gitlab/LICENSE
generated
vendored
Normal file
201
vendor/github.com/xanzy/go-gitlab/LICENSE
generated
vendored
Normal file
|
@ -0,0 +1,201 @@
|
|||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
194
vendor/github.com/xanzy/go-gitlab/README.md
generated
vendored
Normal file
194
vendor/github.com/xanzy/go-gitlab/README.md
generated
vendored
Normal file
|
@ -0,0 +1,194 @@
|
|||
# go-gitlab
|
||||
|
||||
A GitLab API client enabling Go programs to interact with GitLab in a simple and uniform way
|
||||
|
||||
[![Build Status](https://github.com/xanzy/go-gitlab/workflows/Lint%20and%20Test/badge.svg)](https://github.com/xanzy/go-gitlab/actions?workflow=Lint%20and%20Test)
|
||||
[![Sourcegraph](https://sourcegraph.com/github.com/xanzy/go-gitlab/-/badge.svg)](https://sourcegraph.com/github.com/xanzy/go-gitlab?badge)
|
||||
[![GoDoc](https://godoc.org/github.com/xanzy/go-gitlab?status.svg)](https://godoc.org/github.com/xanzy/go-gitlab)
|
||||
[![Go Report Card](https://goreportcard.com/badge/github.com/xanzy/go-gitlab)](https://goreportcard.com/report/github.com/xanzy/go-gitlab)
|
||||
|
||||
## NOTE
|
||||
|
||||
Release v0.6.0 (released on 25-08-2017) no longer supports the older V3 Gitlab API. If
|
||||
you need V3 support, please use the `f-api-v3` branch. This release contains some backwards
|
||||
incompatible changes that were needed to fully support the V4 Gitlab API.
|
||||
|
||||
## Coverage
|
||||
|
||||
This API client package covers most of the existing Gitlab API calls and is updated regularly
|
||||
to add new and/or missing endpoints. Currently the following services are supported:
|
||||
|
||||
- [x] Applications
|
||||
- [x] Award Emojis
|
||||
- [x] Branches
|
||||
- [x] Broadcast Messages
|
||||
- [x] Commits
|
||||
- [x] Container Registry
|
||||
- [x] Custom Attributes
|
||||
- [x] Deploy Keys
|
||||
- [x] Deployments
|
||||
- [ ] Discussions (threaded comments)
|
||||
- [x] Environments
|
||||
- [ ] Epic Issues
|
||||
- [ ] Epics
|
||||
- [x] Events
|
||||
- [x] Feature Flags
|
||||
- [ ] Geo Nodes
|
||||
- [x] GitLab CI Config Templates
|
||||
- [x] Gitignores Templates
|
||||
- [x] Group Access Requests
|
||||
- [x] Group Issue Boards
|
||||
- [x] Group Members
|
||||
- [x] Group Milestones
|
||||
- [x] Group Wikis
|
||||
- [x] Group-Level Variables
|
||||
- [x] Groups
|
||||
- [x] Instance Clusters
|
||||
- [x] Invites
|
||||
- [x] Issue Boards
|
||||
- [x] Issues
|
||||
- [x] Jobs
|
||||
- [x] Keys
|
||||
- [x] Labels
|
||||
- [x] License
|
||||
- [x] Merge Request Approvals
|
||||
- [x] Merge Requests
|
||||
- [x] Namespaces
|
||||
- [x] Notes (comments)
|
||||
- [x] Notification Settings
|
||||
- [x] Open Source License Templates
|
||||
- [x] Pages
|
||||
- [x] Pages Domains
|
||||
- [x] Personal Access Tokens
|
||||
- [x] Pipeline Schedules
|
||||
- [x] Pipeline Triggers
|
||||
- [x] Pipelines
|
||||
- [x] Project Access Requests
|
||||
- [x] Project Badges
|
||||
- [x] Project Clusters
|
||||
- [x] Project Import/export
|
||||
- [x] Project Members
|
||||
- [x] Project Milestones
|
||||
- [x] Project Snippets
|
||||
- [x] Project-Level Variables
|
||||
- [x] Projects (including setting Webhooks)
|
||||
- [x] Protected Branches
|
||||
- [x] Protected Environments
|
||||
- [x] Protected Tags
|
||||
- [x] Repositories
|
||||
- [x] Repository Files
|
||||
- [x] Runners
|
||||
- [x] Search
|
||||
- [x] Services
|
||||
- [x] Settings
|
||||
- [x] Sidekiq Metrics
|
||||
- [x] System Hooks
|
||||
- [x] Tags
|
||||
- [x] Todos
|
||||
- [x] Users
|
||||
- [x] Validate CI Configuration
|
||||
- [x] Version
|
||||
- [x] Wikis
|
||||
|
||||
## Usage
|
||||
|
||||
```go
|
||||
import "github.com/xanzy/go-gitlab"
|
||||
```
|
||||
|
||||
Construct a new GitLab client, then use the various services on the client to
|
||||
access different parts of the GitLab API. For example, to list all
|
||||
users:
|
||||
|
||||
```go
|
||||
git, err := gitlab.NewClient("yourtokengoeshere")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create client: %v", err)
|
||||
}
|
||||
users, _, err := git.Users.ListUsers(&gitlab.ListUsersOptions{})
|
||||
```
|
||||
|
||||
There are a few `With...` option functions that can be used to customize
|
||||
the API client. For example, to set a custom base URL:
|
||||
|
||||
```go
|
||||
git, err := gitlab.NewClient("yourtokengoeshere", gitlab.WithBaseURL("https://git.mydomain.com/api/v4"))
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create client: %v", err)
|
||||
}
|
||||
users, _, err := git.Users.ListUsers(&gitlab.ListUsersOptions{})
|
||||
```
|
||||
|
||||
Some API methods have optional parameters that can be passed. For example,
|
||||
to list all projects for user "svanharmelen":
|
||||
|
||||
```go
|
||||
git := gitlab.NewClient("yourtokengoeshere")
|
||||
opt := &ListProjectsOptions{Search: gitlab.String("svanharmelen")}
|
||||
projects, _, err := git.Projects.ListProjects(opt)
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
The [examples](https://github.com/xanzy/go-gitlab/tree/master/examples) directory
|
||||
contains a couple for clear examples, of which one is partially listed here as well:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
func main() {
|
||||
git, err := gitlab.NewClient("yourtokengoeshere")
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to create client: %v", err)
|
||||
}
|
||||
|
||||
// Create new project
|
||||
p := &gitlab.CreateProjectOptions{
|
||||
Name: gitlab.String("My Project"),
|
||||
Description: gitlab.String("Just a test project to play with"),
|
||||
MergeRequestsEnabled: gitlab.Bool(true),
|
||||
SnippetsEnabled: gitlab.Bool(true),
|
||||
Visibility: gitlab.Visibility(gitlab.PublicVisibility),
|
||||
}
|
||||
project, _, err := git.Projects.CreateProject(p)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Add a new snippet
|
||||
s := &gitlab.CreateProjectSnippetOptions{
|
||||
Title: gitlab.String("Dummy Snippet"),
|
||||
FileName: gitlab.String("snippet.go"),
|
||||
Content: gitlab.String("package main...."),
|
||||
Visibility: gitlab.Visibility(gitlab.PublicVisibility),
|
||||
}
|
||||
_, _, err = git.ProjectSnippets.CreateSnippet(project.ID, s)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For complete usage of go-gitlab, see the full [package docs](https://godoc.org/github.com/xanzy/go-gitlab).
|
||||
|
||||
## ToDo
|
||||
|
||||
- The biggest thing this package still needs is tests :disappointed:
|
||||
|
||||
## Issues
|
||||
|
||||
- If you have an issue: report it on the [issue tracker](https://github.com/xanzy/go-gitlab/issues)
|
||||
|
||||
## Author
|
||||
|
||||
Sander van Harmelen (<sander@vanharmelen.nl>)
|
||||
|
||||
## License
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at <http://www.apache.org/licenses/LICENSE-2.0>
|
253
vendor/github.com/xanzy/go-gitlab/access_requests.go
generated
vendored
Normal file
253
vendor/github.com/xanzy/go-gitlab/access_requests.go
generated
vendored
Normal file
|
@ -0,0 +1,253 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AccessRequest represents a access request for a group or project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/access_requests.html
|
||||
type AccessRequest struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
RequestedAt *time.Time `json:"requested_at"`
|
||||
AccessLevel AccessLevelValue `json:"access_level"`
|
||||
}
|
||||
|
||||
// AccessRequestsService handles communication with the project/group
|
||||
// access requests related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/access_requests.html
|
||||
type AccessRequestsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// ListAccessRequestsOptions represents the available
|
||||
// ListProjectAccessRequests() or ListGroupAccessRequests() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/access_requests.html#list-access-requests-for-a-group-or-project
|
||||
type ListAccessRequestsOptions ListOptions
|
||||
|
||||
// ListProjectAccessRequests gets a list of access requests
|
||||
// viewable by the authenticated user.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/access_requests.html#list-access-requests-for-a-group-or-project
|
||||
func (s *AccessRequestsService) ListProjectAccessRequests(pid interface{}, opt *ListAccessRequestsOptions, options ...RequestOptionFunc) ([]*AccessRequest, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/access_requests", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ars []*AccessRequest
|
||||
resp, err := s.client.Do(req, &ars)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ars, resp, err
|
||||
}
|
||||
|
||||
// ListGroupAccessRequests gets a list of access requests
|
||||
// viewable by the authenticated user.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/access_requests.html#list-access-requests-for-a-group-or-project
|
||||
func (s *AccessRequestsService) ListGroupAccessRequests(gid interface{}, opt *ListAccessRequestsOptions, options ...RequestOptionFunc) ([]*AccessRequest, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/access_requests", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ars []*AccessRequest
|
||||
resp, err := s.client.Do(req, &ars)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ars, resp, err
|
||||
}
|
||||
|
||||
// RequestProjectAccess requests access for the authenticated user
|
||||
// to a group or project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/access_requests.html#request-access-to-a-group-or-project
|
||||
func (s *AccessRequestsService) RequestProjectAccess(pid interface{}, options ...RequestOptionFunc) (*AccessRequest, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/access_requests", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ar := new(AccessRequest)
|
||||
resp, err := s.client.Do(req, ar)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ar, resp, err
|
||||
}
|
||||
|
||||
// RequestGroupAccess requests access for the authenticated user
|
||||
// to a group or project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/access_requests.html#request-access-to-a-group-or-project
|
||||
func (s *AccessRequestsService) RequestGroupAccess(gid interface{}, options ...RequestOptionFunc) (*AccessRequest, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/access_requests", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ar := new(AccessRequest)
|
||||
resp, err := s.client.Do(req, ar)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ar, resp, err
|
||||
}
|
||||
|
||||
// ApproveAccessRequestOptions represents the available
|
||||
// ApproveProjectAccessRequest() and ApproveGroupAccessRequest() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/access_requests.html#approve-an-access-request
|
||||
type ApproveAccessRequestOptions struct {
|
||||
AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"`
|
||||
}
|
||||
|
||||
// ApproveProjectAccessRequest approves an access request for the given user.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/access_requests.html#approve-an-access-request
|
||||
func (s *AccessRequestsService) ApproveProjectAccessRequest(pid interface{}, user int, opt *ApproveAccessRequestOptions, options ...RequestOptionFunc) (*AccessRequest, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/access_requests/%d/approve", pathEscape(project), user)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ar := new(AccessRequest)
|
||||
resp, err := s.client.Do(req, ar)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ar, resp, err
|
||||
}
|
||||
|
||||
// ApproveGroupAccessRequest approves an access request for the given user.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/access_requests.html#approve-an-access-request
|
||||
func (s *AccessRequestsService) ApproveGroupAccessRequest(gid interface{}, user int, opt *ApproveAccessRequestOptions, options ...RequestOptionFunc) (*AccessRequest, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/access_requests/%d/approve", pathEscape(group), user)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ar := new(AccessRequest)
|
||||
resp, err := s.client.Do(req, ar)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ar, resp, err
|
||||
}
|
||||
|
||||
// DenyProjectAccessRequest denies an access request for the given user.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/access_requests.html#deny-an-access-request
|
||||
func (s *AccessRequestsService) DenyProjectAccessRequest(pid interface{}, user int, options ...RequestOptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/access_requests/%d", pathEscape(project), user)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// DenyGroupAccessRequest denies an access request for the given user.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/access_requests.html#deny-an-access-request
|
||||
func (s *AccessRequestsService) DenyGroupAccessRequest(gid interface{}, user int, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/access_requests/%d", pathEscape(group), user)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
106
vendor/github.com/xanzy/go-gitlab/applications.go
generated
vendored
Normal file
106
vendor/github.com/xanzy/go-gitlab/applications.go
generated
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// ApplicationsService handles communication with administrables applications
|
||||
// of the Gitlab API.
|
||||
//
|
||||
// Gitlab API docs : https://docs.gitlab.com/ee/api/applications.html
|
||||
type ApplicationsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Application represents a GitLab application
|
||||
type Application struct {
|
||||
ID int `json:"id"`
|
||||
ApplicationID string `json:"application_id"`
|
||||
ApplicationName string `json:"application_name"`
|
||||
Secret string `json:"secret"`
|
||||
CallbackURL string `json:"callback_url"`
|
||||
Confidential bool `json:"confidential"`
|
||||
}
|
||||
|
||||
// CreateApplicationOptions represents the available CreateApplication() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/applications.html#create-an-application
|
||||
type CreateApplicationOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
RedirectURI *string `url:"redirect_uri,omitempty" json:"redirect_uri,omitempty"`
|
||||
Scopes *string `url:"scopes,omitempty" json:"scopes,omitempty"`
|
||||
Confidential *bool `url:"confidential,omitempty" json:"confidential,omitempty"`
|
||||
}
|
||||
|
||||
// CreateApplication creates a new application owned by the authenticated user.
|
||||
//
|
||||
// Gitlab API docs : https://docs.gitlab.com/ce/api/applications.html#create-an-application
|
||||
func (s *ApplicationsService) CreateApplication(opt *CreateApplicationOptions, options ...RequestOptionFunc) (*Application, *Response, error) {
|
||||
req, err := s.client.NewRequest(http.MethodPost, "applications", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
a := new(Application)
|
||||
resp, err := s.client.Do(req, a)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return a, resp, err
|
||||
}
|
||||
|
||||
// ListApplicationsOptions represents the available
|
||||
// ListApplications() options.
|
||||
type ListApplicationsOptions ListOptions
|
||||
|
||||
// ListApplications get a list of administrables applications by the authenticated user
|
||||
//
|
||||
// Gitlab API docs : https://docs.gitlab.com/ce/api/applications.html#list-all-applications
|
||||
func (s *ApplicationsService) ListApplications(opt *ListApplicationsOptions, options ...RequestOptionFunc) ([]*Application, *Response, error) {
|
||||
req, err := s.client.NewRequest(http.MethodGet, "applications", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var as []*Application
|
||||
resp, err := s.client.Do(req, &as)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return as, resp, err
|
||||
}
|
||||
|
||||
// DeleteApplication removes a specific application.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/applications.html#delete-an-application
|
||||
func (s *ApplicationsService) DeleteApplication(application int, options ...RequestOptionFunc) (*Response, error) {
|
||||
u := fmt.Sprintf("applications/%d", application)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
199
vendor/github.com/xanzy/go-gitlab/audit_events.go
generated
vendored
Normal file
199
vendor/github.com/xanzy/go-gitlab/audit_events.go
generated
vendored
Normal file
|
@ -0,0 +1,199 @@
|
|||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AuditEvent represents an audit event for a group, a project or the instance.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/audit_events.html
|
||||
type AuditEvent struct {
|
||||
ID int `json:"id"`
|
||||
AuthorID int `json:"author_id"`
|
||||
EntityID int `json:"entity_id"`
|
||||
EntityType string `json:"entity_type"`
|
||||
Details AuditEventDetails `json:"details"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// AuditEventDetails represents the details portion of an audit event for
|
||||
// a group, a project or the instance. The exact fields that are returned
|
||||
// for an audit event depend on the action being recorded.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/audit_events.html
|
||||
type AuditEventDetails struct {
|
||||
With string `json:"with"`
|
||||
Add string `json:"add"`
|
||||
As string `json:"as"`
|
||||
Change string `json:"change"`
|
||||
From string `json:"from"`
|
||||
To string `json:"to"`
|
||||
Remove string `json:"remove"`
|
||||
CustomMessage string `json:"custom_message"`
|
||||
AuthorName string `json:"author_name"`
|
||||
TargetID interface{} `json:"target_id"`
|
||||
TargetType string `json:"target_type"`
|
||||
TargetDetails string `json:"target_details"`
|
||||
IPAddress string `json:"ip_address"`
|
||||
EntityPath string `json:"entity_path"`
|
||||
FailedLogin string `json:"failed_login"`
|
||||
}
|
||||
|
||||
// AuditEventsService handles communication with the project/group/instance
|
||||
// audit event related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/audit_events.html
|
||||
type AuditEventsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// ListAuditEventsOptions represents the available ListProjectAuditEvents(),
|
||||
// ListGroupAuditEvents() or ListInstanceAuditEvents() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/audit_events.html
|
||||
type ListAuditEventsOptions struct {
|
||||
ListOptions
|
||||
CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"`
|
||||
CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"`
|
||||
}
|
||||
|
||||
// ListInstanceAuditEvents gets a list of audit events for instance.
|
||||
// Authentication as Administrator is required.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/audit_events.html
|
||||
func (s *AuditEventsService) ListInstanceAuditEvents(opt *ListAuditEventsOptions, options ...RequestOptionFunc) ([]*AuditEvent, *Response, error) {
|
||||
req, err := s.client.NewRequest(http.MethodGet, "audit_events", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var aes []*AuditEvent
|
||||
resp, err := s.client.Do(req, &aes)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return aes, resp, err
|
||||
}
|
||||
|
||||
// GetInstanceAuditEvent gets a specific instance audit event.
|
||||
// Authentication as Administrator is required.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/audit_events.html
|
||||
func (s *AuditEventsService) GetInstanceAuditEvent(event int, options ...RequestOptionFunc) (*AuditEvent, *Response, error) {
|
||||
u := fmt.Sprintf("audit_events/%d", event)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ae := new(AuditEvent)
|
||||
resp, err := s.client.Do(req, ae)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ae, resp, err
|
||||
}
|
||||
|
||||
// ListGroupAuditEvents gets a list of audit events for the specified group
|
||||
// viewable by the authenticated user.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/audit_events.html
|
||||
func (s *AuditEventsService) ListGroupAuditEvents(gid interface{}, opt *ListAuditEventsOptions, options ...RequestOptionFunc) ([]*AuditEvent, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/audit_events", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var aes []*AuditEvent
|
||||
resp, err := s.client.Do(req, &aes)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return aes, resp, err
|
||||
}
|
||||
|
||||
// GetGroupAuditEvent gets a specific group audit event.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/audit_events.html
|
||||
func (s *AuditEventsService) GetGroupAuditEvent(gid interface{}, event int, options ...RequestOptionFunc) (*AuditEvent, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/audit_events/%d", pathEscape(group), event)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ae := new(AuditEvent)
|
||||
resp, err := s.client.Do(req, ae)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ae, resp, err
|
||||
}
|
||||
|
||||
// ListProjectAuditEvents gets a list of audit events for the specified project
|
||||
// viewable by the authenticated user.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/audit_events.html
|
||||
func (s *AuditEventsService) ListProjectAuditEvents(pid interface{}, opt *ListAuditEventsOptions, options ...RequestOptionFunc) ([]*AuditEvent, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/audit_events", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var aes []*AuditEvent
|
||||
resp, err := s.client.Do(req, &aes)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return aes, resp, err
|
||||
}
|
||||
|
||||
// GetProjectAuditEvent gets a specific project audit event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/audit_events.html
|
||||
func (s *AuditEventsService) GetProjectAuditEvent(pid interface{}, event int, options ...RequestOptionFunc) (*AuditEvent, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/audit_events/%d", pathEscape(project), event)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ae := new(AuditEvent)
|
||||
resp, err := s.client.Do(req, ae)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ae, resp, err
|
||||
}
|
64
vendor/github.com/xanzy/go-gitlab/avatar.go
generated
vendored
Normal file
64
vendor/github.com/xanzy/go-gitlab/avatar.go
generated
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
//
|
||||
// Copyright 2021, Pavel Kostohrys
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// AvatarRequestsService handles communication with the avatar related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/avatar.html
|
||||
type AvatarRequestsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Avatar represents a GitLab avatar.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/avatar.html
|
||||
type Avatar struct {
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
}
|
||||
|
||||
// GetAvatarOptions represents the available GetAvatar() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/avatar.html#get-a-single-avatar-url
|
||||
type GetAvatarOptions struct {
|
||||
Email *string `url:"email,omitempty" json:"email,omitempty"`
|
||||
Size *int `url:"size,omitempty" json:"size,omitempty"`
|
||||
}
|
||||
|
||||
// GetAvatar gets the avatar URL for a user with the given email address.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/avatar.html#get-a-single-avatar-url
|
||||
func (s *AvatarRequestsService) GetAvatar(opt *GetAvatarOptions, options ...RequestOptionFunc) (*Avatar, *Response, error) {
|
||||
req, err := s.client.NewRequest(http.MethodGet, "avatar", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
avatar := new(Avatar)
|
||||
response, err := s.client.Do(req, avatar)
|
||||
if err != nil {
|
||||
return nil, response, err
|
||||
}
|
||||
|
||||
return avatar, response, nil
|
||||
}
|
468
vendor/github.com/xanzy/go-gitlab/award_emojis.go
generated
vendored
Normal file
468
vendor/github.com/xanzy/go-gitlab/award_emojis.go
generated
vendored
Normal file
|
@ -0,0 +1,468 @@
|
|||
//
|
||||
// Copyright 2021, Arkbriar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// AwardEmojiService handles communication with the emoji awards related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/award_emoji.html
|
||||
type AwardEmojiService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// AwardEmoji represents a GitLab Award Emoji.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/award_emoji.html
|
||||
type AwardEmoji struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
User struct {
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
ID int `json:"id"`
|
||||
State string `json:"state"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
} `json:"user"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
AwardableID int `json:"awardable_id"`
|
||||
AwardableType string `json:"awardable_type"`
|
||||
}
|
||||
|
||||
const (
|
||||
awardMergeRequest = "merge_requests"
|
||||
awardIssue = "issues"
|
||||
awardSnippets = "snippets"
|
||||
)
|
||||
|
||||
// ListAwardEmojiOptions represents the available options for listing emoji
|
||||
// for each resources
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html
|
||||
type ListAwardEmojiOptions ListOptions
|
||||
|
||||
// ListMergeRequestAwardEmoji gets a list of all award emoji on the merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji
|
||||
func (s *AwardEmojiService) ListMergeRequestAwardEmoji(pid interface{}, mergeRequestIID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) {
|
||||
return s.listAwardEmoji(pid, awardMergeRequest, mergeRequestIID, opt, options...)
|
||||
}
|
||||
|
||||
// ListIssueAwardEmoji gets a list of all award emoji on the issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji
|
||||
func (s *AwardEmojiService) ListIssueAwardEmoji(pid interface{}, issueIID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) {
|
||||
return s.listAwardEmoji(pid, awardIssue, issueIID, opt, options...)
|
||||
}
|
||||
|
||||
// ListSnippetAwardEmoji gets a list of all award emoji on the snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji
|
||||
func (s *AwardEmojiService) ListSnippetAwardEmoji(pid interface{}, snippetID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) {
|
||||
return s.listAwardEmoji(pid, awardSnippets, snippetID, opt, options...)
|
||||
}
|
||||
|
||||
func (s *AwardEmojiService) listAwardEmoji(pid interface{}, resource string, resourceID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/%s/%d/award_emoji",
|
||||
pathEscape(project),
|
||||
resource,
|
||||
resourceID,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var as []*AwardEmoji
|
||||
resp, err := s.client.Do(req, &as)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return as, resp, err
|
||||
}
|
||||
|
||||
// GetMergeRequestAwardEmoji get an award emoji from merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji
|
||||
func (s *AwardEmojiService) GetMergeRequestAwardEmoji(pid interface{}, mergeRequestIID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.getAwardEmoji(pid, awardMergeRequest, mergeRequestIID, awardID, options...)
|
||||
}
|
||||
|
||||
// GetIssueAwardEmoji get an award emoji from issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji
|
||||
func (s *AwardEmojiService) GetIssueAwardEmoji(pid interface{}, issueIID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.getAwardEmoji(pid, awardIssue, issueIID, awardID, options...)
|
||||
}
|
||||
|
||||
// GetSnippetAwardEmoji get an award emoji from snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#list-an-awardable-39-s-award-emoji
|
||||
func (s *AwardEmojiService) GetSnippetAwardEmoji(pid interface{}, snippetID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.getAwardEmoji(pid, awardSnippets, snippetID, awardID, options...)
|
||||
}
|
||||
|
||||
func (s *AwardEmojiService) getAwardEmoji(pid interface{}, resource string, resourceID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/%s/%d/award_emoji/%d",
|
||||
pathEscape(project),
|
||||
resource,
|
||||
resourceID,
|
||||
awardID,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
a := new(AwardEmoji)
|
||||
resp, err := s.client.Do(req, &a)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return a, resp, err
|
||||
}
|
||||
|
||||
// CreateAwardEmojiOptions represents the available options for awarding emoji
|
||||
// for a resource
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji
|
||||
type CreateAwardEmojiOptions struct {
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// CreateMergeRequestAwardEmoji get an award emoji from merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji
|
||||
func (s *AwardEmojiService) CreateMergeRequestAwardEmoji(pid interface{}, mergeRequestIID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.createAwardEmoji(pid, awardMergeRequest, mergeRequestIID, opt, options...)
|
||||
}
|
||||
|
||||
// CreateIssueAwardEmoji get an award emoji from issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji
|
||||
func (s *AwardEmojiService) CreateIssueAwardEmoji(pid interface{}, issueIID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.createAwardEmoji(pid, awardIssue, issueIID, opt, options...)
|
||||
}
|
||||
|
||||
// CreateSnippetAwardEmoji get an award emoji from snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji
|
||||
func (s *AwardEmojiService) CreateSnippetAwardEmoji(pid interface{}, snippetID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.createAwardEmoji(pid, awardSnippets, snippetID, opt, options...)
|
||||
}
|
||||
|
||||
func (s *AwardEmojiService) createAwardEmoji(pid interface{}, resource string, resourceID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/%s/%d/award_emoji",
|
||||
pathEscape(project),
|
||||
resource,
|
||||
resourceID,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
a := new(AwardEmoji)
|
||||
resp, err := s.client.Do(req, &a)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return a, resp, err
|
||||
}
|
||||
|
||||
// DeleteIssueAwardEmoji delete award emoji on an issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji-on-a-note
|
||||
func (s *AwardEmojiService) DeleteIssueAwardEmoji(pid interface{}, issueIID, awardID int, options ...RequestOptionFunc) (*Response, error) {
|
||||
return s.deleteAwardEmoji(pid, awardMergeRequest, issueIID, awardID, options...)
|
||||
}
|
||||
|
||||
// DeleteMergeRequestAwardEmoji delete award emoji on a merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji-on-a-note
|
||||
func (s *AwardEmojiService) DeleteMergeRequestAwardEmoji(pid interface{}, mergeRequestIID, awardID int, options ...RequestOptionFunc) (*Response, error) {
|
||||
return s.deleteAwardEmoji(pid, awardMergeRequest, mergeRequestIID, awardID, options...)
|
||||
}
|
||||
|
||||
// DeleteSnippetAwardEmoji delete award emoji on a snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji-on-a-note
|
||||
func (s *AwardEmojiService) DeleteSnippetAwardEmoji(pid interface{}, snippetID, awardID int, options ...RequestOptionFunc) (*Response, error) {
|
||||
return s.deleteAwardEmoji(pid, awardMergeRequest, snippetID, awardID, options...)
|
||||
}
|
||||
|
||||
// DeleteAwardEmoji Delete an award emoji on the specified resource.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#delete-an-award-emoji
|
||||
func (s *AwardEmojiService) deleteAwardEmoji(pid interface{}, resource string, resourceID, awardID int, options ...RequestOptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/%s/%d/award_emoji/%d", pathEscape(project), resource,
|
||||
resourceID, awardID)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// ListIssuesAwardEmojiOnNote gets a list of all award emoji on a note from the
|
||||
// issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) ListIssuesAwardEmojiOnNote(pid interface{}, issueID, noteID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) {
|
||||
return s.listAwardEmojiOnNote(pid, awardIssue, issueID, noteID, opt, options...)
|
||||
}
|
||||
|
||||
// ListMergeRequestAwardEmojiOnNote gets a list of all award emoji on a note
|
||||
// from the merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) ListMergeRequestAwardEmojiOnNote(pid interface{}, mergeRequestIID, noteID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) {
|
||||
return s.listAwardEmojiOnNote(pid, awardMergeRequest, mergeRequestIID, noteID, opt, options...)
|
||||
}
|
||||
|
||||
// ListSnippetAwardEmojiOnNote gets a list of all award emoji on a note from the
|
||||
// snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) ListSnippetAwardEmojiOnNote(pid interface{}, snippetIID, noteID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) {
|
||||
return s.listAwardEmojiOnNote(pid, awardSnippets, snippetIID, noteID, opt, options...)
|
||||
}
|
||||
|
||||
func (s *AwardEmojiService) listAwardEmojiOnNote(pid interface{}, resources string, ressourceID, noteID int, opt *ListAwardEmojiOptions, options ...RequestOptionFunc) ([]*AwardEmoji, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/%s/%d/notes/%d/award_emoji", pathEscape(project), resources,
|
||||
ressourceID, noteID)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var as []*AwardEmoji
|
||||
resp, err := s.client.Do(req, &as)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return as, resp, err
|
||||
}
|
||||
|
||||
// GetIssuesAwardEmojiOnNote gets an award emoji on a note from an issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) GetIssuesAwardEmojiOnNote(pid interface{}, issueID, noteID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.getSingleNoteAwardEmoji(pid, awardIssue, issueID, noteID, awardID, options...)
|
||||
}
|
||||
|
||||
// GetMergeRequestAwardEmojiOnNote gets an award emoji on a note from a
|
||||
// merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) GetMergeRequestAwardEmojiOnNote(pid interface{}, mergeRequestIID, noteID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.getSingleNoteAwardEmoji(pid, awardMergeRequest, mergeRequestIID, noteID, awardID,
|
||||
options...)
|
||||
}
|
||||
|
||||
// GetSnippetAwardEmojiOnNote gets an award emoji on a note from a snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) GetSnippetAwardEmojiOnNote(pid interface{}, snippetIID, noteID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.getSingleNoteAwardEmoji(pid, awardSnippets, snippetIID, noteID, awardID, options...)
|
||||
}
|
||||
|
||||
func (s *AwardEmojiService) getSingleNoteAwardEmoji(pid interface{}, ressource string, resourceID, noteID, awardID int, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/%s/%d/notes/%d/award_emoji/%d",
|
||||
pathEscape(project),
|
||||
ressource,
|
||||
resourceID,
|
||||
noteID,
|
||||
awardID,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
a := new(AwardEmoji)
|
||||
resp, err := s.client.Do(req, &a)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return a, resp, err
|
||||
}
|
||||
|
||||
// CreateIssuesAwardEmojiOnNote gets an award emoji on a note from an issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) CreateIssuesAwardEmojiOnNote(pid interface{}, issueID, noteID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.createAwardEmojiOnNote(pid, awardIssue, issueID, noteID, opt, options...)
|
||||
}
|
||||
|
||||
// CreateMergeRequestAwardEmojiOnNote gets an award emoji on a note from a
|
||||
// merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) CreateMergeRequestAwardEmojiOnNote(pid interface{}, mergeRequestIID, noteID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.createAwardEmojiOnNote(pid, awardMergeRequest, mergeRequestIID, noteID, opt, options...)
|
||||
}
|
||||
|
||||
// CreateSnippetAwardEmojiOnNote gets an award emoji on a note from a snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) CreateSnippetAwardEmojiOnNote(pid interface{}, snippetIID, noteID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) {
|
||||
return s.createAwardEmojiOnNote(pid, awardSnippets, snippetIID, noteID, opt, options...)
|
||||
}
|
||||
|
||||
// CreateAwardEmojiOnNote award emoji on a note.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-a-new-emoji-on-a-note
|
||||
func (s *AwardEmojiService) createAwardEmojiOnNote(pid interface{}, resource string, resourceID, noteID int, opt *CreateAwardEmojiOptions, options ...RequestOptionFunc) (*AwardEmoji, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/%s/%d/notes/%d/award_emoji",
|
||||
pathEscape(project),
|
||||
resource,
|
||||
resourceID,
|
||||
noteID,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
a := new(AwardEmoji)
|
||||
resp, err := s.client.Do(req, &a)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return a, resp, err
|
||||
}
|
||||
|
||||
// DeleteIssuesAwardEmojiOnNote deletes an award emoji on a note from an issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) DeleteIssuesAwardEmojiOnNote(pid interface{}, issueID, noteID, awardID int, options ...RequestOptionFunc) (*Response, error) {
|
||||
return s.deleteAwardEmojiOnNote(pid, awardIssue, issueID, noteID, awardID, options...)
|
||||
}
|
||||
|
||||
// DeleteMergeRequestAwardEmojiOnNote deletes an award emoji on a note from a
|
||||
// merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) DeleteMergeRequestAwardEmojiOnNote(pid interface{}, mergeRequestIID, noteID, awardID int, options ...RequestOptionFunc) (*Response, error) {
|
||||
return s.deleteAwardEmojiOnNote(pid, awardMergeRequest, mergeRequestIID, noteID, awardID,
|
||||
options...)
|
||||
}
|
||||
|
||||
// DeleteSnippetAwardEmojiOnNote deletes an award emoji on a note from a snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/award_emoji.html#award-emoji-on-notes
|
||||
func (s *AwardEmojiService) DeleteSnippetAwardEmojiOnNote(pid interface{}, snippetIID, noteID, awardID int, options ...RequestOptionFunc) (*Response, error) {
|
||||
return s.deleteAwardEmojiOnNote(pid, awardSnippets, snippetIID, noteID, awardID, options...)
|
||||
}
|
||||
|
||||
func (s *AwardEmojiService) deleteAwardEmojiOnNote(pid interface{}, resource string, resourceID, noteID, awardID int, options ...RequestOptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/%s/%d/notes/%d/award_emoji/%d",
|
||||
pathEscape(project),
|
||||
resource,
|
||||
resourceID,
|
||||
noteID,
|
||||
awardID,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
345
vendor/github.com/xanzy/go-gitlab/boards.go
generated
vendored
Normal file
345
vendor/github.com/xanzy/go-gitlab/boards.go
generated
vendored
Normal file
|
@ -0,0 +1,345 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// IssueBoardsService handles communication with the issue board related
|
||||
// methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html
|
||||
type IssueBoardsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// IssueBoard represents a GitLab issue board.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html
|
||||
type IssueBoard struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Project *Project `json:"project"`
|
||||
Milestone *Milestone `json:"milestone"`
|
||||
Lists []*BoardList `json:"lists"`
|
||||
}
|
||||
|
||||
func (b IssueBoard) String() string {
|
||||
return Stringify(b)
|
||||
}
|
||||
|
||||
// BoardList represents a GitLab board list.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html
|
||||
type BoardList struct {
|
||||
ID int `json:"id"`
|
||||
Label *Label `json:"label"`
|
||||
Position int `json:"position"`
|
||||
}
|
||||
|
||||
func (b BoardList) String() string {
|
||||
return Stringify(b)
|
||||
}
|
||||
|
||||
// CreateIssueBoardOptions represents the available CreateIssueBoard() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/boards.html#create-a-board-starter
|
||||
type CreateIssueBoardOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// CreateIssueBoard creates a new issue board.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/boards.html#create-a-board-starter
|
||||
func (s *IssueBoardsService) CreateIssueBoard(pid interface{}, opt *CreateIssueBoardOptions, options ...RequestOptionFunc) (*IssueBoard, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/boards", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
board := new(IssueBoard)
|
||||
resp, err := s.client.Do(req, board)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return board, resp, err
|
||||
}
|
||||
|
||||
// UpdateIssueBoardOptions represents the available UpdateIssueBoard() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/boards.html#update-a-board-starter
|
||||
type UpdateIssueBoardOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
|
||||
MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"`
|
||||
Labels Labels `url:"labels,omitempty" json:"labels,omitempty"`
|
||||
Weight *int `url:"weight,omitempty" json:"weight,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateIssueBoard update an issue board.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/boards.html#create-a-board-starter
|
||||
func (s *IssueBoardsService) UpdateIssueBoard(pid interface{}, board int, opt *UpdateIssueBoardOptions, options ...RequestOptionFunc) (*IssueBoard, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/boards/%d", pathEscape(project), board)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
is := new(IssueBoard)
|
||||
resp, err := s.client.Do(req, is)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return is, resp, err
|
||||
}
|
||||
|
||||
// DeleteIssueBoard deletes an issue board.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/boards.html#delete-a-board-starter
|
||||
func (s *IssueBoardsService) DeleteIssueBoard(pid interface{}, board int, options ...RequestOptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/boards/%d", pathEscape(project), board)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// ListIssueBoardsOptions represents the available ListIssueBoards() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#project-board
|
||||
type ListIssueBoardsOptions ListOptions
|
||||
|
||||
// ListIssueBoards gets a list of all issue boards in a project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#project-board
|
||||
func (s *IssueBoardsService) ListIssueBoards(pid interface{}, opt *ListIssueBoardsOptions, options ...RequestOptionFunc) ([]*IssueBoard, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/boards", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var is []*IssueBoard
|
||||
resp, err := s.client.Do(req, &is)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return is, resp, err
|
||||
}
|
||||
|
||||
// GetIssueBoard gets a single issue board of a project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#single-board
|
||||
func (s *IssueBoardsService) GetIssueBoard(pid interface{}, board int, options ...RequestOptionFunc) (*IssueBoard, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/boards/%d", pathEscape(project), board)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ib := new(IssueBoard)
|
||||
resp, err := s.client.Do(req, ib)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ib, resp, err
|
||||
}
|
||||
|
||||
// GetIssueBoardListsOptions represents the available GetIssueBoardLists() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#list-board-lists
|
||||
type GetIssueBoardListsOptions ListOptions
|
||||
|
||||
// GetIssueBoardLists gets a list of the issue board's lists. Does not include
|
||||
// backlog and closed lists.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#list-board-lists
|
||||
func (s *IssueBoardsService) GetIssueBoardLists(pid interface{}, board int, opt *GetIssueBoardListsOptions, options ...RequestOptionFunc) ([]*BoardList, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/boards/%d/lists", pathEscape(project), board)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var bl []*BoardList
|
||||
resp, err := s.client.Do(req, &bl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return bl, resp, err
|
||||
}
|
||||
|
||||
// GetIssueBoardList gets a single issue board list.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#single-board-list
|
||||
func (s *IssueBoardsService) GetIssueBoardList(pid interface{}, board, list int, options ...RequestOptionFunc) (*BoardList, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/boards/%d/lists/%d",
|
||||
pathEscape(project),
|
||||
board,
|
||||
list,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
bl := new(BoardList)
|
||||
resp, err := s.client.Do(req, bl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return bl, resp, err
|
||||
}
|
||||
|
||||
// CreateIssueBoardListOptions represents the available CreateIssueBoardList()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#new-board-list
|
||||
type CreateIssueBoardListOptions struct {
|
||||
LabelID *int `url:"label_id" json:"label_id"`
|
||||
}
|
||||
|
||||
// CreateIssueBoardList creates a new issue board list.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#new-board-list
|
||||
func (s *IssueBoardsService) CreateIssueBoardList(pid interface{}, board int, opt *CreateIssueBoardListOptions, options ...RequestOptionFunc) (*BoardList, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/boards/%d/lists", pathEscape(project), board)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
bl := new(BoardList)
|
||||
resp, err := s.client.Do(req, bl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return bl, resp, err
|
||||
}
|
||||
|
||||
// UpdateIssueBoardListOptions represents the available UpdateIssueBoardList()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#edit-board-list
|
||||
type UpdateIssueBoardListOptions struct {
|
||||
Position *int `url:"position" json:"position"`
|
||||
}
|
||||
|
||||
// UpdateIssueBoardList updates the position of an existing issue board list.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/boards.html#edit-board-list
|
||||
func (s *IssueBoardsService) UpdateIssueBoardList(pid interface{}, board, list int, opt *UpdateIssueBoardListOptions, options ...RequestOptionFunc) (*BoardList, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/boards/%d/lists/%d",
|
||||
pathEscape(project),
|
||||
board,
|
||||
list,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
bl := new(BoardList)
|
||||
resp, err := s.client.Do(req, bl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return bl, resp, err
|
||||
}
|
||||
|
||||
// DeleteIssueBoardList soft deletes an issue board list. Only for admins and
|
||||
// project owners.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/boards.html#delete-a-board-list
|
||||
func (s *IssueBoardsService) DeleteIssueBoardList(pid interface{}, board, list int, options ...RequestOptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/boards/%d/lists/%d",
|
||||
pathEscape(project),
|
||||
board,
|
||||
list,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
245
vendor/github.com/xanzy/go-gitlab/branches.go
generated
vendored
Normal file
245
vendor/github.com/xanzy/go-gitlab/branches.go
generated
vendored
Normal file
|
@ -0,0 +1,245 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// BranchesService handles communication with the branch related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/branches.html
|
||||
type BranchesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Branch represents a GitLab branch.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/branches.html
|
||||
type Branch struct {
|
||||
Commit *Commit `json:"commit"`
|
||||
Name string `json:"name"`
|
||||
Protected bool `json:"protected"`
|
||||
Merged bool `json:"merged"`
|
||||
Default bool `json:"default"`
|
||||
CanPush bool `json:"can_push"`
|
||||
DevelopersCanPush bool `json:"developers_can_push"`
|
||||
DevelopersCanMerge bool `json:"developers_can_merge"`
|
||||
WebURL string `json:"web_url"`
|
||||
}
|
||||
|
||||
func (b Branch) String() string {
|
||||
return Stringify(b)
|
||||
}
|
||||
|
||||
// ListBranchesOptions represents the available ListBranches() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#list-repository-branches
|
||||
type ListBranchesOptions struct {
|
||||
ListOptions
|
||||
Search *string `url:"search,omitempty" json:"search,omitempty"`
|
||||
}
|
||||
|
||||
// ListBranches gets a list of repository branches from a project, sorted by
|
||||
// name alphabetically.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#list-repository-branches
|
||||
func (s *BranchesService) ListBranches(pid interface{}, opts *ListBranchesOptions, options ...RequestOptionFunc) ([]*Branch, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/branches", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opts, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var b []*Branch
|
||||
resp, err := s.client.Do(req, &b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b, resp, err
|
||||
}
|
||||
|
||||
// GetBranch gets a single project repository branch.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#get-single-repository-branch
|
||||
func (s *BranchesService) GetBranch(pid interface{}, branch string, options ...RequestOptionFunc) (*Branch, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/branches/%s", pathEscape(project), url.PathEscape(branch))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
b := new(Branch)
|
||||
resp, err := s.client.Do(req, b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b, resp, err
|
||||
}
|
||||
|
||||
// ProtectBranchOptions represents the available ProtectBranch() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#protect-repository-branch
|
||||
type ProtectBranchOptions struct {
|
||||
DevelopersCanPush *bool `url:"developers_can_push,omitempty" json:"developers_can_push,omitempty"`
|
||||
DevelopersCanMerge *bool `url:"developers_can_merge,omitempty" json:"developers_can_merge,omitempty"`
|
||||
}
|
||||
|
||||
// ProtectBranch protects a single project repository branch. This is an
|
||||
// idempotent function, protecting an already protected repository branch
|
||||
// still returns a 200 OK status code.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#protect-repository-branch
|
||||
func (s *BranchesService) ProtectBranch(pid interface{}, branch string, opts *ProtectBranchOptions, options ...RequestOptionFunc) (*Branch, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/branches/%s/protect", pathEscape(project), url.PathEscape(branch))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opts, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
b := new(Branch)
|
||||
resp, err := s.client.Do(req, b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b, resp, err
|
||||
}
|
||||
|
||||
// UnprotectBranch unprotects a single project repository branch. This is an
|
||||
// idempotent function, unprotecting an already unprotected repository branch
|
||||
// still returns a 200 OK status code.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#unprotect-repository-branch
|
||||
func (s *BranchesService) UnprotectBranch(pid interface{}, branch string, options ...RequestOptionFunc) (*Branch, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/branches/%s/unprotect", pathEscape(project), url.PathEscape(branch))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
b := new(Branch)
|
||||
resp, err := s.client.Do(req, b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b, resp, err
|
||||
}
|
||||
|
||||
// CreateBranchOptions represents the available CreateBranch() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#create-repository-branch
|
||||
type CreateBranchOptions struct {
|
||||
Branch *string `url:"branch,omitempty" json:"branch,omitempty"`
|
||||
Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
|
||||
}
|
||||
|
||||
// CreateBranch creates branch from commit SHA or existing branch.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#create-repository-branch
|
||||
func (s *BranchesService) CreateBranch(pid interface{}, opt *CreateBranchOptions, options ...RequestOptionFunc) (*Branch, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/branches", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
b := new(Branch)
|
||||
resp, err := s.client.Do(req, b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b, resp, err
|
||||
}
|
||||
|
||||
// DeleteBranch deletes an existing branch.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#delete-repository-branch
|
||||
func (s *BranchesService) DeleteBranch(pid interface{}, branch string, options ...RequestOptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/branches/%s", pathEscape(project), url.PathEscape(branch))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// DeleteMergedBranches deletes all branches that are merged into the project's default branch.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/branches.html#delete-merged-branches
|
||||
func (s *BranchesService) DeleteMergedBranches(pid interface{}, options ...RequestOptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/merged_branches", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
173
vendor/github.com/xanzy/go-gitlab/broadcast_messages.go
generated
vendored
Normal file
173
vendor/github.com/xanzy/go-gitlab/broadcast_messages.go
generated
vendored
Normal file
|
@ -0,0 +1,173 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// BroadcastMessagesService handles communication with the broadcast
|
||||
// messages methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/broadcast_messages.html
|
||||
type BroadcastMessagesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// BroadcastMessage represents a GitLab issue board.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#get-all-broadcast-messages
|
||||
type BroadcastMessage struct {
|
||||
Message string `json:"message"`
|
||||
StartsAt *time.Time `json:"starts_at"`
|
||||
EndsAt *time.Time `json:"ends_at"`
|
||||
Color string `json:"color"`
|
||||
Font string `json:"font"`
|
||||
ID int `json:"id"`
|
||||
Active bool `json:"active"`
|
||||
}
|
||||
|
||||
// ListBroadcastMessagesOptions represents the available ListBroadcastMessages()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#get-all-broadcast-messages
|
||||
type ListBroadcastMessagesOptions ListOptions
|
||||
|
||||
// ListBroadcastMessages gets a list of all broadcasted messages.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#get-all-broadcast-messages
|
||||
func (s *BroadcastMessagesService) ListBroadcastMessages(opt *ListBroadcastMessagesOptions, options ...RequestOptionFunc) ([]*BroadcastMessage, *Response, error) {
|
||||
req, err := s.client.NewRequest(http.MethodGet, "broadcast_messages", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var bs []*BroadcastMessage
|
||||
resp, err := s.client.Do(req, &bs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return bs, resp, err
|
||||
}
|
||||
|
||||
// GetBroadcastMessage gets a single broadcast message.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#get-a-specific-broadcast-message
|
||||
func (s *BroadcastMessagesService) GetBroadcastMessage(broadcast int, options ...RequestOptionFunc) (*BroadcastMessage, *Response, error) {
|
||||
u := fmt.Sprintf("broadcast_messages/%d", broadcast)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
b := new(BroadcastMessage)
|
||||
resp, err := s.client.Do(req, &b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b, resp, err
|
||||
}
|
||||
|
||||
// CreateBroadcastMessageOptions represents the available CreateBroadcastMessage()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#create-a-broadcast-message
|
||||
type CreateBroadcastMessageOptions struct {
|
||||
Message *string `url:"message" json:"message"`
|
||||
StartsAt *time.Time `url:"starts_at,omitempty" json:"starts_at,omitempty"`
|
||||
EndsAt *time.Time `url:"ends_at,omitempty" json:"ends_at,omitempty"`
|
||||
Color *string `url:"color,omitempty" json:"color,omitempty"`
|
||||
Font *string `url:"font,omitempty" json:"font,omitempty"`
|
||||
}
|
||||
|
||||
// CreateBroadcastMessage creates a message to broadcast.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#create-a-broadcast-message
|
||||
func (s *BroadcastMessagesService) CreateBroadcastMessage(opt *CreateBroadcastMessageOptions, options ...RequestOptionFunc) (*BroadcastMessage, *Response, error) {
|
||||
req, err := s.client.NewRequest(http.MethodPost, "broadcast_messages", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
b := new(BroadcastMessage)
|
||||
resp, err := s.client.Do(req, &b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b, resp, err
|
||||
}
|
||||
|
||||
// UpdateBroadcastMessageOptions represents the available CreateBroadcastMessage()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#update-a-broadcast-message
|
||||
type UpdateBroadcastMessageOptions struct {
|
||||
Message *string `url:"message,omitempty" json:"message,omitempty"`
|
||||
StartsAt *time.Time `url:"starts_at,omitempty" json:"starts_at,omitempty"`
|
||||
EndsAt *time.Time `url:"ends_at,omitempty" json:"ends_at,omitempty"`
|
||||
Color *string `url:"color,omitempty" json:"color,omitempty"`
|
||||
Font *string `url:"font,omitempty" json:"font,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateBroadcastMessage update a broadcasted message.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#update-a-broadcast-message
|
||||
func (s *BroadcastMessagesService) UpdateBroadcastMessage(broadcast int, opt *UpdateBroadcastMessageOptions, options ...RequestOptionFunc) (*BroadcastMessage, *Response, error) {
|
||||
u := fmt.Sprintf("broadcast_messages/%d", broadcast)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
b := new(BroadcastMessage)
|
||||
resp, err := s.client.Do(req, &b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b, resp, err
|
||||
}
|
||||
|
||||
// DeleteBroadcastMessage deletes a broadcasted message.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/broadcast_messages.html#delete-a-broadcast-message
|
||||
func (s *BroadcastMessagesService) DeleteBroadcastMessage(broadcast int, options ...RequestOptionFunc) (*Response, error) {
|
||||
u := fmt.Sprintf("broadcast_messages/%d", broadcast)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
86
vendor/github.com/xanzy/go-gitlab/ci_yml_templates.go
generated
vendored
Normal file
86
vendor/github.com/xanzy/go-gitlab/ci_yml_templates.go
generated
vendored
Normal file
|
@ -0,0 +1,86 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// CIYMLTemplatesService handles communication with the gitlab
|
||||
// CI YML templates related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/templates/gitlab_ci_ymls.html
|
||||
type CIYMLTemplatesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// CIYMLTemplate represents a GitLab CI YML template.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/templates/gitlab_ci_ymls.html
|
||||
type CIYMLTemplate struct {
|
||||
Name string `json:"name"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
// ListCIYMLTemplatesOptions represents the available ListAllTemplates() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/templates/gitignores.html#list-gitignore-templates
|
||||
type ListCIYMLTemplatesOptions ListOptions
|
||||
|
||||
// ListAllTemplates get all GitLab CI YML templates.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/templates/gitlab_ci_ymls.html#list-gitlab-ci-yml-templates
|
||||
func (s *CIYMLTemplatesService) ListAllTemplates(opt *ListCIYMLTemplatesOptions, options ...RequestOptionFunc) ([]*CIYMLTemplate, *Response, error) {
|
||||
req, err := s.client.NewRequest(http.MethodGet, "templates/gitlab_ci_ymls", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var cts []*CIYMLTemplate
|
||||
resp, err := s.client.Do(req, &cts)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return cts, resp, err
|
||||
}
|
||||
|
||||
// GetTemplate get a single GitLab CI YML template.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/templates/gitlab_ci_ymls.html#single-gitlab-ci-yml-template
|
||||
func (s *CIYMLTemplatesService) GetTemplate(key string, options ...RequestOptionFunc) (*CIYMLTemplate, *Response, error) {
|
||||
u := fmt.Sprintf("templates/gitlab_ci_ymls/%s", pathEscape(key))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ct := new(CIYMLTemplate)
|
||||
resp, err := s.client.Do(req, ct)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ct, resp, err
|
||||
}
|
92
vendor/github.com/xanzy/go-gitlab/client_options.go
generated
vendored
Normal file
92
vendor/github.com/xanzy/go-gitlab/client_options.go
generated
vendored
Normal file
|
@ -0,0 +1,92 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
retryablehttp "github.com/hashicorp/go-retryablehttp"
|
||||
)
|
||||
|
||||
// ClientOptionFunc can be used to customize a new GitLab API client.
|
||||
type ClientOptionFunc func(*Client) error
|
||||
|
||||
// WithBaseURL sets the base URL for API requests to a custom endpoint.
|
||||
func WithBaseURL(urlStr string) ClientOptionFunc {
|
||||
return func(c *Client) error {
|
||||
return c.setBaseURL(urlStr)
|
||||
}
|
||||
}
|
||||
|
||||
// WithCustomBackoff can be used to configure a custom backoff policy.
|
||||
func WithCustomBackoff(backoff retryablehttp.Backoff) ClientOptionFunc {
|
||||
return func(c *Client) error {
|
||||
c.client.Backoff = backoff
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithCustomLeveledLogger can be used to configure a custom retryablehttp
|
||||
// leveled logger.
|
||||
func WithCustomLeveledLogger(leveledLogger retryablehttp.LeveledLogger) ClientOptionFunc {
|
||||
return func(c *Client) error {
|
||||
c.client.Logger = leveledLogger
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithCustomLimiter injects a custom rate limiter to the client.
|
||||
func WithCustomLimiter(limiter RateLimiter) ClientOptionFunc {
|
||||
return func(c *Client) error {
|
||||
c.configureLimiterOnce.Do(func() {
|
||||
c.limiter = limiter
|
||||
})
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithCustomLogger can be used to configure a custom retryablehttp logger.
|
||||
func WithCustomLogger(logger retryablehttp.Logger) ClientOptionFunc {
|
||||
return func(c *Client) error {
|
||||
c.client.Logger = logger
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithCustomRetry can be used to configure a custom retry policy.
|
||||
func WithCustomRetry(checkRetry retryablehttp.CheckRetry) ClientOptionFunc {
|
||||
return func(c *Client) error {
|
||||
c.client.CheckRetry = checkRetry
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithHTTPClient can be used to configure a custom HTTP client.
|
||||
func WithHTTPClient(httpClient *http.Client) ClientOptionFunc {
|
||||
return func(c *Client) error {
|
||||
c.client.HTTPClient = httpClient
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// WithoutRetries disables the default retry logic.
|
||||
func WithoutRetries() ClientOptionFunc {
|
||||
return func(c *Client) error {
|
||||
c.disableRetries = true
|
||||
return nil
|
||||
}
|
||||
}
|
593
vendor/github.com/xanzy/go-gitlab/commits.go
generated
vendored
Normal file
593
vendor/github.com/xanzy/go-gitlab/commits.go
generated
vendored
Normal file
|
@ -0,0 +1,593 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// CommitsService handles communication with the commit related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html
|
||||
type CommitsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Commit represents a GitLab commit.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html
|
||||
type Commit struct {
|
||||
ID string `json:"id"`
|
||||
ShortID string `json:"short_id"`
|
||||
Title string `json:"title"`
|
||||
AuthorName string `json:"author_name"`
|
||||
AuthorEmail string `json:"author_email"`
|
||||
AuthoredDate *time.Time `json:"authored_date"`
|
||||
CommitterName string `json:"committer_name"`
|
||||
CommitterEmail string `json:"committer_email"`
|
||||
CommittedDate *time.Time `json:"committed_date"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
Message string `json:"message"`
|
||||
ParentIDs []string `json:"parent_ids"`
|
||||
Stats *CommitStats `json:"stats"`
|
||||
Status *BuildStateValue `json:"status"`
|
||||
LastPipeline *PipelineInfo `json:"last_pipeline"`
|
||||
ProjectID int `json:"project_id"`
|
||||
WebURL string `json:"web_url"`
|
||||
}
|
||||
|
||||
// CommitStats represents the number of added and deleted files in a commit.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html
|
||||
type CommitStats struct {
|
||||
Additions int `json:"additions"`
|
||||
Deletions int `json:"deletions"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
func (c Commit) String() string {
|
||||
return Stringify(c)
|
||||
}
|
||||
|
||||
// ListCommitsOptions represents the available ListCommits() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#list-repository-commits
|
||||
type ListCommitsOptions struct {
|
||||
ListOptions
|
||||
RefName *string `url:"ref_name,omitempty" json:"ref_name,omitempty"`
|
||||
Since *time.Time `url:"since,omitempty" json:"since,omitempty"`
|
||||
Until *time.Time `url:"until,omitempty" json:"until,omitempty"`
|
||||
Path *string `url:"path,omitempty" json:"path,omitempty"`
|
||||
All *bool `url:"all,omitempty" json:"all,omitempty"`
|
||||
WithStats *bool `url:"with_stats,omitempty" json:"with_stats,omitempty"`
|
||||
FirstParent *bool `url:"first_parent,omitempty" json:"first_parent,omitempty"`
|
||||
}
|
||||
|
||||
// ListCommits gets a list of repository commits in a project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#list-commits
|
||||
func (s *CommitsService) ListCommits(pid interface{}, opt *ListCommitsOptions, options ...RequestOptionFunc) ([]*Commit, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var c []*Commit
|
||||
resp, err := s.client.Do(req, &c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// CommitRef represents the reference of branches/tags in a commit.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#get-references-a-commit-is-pushed-to
|
||||
type CommitRef struct {
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
// GetCommitRefsOptions represents the available GetCommitRefs() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#get-references-a-commit-is-pushed-to
|
||||
type GetCommitRefsOptions struct {
|
||||
ListOptions
|
||||
Type *string `url:"type,omitempty" json:"type,omitempty"`
|
||||
}
|
||||
|
||||
// GetCommitRefs gets all references (from branches or tags) a commit is pushed to
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#get-references-a-commit-is-pushed-to
|
||||
func (s *CommitsService) GetCommitRefs(pid interface{}, sha string, opt *GetCommitRefsOptions, options ...RequestOptionFunc) ([]*CommitRef, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/refs", pathEscape(project), url.PathEscape(sha))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var cs []*CommitRef
|
||||
resp, err := s.client.Do(req, &cs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return cs, resp, err
|
||||
}
|
||||
|
||||
// GetCommit gets a specific commit identified by the commit hash or name of a
|
||||
// branch or tag.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-a-single-commit
|
||||
func (s *CommitsService) GetCommit(pid interface{}, sha string, options ...RequestOptionFunc) (*Commit, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if sha == "" {
|
||||
return nil, nil, fmt.Errorf("SHA must be a non-empty string")
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s", pathEscape(project), url.PathEscape(sha))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
c := new(Commit)
|
||||
resp, err := s.client.Do(req, c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// CreateCommitOptions represents the available options for a new commit.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions
|
||||
type CreateCommitOptions struct {
|
||||
Branch *string `url:"branch,omitempty" json:"branch,omitempty"`
|
||||
CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"`
|
||||
StartBranch *string `url:"start_branch,omitempty" json:"start_branch,omitempty"`
|
||||
StartSHA *string `url:"start_sha,omitempty" json:"start_sha,omitempty"`
|
||||
StartProject *string `url:"start_project,omitempty" json:"start_project,omitempty"`
|
||||
Actions []*CommitActionOptions `url:"actions" json:"actions"`
|
||||
AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"`
|
||||
AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"`
|
||||
Stats *bool `url:"stats,omitempty" json:"stats,omitempty"`
|
||||
Force *bool `url:"force,omitempty" json:"force,omitempty"`
|
||||
}
|
||||
|
||||
// CommitActionOptions represents the available options for a new single
|
||||
// file action.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions
|
||||
type CommitActionOptions struct {
|
||||
Action *FileActionValue `url:"action,omitempty" json:"action,omitempty"`
|
||||
FilePath *string `url:"file_path,omitempty" json:"file_path,omitempty"`
|
||||
PreviousPath *string `url:"previous_path,omitempty" json:"previous_path,omitempty"`
|
||||
Content *string `url:"content,omitempty" json:"content,omitempty"`
|
||||
Encoding *string `url:"encoding,omitempty" json:"encoding,omitempty"`
|
||||
LastCommitID *string `url:"last_commit_id,omitempty" json:"last_commit_id,omitempty"`
|
||||
ExecuteFilemode *bool `url:"execute_filemode,omitempty" json:"execute_filemode,omitempty"`
|
||||
}
|
||||
|
||||
// CreateCommit creates a commit with multiple files and actions.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions
|
||||
func (s *CommitsService) CreateCommit(pid interface{}, opt *CreateCommitOptions, options ...RequestOptionFunc) (*Commit, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
c := new(Commit)
|
||||
resp, err := s.client.Do(req, &c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// Diff represents a GitLab diff.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html
|
||||
type Diff struct {
|
||||
Diff string `json:"diff"`
|
||||
NewPath string `json:"new_path"`
|
||||
OldPath string `json:"old_path"`
|
||||
AMode string `json:"a_mode"`
|
||||
BMode string `json:"b_mode"`
|
||||
NewFile bool `json:"new_file"`
|
||||
RenamedFile bool `json:"renamed_file"`
|
||||
DeletedFile bool `json:"deleted_file"`
|
||||
}
|
||||
|
||||
func (d Diff) String() string {
|
||||
return Stringify(d)
|
||||
}
|
||||
|
||||
// GetCommitDiffOptions represents the available GetCommitDiff() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#get-the-diff-of-a-commit
|
||||
type GetCommitDiffOptions ListOptions
|
||||
|
||||
// GetCommitDiff gets the diff of a commit in a project..
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#get-the-diff-of-a-commit
|
||||
func (s *CommitsService) GetCommitDiff(pid interface{}, sha string, opt *GetCommitDiffOptions, options ...RequestOptionFunc) ([]*Diff, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/diff", pathEscape(project), url.PathEscape(sha))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var d []*Diff
|
||||
resp, err := s.client.Do(req, &d)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return d, resp, err
|
||||
}
|
||||
|
||||
// CommitComment represents a GitLab commit comment.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html
|
||||
type CommitComment struct {
|
||||
Note string `json:"note"`
|
||||
Path string `json:"path"`
|
||||
Line int `json:"line"`
|
||||
LineType string `json:"line_type"`
|
||||
Author Author `json:"author"`
|
||||
}
|
||||
|
||||
// Author represents a GitLab commit author
|
||||
type Author struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
Blocked bool `json:"blocked"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func (c CommitComment) String() string {
|
||||
return Stringify(c)
|
||||
}
|
||||
|
||||
// GetCommitCommentsOptions represents the available GetCommitComments() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#get-the-comments-of-a-commit
|
||||
type GetCommitCommentsOptions ListOptions
|
||||
|
||||
// GetCommitComments gets the comments of a commit in a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#get-the-comments-of-a-commit
|
||||
func (s *CommitsService) GetCommitComments(pid interface{}, sha string, opt *GetCommitCommentsOptions, options ...RequestOptionFunc) ([]*CommitComment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/comments", pathEscape(project), url.PathEscape(sha))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var c []*CommitComment
|
||||
resp, err := s.client.Do(req, &c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// PostCommitCommentOptions represents the available PostCommitComment()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#post-comment-to-commit
|
||||
type PostCommitCommentOptions struct {
|
||||
Note *string `url:"note,omitempty" json:"note,omitempty"`
|
||||
Path *string `url:"path" json:"path"`
|
||||
Line *int `url:"line" json:"line"`
|
||||
LineType *string `url:"line_type" json:"line_type"`
|
||||
}
|
||||
|
||||
// PostCommitComment adds a comment to a commit. Optionally you can post
|
||||
// comments on a specific line of a commit. Therefor both path, line_new and
|
||||
// line_old are required.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#post-comment-to-commit
|
||||
func (s *CommitsService) PostCommitComment(pid interface{}, sha string, opt *PostCommitCommentOptions, options ...RequestOptionFunc) (*CommitComment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/comments", pathEscape(project), url.PathEscape(sha))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
c := new(CommitComment)
|
||||
resp, err := s.client.Do(req, c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// GetCommitStatusesOptions represents the available GetCommitStatuses() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-the-status-of-a-commit
|
||||
type GetCommitStatusesOptions struct {
|
||||
ListOptions
|
||||
Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
|
||||
Stage *string `url:"stage,omitempty" json:"stage,omitempty"`
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
All *bool `url:"all,omitempty" json:"all,omitempty"`
|
||||
}
|
||||
|
||||
// CommitStatus represents a GitLab commit status.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-the-status-of-a-commit
|
||||
type CommitStatus struct {
|
||||
ID int `json:"id"`
|
||||
SHA string `json:"sha"`
|
||||
Ref string `json:"ref"`
|
||||
Status string `json:"status"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
StartedAt *time.Time `json:"started_at"`
|
||||
FinishedAt *time.Time `json:"finished_at"`
|
||||
Name string `json:"name"`
|
||||
AllowFailure bool `json:"allow_failure"`
|
||||
Author Author `json:"author"`
|
||||
Description string `json:"description"`
|
||||
TargetURL string `json:"target_url"`
|
||||
}
|
||||
|
||||
// GetCommitStatuses gets the statuses of a commit in a project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-the-status-of-a-commit
|
||||
func (s *CommitsService) GetCommitStatuses(pid interface{}, sha string, opt *GetCommitStatusesOptions, options ...RequestOptionFunc) ([]*CommitStatus, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/statuses", pathEscape(project), url.PathEscape(sha))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var cs []*CommitStatus
|
||||
resp, err := s.client.Do(req, &cs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return cs, resp, err
|
||||
}
|
||||
|
||||
// SetCommitStatusOptions represents the available SetCommitStatus() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#post-the-status-to-commit
|
||||
type SetCommitStatusOptions struct {
|
||||
State BuildStateValue `url:"state" json:"state"`
|
||||
Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Context *string `url:"context,omitempty" json:"context,omitempty"`
|
||||
TargetURL *string `url:"target_url,omitempty" json:"target_url,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
Coverage *float64 `url:"coverage,omitempty" json:"coverage,omitempty"`
|
||||
PipelineID *int `url:"pipeline_id,omitempty" json:"pipeline_id,omitempty"`
|
||||
}
|
||||
|
||||
// SetCommitStatus sets the status of a commit in a project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#post-the-status-to-commit
|
||||
func (s *CommitsService) SetCommitStatus(pid interface{}, sha string, opt *SetCommitStatusOptions, options ...RequestOptionFunc) (*CommitStatus, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/statuses/%s", pathEscape(project), url.PathEscape(sha))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
cs := new(CommitStatus)
|
||||
resp, err := s.client.Do(req, &cs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return cs, resp, err
|
||||
}
|
||||
|
||||
// GetMergeRequestsByCommit gets merge request associated with a commit.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#list-merge-requests-associated-with-a-commit
|
||||
func (s *CommitsService) GetMergeRequestsByCommit(pid interface{}, sha string, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/merge_requests", pathEscape(project), url.PathEscape(sha))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var mrs []*MergeRequest
|
||||
resp, err := s.client.Do(req, &mrs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return mrs, resp, err
|
||||
}
|
||||
|
||||
// CherryPickCommitOptions represents the available CherryPickCommit() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#cherry-pick-a-commit
|
||||
type CherryPickCommitOptions struct {
|
||||
Branch *string `url:"branch,omitempty" json:"branch,omitempty"`
|
||||
DryRun *bool `url:"dry_run,omitempty" json:"dry_run,omitempty"`
|
||||
Message *string `url:"message,omitempty" json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// CherryPickCommit cherry picks a commit to a given branch.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#cherry-pick-a-commit
|
||||
func (s *CommitsService) CherryPickCommit(pid interface{}, sha string, opt *CherryPickCommitOptions, options ...RequestOptionFunc) (*Commit, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/cherry_pick", pathEscape(project), url.PathEscape(sha))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
c := new(Commit)
|
||||
resp, err := s.client.Do(req, &c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// RevertCommitOptions represents the available RevertCommit() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/commits.html#revert-a-commit
|
||||
type RevertCommitOptions struct {
|
||||
Branch *string `url:"branch,omitempty" json:"branch,omitempty"`
|
||||
}
|
||||
|
||||
// RevertCommit reverts a commit in a given branch.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/commits.html#revert-a-commit
|
||||
func (s *CommitsService) RevertCommit(pid interface{}, sha string, opt *RevertCommitOptions, options ...RequestOptionFunc) (*Commit, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/revert", pathEscape(project), url.PathEscape(sha))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
c := new(Commit)
|
||||
resp, err := s.client.Do(req, &c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// GPGSignature represents a Gitlab commit's GPG Signature.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/commits.html#get-gpg-signature-of-a-commit
|
||||
type GPGSignature struct {
|
||||
KeyID int `json:"gpg_key_id"`
|
||||
KeyPrimaryKeyID string `json:"gpg_key_primary_keyid"`
|
||||
KeyUserName string `json:"gpg_key_user_name"`
|
||||
KeyUserEmail string `json:"gpg_key_user_email"`
|
||||
VerificationStatus string `json:"verification_status"`
|
||||
KeySubkeyID int `json:"gpg_key_subkey_id"`
|
||||
}
|
||||
|
||||
// GetGPGSiganature gets a GPG signature of a commit.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/commits.html#get-gpg-signature-of-a-commit
|
||||
func (s *CommitsService) GetGPGSiganature(pid interface{}, sha string, options ...RequestOptionFunc) (*GPGSignature, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/signature", pathEscape(project), url.PathEscape(sha))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
sig := new(GPGSignature)
|
||||
resp, err := s.client.Do(req, &sig)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return sig, resp, err
|
||||
}
|
247
vendor/github.com/xanzy/go-gitlab/container_registry.go
generated
vendored
Normal file
247
vendor/github.com/xanzy/go-gitlab/container_registry.go
generated
vendored
Normal file
|
@ -0,0 +1,247 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ContainerRegistryService handles communication with the container registry
|
||||
// related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/container_registry.html
|
||||
type ContainerRegistryService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// RegistryRepository represents a GitLab content registry repository.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/container_registry.html
|
||||
type RegistryRepository struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
Location string `json:"location"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
CleanupPolicyStartedAt *time.Time `json:"cleanup_policy_started_at"`
|
||||
TagsCount int `json:"tags_count"`
|
||||
Tags []*RegistryRepositoryTag `json:"tags"`
|
||||
}
|
||||
|
||||
func (s RegistryRepository) String() string {
|
||||
return Stringify(s)
|
||||
}
|
||||
|
||||
// RegistryRepositoryTag represents a GitLab registry image tag.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/container_registry.html
|
||||
type RegistryRepositoryTag struct {
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
Location string `json:"location"`
|
||||
Revision string `json:"revision"`
|
||||
ShortRevision string `json:"short_revision"`
|
||||
Digest string `json:"digest"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
TotalSize int `json:"total_size"`
|
||||
}
|
||||
|
||||
func (s RegistryRepositoryTag) String() string {
|
||||
return Stringify(s)
|
||||
}
|
||||
|
||||
// ListRegistryRepositoriesOptions represents the available
|
||||
// ListRegistryRepositories() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/container_registry.html#list-registry-repositories
|
||||
type ListRegistryRepositoriesOptions struct {
|
||||
ListOptions
|
||||
Tags *bool `url:"tags,omitempty" json:"tags,omitempty"`
|
||||
TagsCount *bool `url:"tags_count,omitempty" json:"tags_count,omitempty"`
|
||||
}
|
||||
|
||||
// ListRegistryRepositories gets a list of registry repositories in a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/container_registry.html#list-registry-repositories
|
||||
func (s *ContainerRegistryService) ListRegistryRepositories(pid interface{}, opt *ListRegistryRepositoriesOptions, options ...RequestOptionFunc) ([]*RegistryRepository, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/registry/repositories", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var repos []*RegistryRepository
|
||||
resp, err := s.client.Do(req, &repos)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return repos, resp, err
|
||||
}
|
||||
|
||||
// DeleteRegistryRepository deletes a repository in a registry.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/container_registry.html#delete-registry-repository
|
||||
func (s *ContainerRegistryService) DeleteRegistryRepository(pid interface{}, repository int, options ...RequestOptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/registry/repositories/%d", pathEscape(project), repository)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// ListRegistryRepositoryTagsOptions represents the available
|
||||
// ListRegistryRepositoryTags() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/container_registry.html#list-registry-repository-tags
|
||||
type ListRegistryRepositoryTagsOptions ListOptions
|
||||
|
||||
// ListRegistryRepositoryTags gets a list of tags for given registry repository.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/container_registry.html#list-registry-repository-tags
|
||||
func (s *ContainerRegistryService) ListRegistryRepositoryTags(pid interface{}, repository int, opt *ListRegistryRepositoryTagsOptions, options ...RequestOptionFunc) ([]*RegistryRepositoryTag, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/registry/repositories/%d/tags",
|
||||
pathEscape(project),
|
||||
repository,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var tags []*RegistryRepositoryTag
|
||||
resp, err := s.client.Do(req, &tags)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return tags, resp, err
|
||||
}
|
||||
|
||||
// GetRegistryRepositoryTagDetail get details of a registry repository tag
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/container_registry.html#get-details-of-a-registry-repository-tag
|
||||
func (s *ContainerRegistryService) GetRegistryRepositoryTagDetail(pid interface{}, repository int, tagName string, options ...RequestOptionFunc) (*RegistryRepositoryTag, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/registry/repositories/%d/tags/%s",
|
||||
pathEscape(project),
|
||||
repository,
|
||||
tagName,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
tag := new(RegistryRepositoryTag)
|
||||
resp, err := s.client.Do(req, &tag)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return tag, resp, err
|
||||
}
|
||||
|
||||
// DeleteRegistryRepositoryTag deletes a registry repository tag.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/container_registry.html#delete-a-registry-repository-tag
|
||||
func (s *ContainerRegistryService) DeleteRegistryRepositoryTag(pid interface{}, repository int, tagName string, options ...RequestOptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/registry/repositories/%d/tags/%s",
|
||||
pathEscape(project),
|
||||
repository,
|
||||
tagName,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// DeleteRegistryRepositoryTagsOptions represents the available
|
||||
// DeleteRegistryRepositoryTags() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/container_registry.html#delete-repository-tags-in-bulk
|
||||
type DeleteRegistryRepositoryTagsOptions struct {
|
||||
NameRegexpDelete *string `url:"name_regex_delete,omitempty" json:"name_regex_delete,omitempty"`
|
||||
NameRegexpKeep *string `url:"name_regex_keep,omitempty" json:"name_regex_keep,omitempty"`
|
||||
KeepN *int `url:"keep_n,omitempty" json:"keep_n,omitempty"`
|
||||
OlderThan *string `url:"older_than,omitempty" json:"older_than,omitempty"`
|
||||
|
||||
// Deprecated members
|
||||
NameRegexp *string `url:"name_regex,omitempty" json:"name_regex,omitempty"`
|
||||
}
|
||||
|
||||
// DeleteRegistryRepositoryTags deletes repository tags in bulk based on
|
||||
// given criteria.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/container_registry.html#delete-repository-tags-in-bulk
|
||||
func (s *ContainerRegistryService) DeleteRegistryRepositoryTags(pid interface{}, repository int, opt *DeleteRegistryRepositoryTagsOptions, options ...RequestOptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/registry/repositories/%d/tags",
|
||||
pathEscape(project),
|
||||
repository,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
188
vendor/github.com/xanzy/go-gitlab/custom_attributes.go
generated
vendored
Normal file
188
vendor/github.com/xanzy/go-gitlab/custom_attributes.go
generated
vendored
Normal file
|
@ -0,0 +1,188 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// CustomAttributesService handles communication with the group, project and
|
||||
// user custom attributes related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/custom_attributes.html
|
||||
type CustomAttributesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// CustomAttribute struct is used to unmarshal response to api calls.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/custom_attributes.html
|
||||
type CustomAttribute struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
// ListCustomUserAttributes lists the custom attributes of the specified user.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/custom_attributes.html#list-custom-attributes
|
||||
func (s *CustomAttributesService) ListCustomUserAttributes(user int, options ...RequestOptionFunc) ([]*CustomAttribute, *Response, error) {
|
||||
return s.listCustomAttributes("users", user, options...)
|
||||
}
|
||||
|
||||
// ListCustomGroupAttributes lists the custom attributes of the specified group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/custom_attributes.html#list-custom-attributes
|
||||
func (s *CustomAttributesService) ListCustomGroupAttributes(group int, options ...RequestOptionFunc) ([]*CustomAttribute, *Response, error) {
|
||||
return s.listCustomAttributes("groups", group, options...)
|
||||
}
|
||||
|
||||
// ListCustomProjectAttributes lists the custom attributes of the specified project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/custom_attributes.html#list-custom-attributes
|
||||
func (s *CustomAttributesService) ListCustomProjectAttributes(project int, options ...RequestOptionFunc) ([]*CustomAttribute, *Response, error) {
|
||||
return s.listCustomAttributes("projects", project, options...)
|
||||
}
|
||||
|
||||
func (s *CustomAttributesService) listCustomAttributes(resource string, id int, options ...RequestOptionFunc) ([]*CustomAttribute, *Response, error) {
|
||||
u := fmt.Sprintf("%s/%d/custom_attributes", resource, id)
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var cas []*CustomAttribute
|
||||
resp, err := s.client.Do(req, &cas)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
return cas, resp, err
|
||||
}
|
||||
|
||||
// GetCustomUserAttribute returns the user attribute with a speciifc key.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/custom_attributes.html#single-custom-attribute
|
||||
func (s *CustomAttributesService) GetCustomUserAttribute(user int, key string, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) {
|
||||
return s.getCustomAttribute("users", user, key, options...)
|
||||
}
|
||||
|
||||
// GetCustomGroupAttribute returns the group attribute with a speciifc key.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/custom_attributes.html#single-custom-attribute
|
||||
func (s *CustomAttributesService) GetCustomGroupAttribute(group int, key string, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) {
|
||||
return s.getCustomAttribute("groups", group, key, options...)
|
||||
}
|
||||
|
||||
// GetCustomProjectAttribute returns the project attribute with a speciifc key.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/custom_attributes.html#single-custom-attribute
|
||||
func (s *CustomAttributesService) GetCustomProjectAttribute(project int, key string, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) {
|
||||
return s.getCustomAttribute("projects", project, key, options...)
|
||||
}
|
||||
|
||||
func (s *CustomAttributesService) getCustomAttribute(resource string, id int, key string, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) {
|
||||
u := fmt.Sprintf("%s/%d/custom_attributes/%s", resource, id, key)
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ca *CustomAttribute
|
||||
resp, err := s.client.Do(req, &ca)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
return ca, resp, err
|
||||
}
|
||||
|
||||
// SetCustomUserAttribute sets the custom attributes of the specified user.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/custom_attributes.html#set-custom-attribute
|
||||
func (s *CustomAttributesService) SetCustomUserAttribute(user int, c CustomAttribute, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) {
|
||||
return s.setCustomAttribute("users", user, c, options...)
|
||||
}
|
||||
|
||||
// SetCustomGroupAttribute sets the custom attributes of the specified group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/custom_attributes.html#set-custom-attribute
|
||||
func (s *CustomAttributesService) SetCustomGroupAttribute(group int, c CustomAttribute, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) {
|
||||
return s.setCustomAttribute("groups", group, c, options...)
|
||||
}
|
||||
|
||||
// SetCustomProjectAttribute sets the custom attributes of the specified project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/custom_attributes.html#set-custom-attribute
|
||||
func (s *CustomAttributesService) SetCustomProjectAttribute(project int, c CustomAttribute, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) {
|
||||
return s.setCustomAttribute("projects", project, c, options...)
|
||||
}
|
||||
|
||||
func (s *CustomAttributesService) setCustomAttribute(resource string, id int, c CustomAttribute, options ...RequestOptionFunc) (*CustomAttribute, *Response, error) {
|
||||
u := fmt.Sprintf("%s/%d/custom_attributes/%s", resource, id, c.Key)
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, c, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ca := new(CustomAttribute)
|
||||
resp, err := s.client.Do(req, ca)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
return ca, resp, err
|
||||
}
|
||||
|
||||
// DeleteCustomUserAttribute removes the custom attribute of the specified user.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/custom_attributes.html#delete-custom-attribute
|
||||
func (s *CustomAttributesService) DeleteCustomUserAttribute(user int, key string, options ...RequestOptionFunc) (*Response, error) {
|
||||
return s.deleteCustomAttribute("users", user, key, options...)
|
||||
}
|
||||
|
||||
// DeleteCustomGroupAttribute removes the custom attribute of the specified group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/custom_attributes.html#delete-custom-attribute
|
||||
func (s *CustomAttributesService) DeleteCustomGroupAttribute(group int, key string, options ...RequestOptionFunc) (*Response, error) {
|
||||
return s.deleteCustomAttribute("groups", group, key, options...)
|
||||
}
|
||||
|
||||
// DeleteCustomProjectAttribute removes the custom attribute of the specified project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/custom_attributes.html#delete-custom-attribute
|
||||
func (s *CustomAttributesService) DeleteCustomProjectAttribute(project int, key string, options ...RequestOptionFunc) (*Response, error) {
|
||||
return s.deleteCustomAttribute("projects", project, key, options...)
|
||||
}
|
||||
|
||||
func (s *CustomAttributesService) deleteCustomAttribute(resource string, id int, key string, options ...RequestOptionFunc) (*Response, error) {
|
||||
u := fmt.Sprintf("%s/%d/custom_attributes/%s", resource, id, key)
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s.client.Do(req, nil)
|
||||
}
|
235
vendor/github.com/xanzy/go-gitlab/deploy_keys.go
generated
vendored
Normal file
235
vendor/github.com/xanzy/go-gitlab/deploy_keys.go
generated
vendored
Normal file
|
@ -0,0 +1,235 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DeployKeysService handles communication with the keys related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/deploy_keys.html
|
||||
type DeployKeysService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// DeployKey represents a GitLab deploy key.
|
||||
type DeployKey struct {
|
||||
ID int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Key string `json:"key"`
|
||||
CanPush *bool `json:"can_push"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func (k DeployKey) String() string {
|
||||
return Stringify(k)
|
||||
}
|
||||
|
||||
// ListAllDeployKeys gets a list of all deploy keys
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#list-all-deploy-keys
|
||||
func (s *DeployKeysService) ListAllDeployKeys(options ...RequestOptionFunc) ([]*DeployKey, *Response, error) {
|
||||
req, err := s.client.NewRequest(http.MethodGet, "deploy_keys", nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ks []*DeployKey
|
||||
resp, err := s.client.Do(req, &ks)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ks, resp, err
|
||||
}
|
||||
|
||||
// ListProjectDeployKeysOptions represents the available ListProjectDeployKeys()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#list-project-deploy-keys
|
||||
type ListProjectDeployKeysOptions ListOptions
|
||||
|
||||
// ListProjectDeployKeys gets a list of a project's deploy keys
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#list-project-deploy-keys
|
||||
func (s *DeployKeysService) ListProjectDeployKeys(pid interface{}, opt *ListProjectDeployKeysOptions, options ...RequestOptionFunc) ([]*DeployKey, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deploy_keys", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ks []*DeployKey
|
||||
resp, err := s.client.Do(req, &ks)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ks, resp, err
|
||||
}
|
||||
|
||||
// GetDeployKey gets a single deploy key.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#single-deploy-key
|
||||
func (s *DeployKeysService) GetDeployKey(pid interface{}, deployKey int, options ...RequestOptionFunc) (*DeployKey, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deploy_keys/%d", pathEscape(project), deployKey)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
k := new(DeployKey)
|
||||
resp, err := s.client.Do(req, k)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return k, resp, err
|
||||
}
|
||||
|
||||
// AddDeployKeyOptions represents the available ADDDeployKey() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#add-deploy-key
|
||||
type AddDeployKeyOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Key *string `url:"key,omitempty" json:"key,omitempty"`
|
||||
CanPush *bool `url:"can_push,omitempty" json:"can_push,omitempty"`
|
||||
}
|
||||
|
||||
// AddDeployKey creates a new deploy key for a project. If deploy key already
|
||||
// exists in another project - it will be joined to project but only if
|
||||
// original one was is accessible by same user.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#add-deploy-key
|
||||
func (s *DeployKeysService) AddDeployKey(pid interface{}, opt *AddDeployKeyOptions, options ...RequestOptionFunc) (*DeployKey, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deploy_keys", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
k := new(DeployKey)
|
||||
resp, err := s.client.Do(req, k)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return k, resp, err
|
||||
}
|
||||
|
||||
// DeleteDeployKey deletes a deploy key from a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#delete-deploy-key
|
||||
func (s *DeployKeysService) DeleteDeployKey(pid interface{}, deployKey int, options ...RequestOptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deploy_keys/%d", pathEscape(project), deployKey)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// EnableDeployKey enables a deploy key.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#enable-a-deploy-key
|
||||
func (s *DeployKeysService) EnableDeployKey(pid interface{}, deployKey int, options ...RequestOptionFunc) (*DeployKey, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deploy_keys/%d/enable", pathEscape(project), deployKey)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
k := new(DeployKey)
|
||||
resp, err := s.client.Do(req, k)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return k, resp, err
|
||||
}
|
||||
|
||||
// UpdateDeployKeyOptions represents the available UpdateDeployKey() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#update-deploy-key
|
||||
type UpdateDeployKeyOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
CanPush *bool `url:"can_push,omitempty" json:"can_push,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateDeployKey updates a deploy key for a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#update-deploy-key
|
||||
func (s *DeployKeysService) UpdateDeployKey(pid interface{}, deployKey int, opt *UpdateDeployKeyOptions, options ...RequestOptionFunc) (*DeployKey, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deploy_keys/%d", pathEscape(project), deployKey)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
k := new(DeployKey)
|
||||
resp, err := s.client.Do(req, k)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return k, resp, err
|
||||
}
|
238
vendor/github.com/xanzy/go-gitlab/deploy_tokens.go
generated
vendored
Normal file
238
vendor/github.com/xanzy/go-gitlab/deploy_tokens.go
generated
vendored
Normal file
|
@ -0,0 +1,238 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DeployTokensService handles communication with the deploy tokens related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/deploy_tokens.html
|
||||
type DeployTokensService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// DeployToken represents a GitLab deploy token.
|
||||
type DeployToken struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
ExpiresAt *time.Time `json:"expires_at"`
|
||||
Token string `json:"token,omitempty"`
|
||||
Scopes []string `json:"scopes"`
|
||||
}
|
||||
|
||||
func (k DeployToken) String() string {
|
||||
return Stringify(k)
|
||||
}
|
||||
|
||||
// ListAllDeployTokens gets a list of all deploy tokens.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_tokens.html#list-all-deploy-tokens
|
||||
func (s *DeployTokensService) ListAllDeployTokens(options ...RequestOptionFunc) ([]*DeployToken, *Response, error) {
|
||||
req, err := s.client.NewRequest(http.MethodGet, "deploy_tokens", nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ts []*DeployToken
|
||||
resp, err := s.client.Do(req, &ts)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ts, resp, err
|
||||
}
|
||||
|
||||
// ListProjectDeployTokensOptions represents the available ListProjectDeployTokens()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_tokens.html#list-project-deploy-tokens
|
||||
type ListProjectDeployTokensOptions ListOptions
|
||||
|
||||
// ListProjectDeployTokens gets a list of a project's deploy tokens.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_tokens.html#list-project-deploy-tokens
|
||||
func (s *DeployTokensService) ListProjectDeployTokens(pid interface{}, opt *ListProjectDeployTokensOptions, options ...RequestOptionFunc) ([]*DeployToken, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deploy_tokens", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ts []*DeployToken
|
||||
resp, err := s.client.Do(req, &ts)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ts, resp, err
|
||||
}
|
||||
|
||||
// CreateProjectDeployTokenOptions represents the available CreateProjectDeployToken() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_tokens.html#create-a-project-deploy-token
|
||||
type CreateProjectDeployTokenOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
ExpiresAt *time.Time `url:"expires_at,omitempty" json:"expires_at,omitempty"`
|
||||
Username *string `url:"username,omitempty" json:"username,omitempty"`
|
||||
Scopes []string `url:"scopes,omitempty" json:"scopes,omitempty"`
|
||||
}
|
||||
|
||||
// CreateProjectDeployToken creates a new deploy token for a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_tokens.html#create-a-project-deploy-token
|
||||
func (s *DeployTokensService) CreateProjectDeployToken(pid interface{}, opt *CreateProjectDeployTokenOptions, options ...RequestOptionFunc) (*DeployToken, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deploy_tokens", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
t := new(DeployToken)
|
||||
resp, err := s.client.Do(req, t)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return t, resp, err
|
||||
}
|
||||
|
||||
// DeleteProjectDeployToken removes a deploy token from the project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_tokens.html#delete-a-project-deploy-token
|
||||
func (s *DeployTokensService) DeleteProjectDeployToken(pid interface{}, deployToken int, options ...RequestOptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deploy_tokens/%d", pathEscape(project), deployToken)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// ListGroupDeployTokensOptions represents the available ListGroupDeployTokens()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_tokens.html#list-group-deploy-deploy-tokens
|
||||
type ListGroupDeployTokensOptions ListOptions
|
||||
|
||||
// ListGroupDeployTokens gets a list of a group’s deploy tokens.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_tokens.html#list-project-deploy-tokens
|
||||
func (s *DeployTokensService) ListGroupDeployTokens(gid interface{}, opt *ListGroupDeployTokensOptions, options ...RequestOptionFunc) ([]*DeployToken, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/deploy_tokens", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ts []*DeployToken
|
||||
resp, err := s.client.Do(req, &ts)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ts, resp, err
|
||||
}
|
||||
|
||||
// CreateGroupDeployTokenOptions represents the available CreateGroupDeployToken() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_tokens.html#create-a-group-deploy-token
|
||||
type CreateGroupDeployTokenOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
ExpiresAt *time.Time `url:"expires_at,omitempty" json:"expires_at,omitempty"`
|
||||
Username *string `url:"username,omitempty" json:"username,omitempty"`
|
||||
Scopes []string `url:"scopes,omitempty" json:"scopes,omitempty"`
|
||||
}
|
||||
|
||||
// CreateGroupDeployToken creates a new deploy token for a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_tokens.html#create-a-group-deploy-token
|
||||
func (s *DeployTokensService) CreateGroupDeployToken(gid interface{}, opt *CreateGroupDeployTokenOptions, options ...RequestOptionFunc) (*DeployToken, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/deploy_tokens", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
t := new(DeployToken)
|
||||
resp, err := s.client.Do(req, t)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return t, resp, err
|
||||
}
|
||||
|
||||
// DeleteGroupDeployToken removes a deploy token from the group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_tokens.html#delete-a-group-deploy-token
|
||||
func (s *DeployTokensService) DeleteGroupDeployToken(gid interface{}, deployToken int, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/deploy_tokens/%d", pathEscape(group), deployToken)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
203
vendor/github.com/xanzy/go-gitlab/deployments.go
generated
vendored
Normal file
203
vendor/github.com/xanzy/go-gitlab/deployments.go
generated
vendored
Normal file
|
@ -0,0 +1,203 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// DeploymentsService handles communication with the deployment related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/deployments.html
|
||||
type DeploymentsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Deployment represents the Gitlab deployment
|
||||
type Deployment struct {
|
||||
ID int `json:"id"`
|
||||
IID int `json:"iid"`
|
||||
Ref string `json:"ref"`
|
||||
SHA string `json:"sha"`
|
||||
Status string `json:"status"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
User *ProjectUser `json:"user"`
|
||||
Environment *Environment `json:"environment"`
|
||||
Deployable struct {
|
||||
ID int `json:"id"`
|
||||
Status string `json:"status"`
|
||||
Stage string `json:"stage"`
|
||||
Name string `json:"name"`
|
||||
Ref string `json:"ref"`
|
||||
Tag bool `json:"tag"`
|
||||
Coverage float64 `json:"coverage"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
StartedAt *time.Time `json:"started_at"`
|
||||
FinishedAt *time.Time `json:"finished_at"`
|
||||
Duration float64 `json:"duration"`
|
||||
User *User `json:"user"`
|
||||
Commit *Commit `json:"commit"`
|
||||
Pipeline struct {
|
||||
ID int `json:"id"`
|
||||
SHA string `json:"sha"`
|
||||
Ref string `json:"ref"`
|
||||
Status string `json:"status"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
} `json:"pipeline"`
|
||||
Runner *Runner `json:"runner"`
|
||||
} `json:"deployable"`
|
||||
}
|
||||
|
||||
// ListProjectDeploymentsOptions represents the available ListProjectDeployments() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deployments.html#list-project-deployments
|
||||
type ListProjectDeploymentsOptions struct {
|
||||
ListOptions
|
||||
OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
|
||||
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
|
||||
Environment *string `url:"environment,omitempty" json:"environment,omitempty"`
|
||||
Status *string `url:"status,omitempty" json:"status,omitempty"`
|
||||
|
||||
// Only for Gitlab versions less than 14
|
||||
UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"`
|
||||
UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"`
|
||||
|
||||
// Only for Gitlab 14 or higher
|
||||
FinishedAfter *time.Time `url:"finished_after,omitempty" json:"finished_after,omitempty"`
|
||||
FinishedBefore *time.Time `url:"finished_before,omitempty" json:"finished_before,omitempty"`
|
||||
}
|
||||
|
||||
// ListProjectDeployments gets a list of deployments in a project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/deployments.html#list-project-deployments
|
||||
func (s *DeploymentsService) ListProjectDeployments(pid interface{}, opts *ListProjectDeploymentsOptions, options ...RequestOptionFunc) ([]*Deployment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deployments", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opts, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ds []*Deployment
|
||||
resp, err := s.client.Do(req, &ds)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ds, resp, err
|
||||
}
|
||||
|
||||
// GetProjectDeployment get a deployment for a project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/deployments.html#get-a-specific-deployment
|
||||
func (s *DeploymentsService) GetProjectDeployment(pid interface{}, deployment int, options ...RequestOptionFunc) (*Deployment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deployments/%d", pathEscape(project), deployment)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
d := new(Deployment)
|
||||
resp, err := s.client.Do(req, d)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return d, resp, err
|
||||
}
|
||||
|
||||
// CreateProjectDeploymentOptions represents the available
|
||||
// CreateProjectDeployment() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/deployments.html#create-a-deployment
|
||||
type CreateProjectDeploymentOptions struct {
|
||||
Environment *string `url:"environment,omitempty" json:"environment,omitempty"`
|
||||
Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
|
||||
SHA *string `url:"sha,omitempty" json:"sha,omitempty"`
|
||||
Tag *bool `url:"tag,omitempty" json:"tag,omitempty"`
|
||||
Status *DeploymentStatusValue `url:"status,omitempty" json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// CreateProjectDeployment creates a project deployment.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/deployments.html#create-a-deployment
|
||||
func (s *DeploymentsService) CreateProjectDeployment(pid interface{}, opt *CreateProjectDeploymentOptions, options ...RequestOptionFunc) (*Deployment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deployments", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
d := new(Deployment)
|
||||
resp, err := s.client.Do(req, &d)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return d, resp, err
|
||||
}
|
||||
|
||||
// UpdateProjectDeploymentOptions represents the available
|
||||
// UpdateProjectDeployment() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/deployments.html#updating-a-deployment
|
||||
type UpdateProjectDeploymentOptions struct {
|
||||
Status *DeploymentStatusValue `url:"status,omitempty" json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateProjectDeployment updates a project deployment.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/deployments.html#updating-a-deployment
|
||||
func (s *DeploymentsService) UpdateProjectDeployment(pid interface{}, deployment int, opt *UpdateProjectDeploymentOptions, options ...RequestOptionFunc) (*Deployment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/deployments/%d", pathEscape(project), deployment)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
d := new(Deployment)
|
||||
resp, err := s.client.Do(req, &d)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return d, resp, err
|
||||
}
|
1114
vendor/github.com/xanzy/go-gitlab/discussions.go
generated
vendored
Normal file
1114
vendor/github.com/xanzy/go-gitlab/discussions.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
218
vendor/github.com/xanzy/go-gitlab/environments.go
generated
vendored
Normal file
218
vendor/github.com/xanzy/go-gitlab/environments.go
generated
vendored
Normal file
|
@ -0,0 +1,218 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// EnvironmentsService handles communication with the environment related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/environments.html
|
||||
type EnvironmentsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Environment represents a GitLab environment.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/environments.html
|
||||
type Environment struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Slug string `json:"slug"`
|
||||
State string `json:"state"`
|
||||
ExternalURL string `json:"external_url"`
|
||||
Project *Project `json:"project"`
|
||||
LastDeployment *Deployment `json:"last_deployment"`
|
||||
}
|
||||
|
||||
func (env Environment) String() string {
|
||||
return Stringify(env)
|
||||
}
|
||||
|
||||
// ListEnvironmentsOptions represents the available ListEnvironments() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/environments.html#list-environments
|
||||
type ListEnvironmentsOptions struct {
|
||||
ListOptions
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Search *string `url:"search,omitempty" json:"search,omitempty"`
|
||||
States *string `url:"states,omitempty" json:"states,omitempty"`
|
||||
}
|
||||
|
||||
// ListEnvironments gets a list of environments from a project, sorted by name
|
||||
// alphabetically.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/environments.html#list-environments
|
||||
func (s *EnvironmentsService) ListEnvironments(pid interface{}, opts *ListEnvironmentsOptions, options ...RequestOptionFunc) ([]*Environment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/environments", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opts, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var envs []*Environment
|
||||
resp, err := s.client.Do(req, &envs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return envs, resp, err
|
||||
}
|
||||
|
||||
// GetEnvironment gets a specific environment from a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/environments.html#get-a-specific-environment
|
||||
func (s *EnvironmentsService) GetEnvironment(pid interface{}, environment int, options ...RequestOptionFunc) (*Environment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/environments/%d", pathEscape(project), environment)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
env := new(Environment)
|
||||
resp, err := s.client.Do(req, env)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return env, resp, err
|
||||
}
|
||||
|
||||
// CreateEnvironmentOptions represents the available CreateEnvironment() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/environments.html#create-a-new-environment
|
||||
type CreateEnvironmentOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
ExternalURL *string `url:"external_url,omitempty" json:"external_url,omitempty"`
|
||||
}
|
||||
|
||||
// CreateEnvironment adds an environment to a project. This is an idempotent
|
||||
// method and can be called multiple times with the same parameters. Createing
|
||||
// an environment that is already a environment does not affect the
|
||||
// existing environmentship.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/environments.html#create-a-new-environment
|
||||
func (s *EnvironmentsService) CreateEnvironment(pid interface{}, opt *CreateEnvironmentOptions, options ...RequestOptionFunc) (*Environment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/environments", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
env := new(Environment)
|
||||
resp, err := s.client.Do(req, env)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return env, resp, err
|
||||
}
|
||||
|
||||
// EditEnvironmentOptions represents the available EditEnvironment() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/environments.html#edit-an-existing-environment
|
||||
type EditEnvironmentOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
ExternalURL *string `url:"external_url,omitempty" json:"external_url,omitempty"`
|
||||
}
|
||||
|
||||
// EditEnvironment updates a project team environment to a specified access level..
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/environments.html#edit-an-existing-environment
|
||||
func (s *EnvironmentsService) EditEnvironment(pid interface{}, environment int, opt *EditEnvironmentOptions, options ...RequestOptionFunc) (*Environment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/environments/%d", pathEscape(project), environment)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
env := new(Environment)
|
||||
resp, err := s.client.Do(req, env)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return env, resp, err
|
||||
}
|
||||
|
||||
// DeleteEnvironment removes an environment from a project team.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/environments.html#remove-a-environment-from-a-group-or-project
|
||||
func (s *EnvironmentsService) DeleteEnvironment(pid interface{}, environment int, options ...RequestOptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/environments/%d", pathEscape(project), environment)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// StopEnvironment stop an environment from a project team.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/environments.html#stop-an-environment
|
||||
func (s *EnvironmentsService) StopEnvironment(pid interface{}, environmentID int, options ...RequestOptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/environments/%d/stop", pathEscape(project), environmentID)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
152
vendor/github.com/xanzy/go-gitlab/epic_issues.go
generated
vendored
Normal file
152
vendor/github.com/xanzy/go-gitlab/epic_issues.go
generated
vendored
Normal file
|
@ -0,0 +1,152 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// EpicIssuesService handles communication with the epic issue related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/epic_issues.html
|
||||
type EpicIssuesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// EpicIssueAssignment contains both the epic and issue objects returned from
|
||||
// Gitlab with the assignment ID.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/epic_issues.html
|
||||
type EpicIssueAssignment struct {
|
||||
ID int `json:"id"`
|
||||
Epic *Epic `json:"epic"`
|
||||
Issue *Issue `json:"issue"`
|
||||
}
|
||||
|
||||
// ListEpicIssues get a list of epic issues.
|
||||
//
|
||||
// Gitlab API docs:
|
||||
// https://docs.gitlab.com/ee/api/epic_issues.html#list-issues-for-an-epic
|
||||
func (s *EpicIssuesService) ListEpicIssues(gid interface{}, epic int, opt *ListOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/epics/%d/issues", pathEscape(group), epic)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var is []*Issue
|
||||
resp, err := s.client.Do(req, &is)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return is, resp, err
|
||||
}
|
||||
|
||||
// AssignEpicIssue assigns an existing issue to an epic.
|
||||
//
|
||||
// Gitlab API Docs:
|
||||
// https://docs.gitlab.com/ee/api/epic_issues.html#assign-an-issue-to-the-epic
|
||||
func (s *EpicIssuesService) AssignEpicIssue(gid interface{}, epic, issue int, options ...RequestOptionFunc) (*EpicIssueAssignment, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/epics/%d/issues/%d", pathEscape(group), epic, issue)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
a := new(EpicIssueAssignment)
|
||||
resp, err := s.client.Do(req, a)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return a, resp, err
|
||||
}
|
||||
|
||||
// RemoveEpicIssue removes an issue from an epic.
|
||||
//
|
||||
// Gitlab API Docs:
|
||||
// https://docs.gitlab.com/ee/api/epic_issues.html#remove-an-issue-from-the-epic
|
||||
func (s *EpicIssuesService) RemoveEpicIssue(gid interface{}, epic, epicIssue int, options ...RequestOptionFunc) (*EpicIssueAssignment, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/epics/%d/issues/%d", pathEscape(group), epic, epicIssue)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
a := new(EpicIssueAssignment)
|
||||
resp, err := s.client.Do(req, a)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return a, resp, err
|
||||
}
|
||||
|
||||
// UpdateEpicIsssueAssignmentOptions describes the UpdateEpicIssueAssignment()
|
||||
// options.
|
||||
//
|
||||
// Gitlab API Docs:
|
||||
// https://docs.gitlab.com/ee/api/epic_issues.html#update-epic---issue-association
|
||||
type UpdateEpicIsssueAssignmentOptions struct {
|
||||
*ListOptions
|
||||
MoveBeforeID *int `url:"move_before_id,omitempty" json:"move_before_id,omitempty"`
|
||||
MoveAfterID *int `url:"move_after_id,omitempty" json:"move_after_id,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateEpicIssueAssignment moves an issue before or after another issue in an
|
||||
// epic issue list.
|
||||
//
|
||||
// Gitlab API Docs:
|
||||
// https://docs.gitlab.com/ee/api/epic_issues.html#update-epic---issue-association
|
||||
func (s *EpicIssuesService) UpdateEpicIssueAssignment(gid interface{}, epic, epicIssue int, opt *UpdateEpicIsssueAssignmentOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/epics/%d/issues/%d", pathEscape(group), epic, epicIssue)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var is []*Issue
|
||||
resp, err := s.client.Do(req, &is)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return is, resp, err
|
||||
}
|
263
vendor/github.com/xanzy/go-gitlab/epics.go
generated
vendored
Normal file
263
vendor/github.com/xanzy/go-gitlab/epics.go
generated
vendored
Normal file
|
@ -0,0 +1,263 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// EpicsService handles communication with the epic related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html
|
||||
type EpicsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// EpicAuthor represents a author of the epic.
|
||||
type EpicAuthor struct {
|
||||
ID int `json:"id"`
|
||||
State string `json:"state"`
|
||||
WebURL string `json:"web_url"`
|
||||
Name string `json:"name"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
Username string `json:"username"`
|
||||
}
|
||||
|
||||
// Epic represents a GitLab epic.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html
|
||||
type Epic struct {
|
||||
ID int `json:"id"`
|
||||
IID int `json:"iid"`
|
||||
GroupID int `json:"group_id"`
|
||||
ParentID int `json:"parent_id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
State string `json:"state"`
|
||||
WebURL string `json:"web_url"`
|
||||
Author *EpicAuthor `json:"author"`
|
||||
StartDate *ISOTime `json:"start_date"`
|
||||
StartDateIsFixed bool `json:"start_date_is_fixed"`
|
||||
StartDateFixed *ISOTime `json:"start_date_fixed"`
|
||||
StartDateFromMilestones *ISOTime `json:"start_date_from_milestones"`
|
||||
DueDate *ISOTime `json:"due_date"`
|
||||
DueDateIsFixed bool `json:"due_date_is_fixed"`
|
||||
DueDateFixed *ISOTime `json:"due_date_fixed"`
|
||||
DueDateFromMilestones *ISOTime `json:"due_date_from_milestones"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
Labels []string `json:"labels"`
|
||||
Upvotes int `json:"upvotes"`
|
||||
Downvotes int `json:"downvotes"`
|
||||
UserNotesCount int `json:"user_notes_count"`
|
||||
URL string `json:"url"`
|
||||
}
|
||||
|
||||
func (e Epic) String() string {
|
||||
return Stringify(e)
|
||||
}
|
||||
|
||||
// ListGroupEpicsOptions represents the available ListGroupEpics() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#list-epics-for-a-group
|
||||
type ListGroupEpicsOptions struct {
|
||||
ListOptions
|
||||
AuthorID *int `url:"author_id,omitempty" json:"author_id,omitempty"`
|
||||
Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
|
||||
WithLabelDetails *bool `url:"with_labels_details,omitempty" json:"with_labels_details,omitempty"`
|
||||
OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
|
||||
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
|
||||
Search *string `url:"search,omitempty" json:"search,omitempty"`
|
||||
State *string `url:"state,omitempty" json:"state,omitempty"`
|
||||
CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"`
|
||||
CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"`
|
||||
UpdatedAfter *time.Time `url:"updated_after,omitempty" json:"updated_after,omitempty"`
|
||||
UpdatedBefore *time.Time `url:"updated_before,omitempty" json:"updated_before,omitempty"`
|
||||
IncludeAncestorGroups *bool `url:"include_ancestor_groups,omitempty" json:"include_ancestor_groups,omitempty"`
|
||||
IncludeDescendantGroups *bool `url:"include_descendant_groups,omitempty" json:"include_descendant_groups,omitempty"`
|
||||
MyReactionEmoji *string `url:"my_reaction_emoji,omitempty" json:"my_reaction_emoji,omitempty"`
|
||||
}
|
||||
|
||||
// ListGroupEpics gets a list of group epics. This function accepts pagination
|
||||
// parameters page and per_page to return the list of group epics.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#list-epics-for-a-group
|
||||
func (s *EpicsService) ListGroupEpics(gid interface{}, opt *ListGroupEpicsOptions, options ...RequestOptionFunc) ([]*Epic, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/epics", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var es []*Epic
|
||||
resp, err := s.client.Do(req, &es)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return es, resp, err
|
||||
}
|
||||
|
||||
// GetEpic gets a single group epic.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#single-epic
|
||||
func (s *EpicsService) GetEpic(gid interface{}, epic int, options ...RequestOptionFunc) (*Epic, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/epics/%d", pathEscape(group), epic)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
e := new(Epic)
|
||||
resp, err := s.client.Do(req, e)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return e, resp, err
|
||||
}
|
||||
|
||||
// GetEpicLinks gets all child epics of an epic.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/epic_links.html
|
||||
func (s *EpicsService) GetEpicLinks(gid interface{}, epic int, options ...RequestOptionFunc) ([]*Epic, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/epics/%d/epics", pathEscape(group), epic)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var e []*Epic
|
||||
resp, err := s.client.Do(req, &e)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return e, resp, err
|
||||
}
|
||||
|
||||
// CreateEpicOptions represents the available CreateEpic() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#new-epic
|
||||
type CreateEpicOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
|
||||
StartDateIsFixed *bool `url:"start_date_is_fixed,omitempty" json:"start_date_is_fixed,omitempty"`
|
||||
StartDateFixed *ISOTime `url:"start_date_fixed,omitempty" json:"start_date_fixed,omitempty"`
|
||||
DueDateIsFixed *bool `url:"due_date_is_fixed,omitempty" json:"due_date_is_fixed,omitempty"`
|
||||
DueDateFixed *ISOTime `url:"due_date_fixed,omitempty" json:"due_date_fixed,omitempty"`
|
||||
}
|
||||
|
||||
// CreateEpic creates a new group epic.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#new-epic
|
||||
func (s *EpicsService) CreateEpic(gid interface{}, opt *CreateEpicOptions, options ...RequestOptionFunc) (*Epic, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/epics", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
e := new(Epic)
|
||||
resp, err := s.client.Do(req, e)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return e, resp, err
|
||||
}
|
||||
|
||||
// UpdateEpicOptions represents the available UpdateEpic() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#update-epic
|
||||
type UpdateEpicOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
|
||||
StartDateIsFixed *bool `url:"start_date_is_fixed,omitempty" json:"start_date_is_fixed,omitempty"`
|
||||
StartDateFixed *ISOTime `url:"start_date_fixed,omitempty" json:"start_date_fixed,omitempty"`
|
||||
DueDateIsFixed *bool `url:"due_date_is_fixed,omitempty" json:"due_date_is_fixed,omitempty"`
|
||||
DueDateFixed *ISOTime `url:"due_date_fixed,omitempty" json:"due_date_fixed,omitempty"`
|
||||
StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateEpic updates an existing group epic. This function is also used
|
||||
// to mark an epic as closed.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#update-epic
|
||||
func (s *EpicsService) UpdateEpic(gid interface{}, epic int, opt *UpdateEpicOptions, options ...RequestOptionFunc) (*Epic, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/epics/%d", pathEscape(group), epic)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
e := new(Epic)
|
||||
resp, err := s.client.Do(req, e)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return e, resp, err
|
||||
}
|
||||
|
||||
// DeleteEpic deletes a single group epic.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/epics.html#delete-epic
|
||||
func (s *EpicsService) DeleteEpic(gid interface{}, epic int, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/epics/%d", pathEscape(group), epic)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
255
vendor/github.com/xanzy/go-gitlab/event_parsing.go
generated
vendored
Normal file
255
vendor/github.com/xanzy/go-gitlab/event_parsing.go
generated
vendored
Normal file
|
@ -0,0 +1,255 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// EventType represents a Gitlab event type.
|
||||
type EventType string
|
||||
|
||||
// List of available event types.
|
||||
const (
|
||||
EventTypeBuild EventType = "Build Hook"
|
||||
EventTypeDeployment EventType = "Deployment Hook"
|
||||
EventTypeIssue EventType = "Issue Hook"
|
||||
EventConfidentialIssue EventType = "Confidential Issue Hook"
|
||||
EventTypeJob EventType = "Job Hook"
|
||||
EventTypeMergeRequest EventType = "Merge Request Hook"
|
||||
EventTypeNote EventType = "Note Hook"
|
||||
EventConfidentialNote EventType = "Confidential Note Hook"
|
||||
EventTypePipeline EventType = "Pipeline Hook"
|
||||
EventTypePush EventType = "Push Hook"
|
||||
EventTypeRelease EventType = "Release Hook"
|
||||
EventTypeSystemHook EventType = "System Hook"
|
||||
EventTypeTagPush EventType = "Tag Push Hook"
|
||||
EventTypeWikiPage EventType = "Wiki Page Hook"
|
||||
)
|
||||
|
||||
const (
|
||||
noteableTypeCommit = "Commit"
|
||||
noteableTypeMergeRequest = "MergeRequest"
|
||||
noteableTypeIssue = "Issue"
|
||||
noteableTypeSnippet = "Snippet"
|
||||
)
|
||||
|
||||
type noteEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
ObjectAttributes struct {
|
||||
NoteableType string `json:"noteable_type"`
|
||||
} `json:"object_attributes"`
|
||||
}
|
||||
|
||||
const eventTypeHeader = "X-Gitlab-Event"
|
||||
|
||||
// HookEventType returns the event type for the given request.
|
||||
func HookEventType(r *http.Request) EventType {
|
||||
return EventType(r.Header.Get(eventTypeHeader))
|
||||
}
|
||||
|
||||
// ParseHook tries to parse both web- and system hooks.
|
||||
//
|
||||
// Example usage:
|
||||
//
|
||||
// func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// payload, err := ioutil.ReadAll(r.Body)
|
||||
// if err != nil { ... }
|
||||
// event, err := gitlab.ParseHook(gitlab.HookEventType(r), payload)
|
||||
// if err != nil { ... }
|
||||
// switch event := event.(type) {
|
||||
// case *gitlab.PushEvent:
|
||||
// processPushEvent(event)
|
||||
// case *gitlab.MergeEvent:
|
||||
// processMergeEvent(event)
|
||||
// ...
|
||||
// }
|
||||
// }
|
||||
//
|
||||
func ParseHook(eventType EventType, payload []byte) (event interface{}, err error) {
|
||||
switch eventType {
|
||||
case EventTypeSystemHook:
|
||||
return ParseSystemhook(payload)
|
||||
default:
|
||||
return ParseWebhook(eventType, payload)
|
||||
}
|
||||
}
|
||||
|
||||
// ParseSystemhook parses the event payload. For recognized event types, a
|
||||
// value of the corresponding struct type will be returned. An error will be
|
||||
// returned for unrecognized event types.
|
||||
//
|
||||
// Example usage:
|
||||
//
|
||||
// func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// payload, err := ioutil.ReadAll(r.Body)
|
||||
// if err != nil { ... }
|
||||
// event, err := gitlab.ParseSystemhook(payload)
|
||||
// if err != nil { ... }
|
||||
// switch event := event.(type) {
|
||||
// case *gitlab.PushSystemEvent:
|
||||
// processPushSystemEvent(event)
|
||||
// case *gitlab.MergeSystemEvent:
|
||||
// processMergeSystemEvent(event)
|
||||
// ...
|
||||
// }
|
||||
// }
|
||||
//
|
||||
func ParseSystemhook(payload []byte) (event interface{}, err error) {
|
||||
e := &systemHookEvent{}
|
||||
err = json.Unmarshal(payload, e)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
switch e.EventName {
|
||||
case "push":
|
||||
event = &PushSystemEvent{}
|
||||
case "tag_push":
|
||||
event = &TagPushSystemEvent{}
|
||||
case "repository_update":
|
||||
event = &RepositoryUpdateSystemEvent{}
|
||||
case
|
||||
"project_create",
|
||||
"project_update",
|
||||
"project_destroy",
|
||||
"project_transfer",
|
||||
"project_rename":
|
||||
event = &ProjectSystemEvent{}
|
||||
case
|
||||
"group_create",
|
||||
"group_destroy",
|
||||
"group_rename":
|
||||
event = &GroupSystemEvent{}
|
||||
case
|
||||
"key_create",
|
||||
"key_destroy":
|
||||
event = &KeySystemEvent{}
|
||||
case
|
||||
"user_create",
|
||||
"user_destroy",
|
||||
"user_rename":
|
||||
event = &UserSystemEvent{}
|
||||
case
|
||||
"user_add_to_group",
|
||||
"user_remove_from_group",
|
||||
"user_update_for_group":
|
||||
event = &UserGroupSystemEvent{}
|
||||
case
|
||||
"user_add_to_team",
|
||||
"user_remove_from_team",
|
||||
"user_update_for_team":
|
||||
event = &UserTeamSystemEvent{}
|
||||
default:
|
||||
switch e.ObjectKind {
|
||||
case string(MergeRequestEventTargetType):
|
||||
event = &MergeEvent{}
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected system hook type %s", e.EventName)
|
||||
}
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(payload, event); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return event, nil
|
||||
}
|
||||
|
||||
// WebhookEventType returns the event type for the given request.
|
||||
func WebhookEventType(r *http.Request) EventType {
|
||||
return EventType(r.Header.Get(eventTypeHeader))
|
||||
}
|
||||
|
||||
// ParseWebhook parses the event payload. For recognized event types, a
|
||||
// value of the corresponding struct type will be returned. An error will
|
||||
// be returned for unrecognized event types.
|
||||
//
|
||||
// Example usage:
|
||||
//
|
||||
// func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
// payload, err := ioutil.ReadAll(r.Body)
|
||||
// if err != nil { ... }
|
||||
// event, err := gitlab.ParseWebhook(gitlab.HookEventType(r), payload)
|
||||
// if err != nil { ... }
|
||||
// switch event := event.(type) {
|
||||
// case *gitlab.PushEvent:
|
||||
// processPushEvent(event)
|
||||
// case *gitlab.MergeEvent:
|
||||
// processMergeEvent(event)
|
||||
// ...
|
||||
// }
|
||||
// }
|
||||
//
|
||||
func ParseWebhook(eventType EventType, payload []byte) (event interface{}, err error) {
|
||||
switch eventType {
|
||||
case EventTypeBuild:
|
||||
event = &BuildEvent{}
|
||||
case EventTypeDeployment:
|
||||
event = &DeploymentEvent{}
|
||||
case EventTypeIssue, EventConfidentialIssue:
|
||||
event = &IssueEvent{}
|
||||
case EventTypeJob:
|
||||
event = &JobEvent{}
|
||||
case EventTypeMergeRequest:
|
||||
event = &MergeEvent{}
|
||||
case EventTypePipeline:
|
||||
event = &PipelineEvent{}
|
||||
case EventTypePush:
|
||||
event = &PushEvent{}
|
||||
case EventTypeRelease:
|
||||
event = &ReleaseEvent{}
|
||||
case EventTypeTagPush:
|
||||
event = &TagEvent{}
|
||||
case EventTypeWikiPage:
|
||||
event = &WikiPageEvent{}
|
||||
case EventTypeNote, EventConfidentialNote:
|
||||
note := ¬eEvent{}
|
||||
err := json.Unmarshal(payload, note)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if note.ObjectKind != string(NoteEventTargetType) {
|
||||
return nil, fmt.Errorf("unexpected object kind %s", note.ObjectKind)
|
||||
}
|
||||
|
||||
switch note.ObjectAttributes.NoteableType {
|
||||
case noteableTypeCommit:
|
||||
event = &CommitCommentEvent{}
|
||||
case noteableTypeMergeRequest:
|
||||
event = &MergeCommentEvent{}
|
||||
case noteableTypeIssue:
|
||||
event = &IssueCommentEvent{}
|
||||
case noteableTypeSnippet:
|
||||
event = &SnippetCommentEvent{}
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected noteable type %s", note.ObjectAttributes.NoteableType)
|
||||
}
|
||||
|
||||
default:
|
||||
return nil, fmt.Errorf("unexpected event type: %s", eventType)
|
||||
}
|
||||
|
||||
if err := json.Unmarshal(payload, event); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return event, nil
|
||||
}
|
149
vendor/github.com/xanzy/go-gitlab/event_systemhook_types.go
generated
vendored
Normal file
149
vendor/github.com/xanzy/go-gitlab/event_systemhook_types.go
generated
vendored
Normal file
|
@ -0,0 +1,149 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
// systemHookEvent is used to pre-process events to determine the
|
||||
// system hook event type.
|
||||
type systemHookEvent struct {
|
||||
BaseSystemEvent
|
||||
ObjectKind string `json:"object_kind"`
|
||||
}
|
||||
|
||||
// BaseSystemEvent contains system hook's common properties.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/system_hooks/system_hooks.html
|
||||
type BaseSystemEvent struct {
|
||||
EventName string `json:"event_name"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
}
|
||||
|
||||
// ProjectSystemEvent represents a project system event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/system_hooks/system_hooks.html
|
||||
type ProjectSystemEvent struct {
|
||||
BaseSystemEvent
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
ProjectID int `json:"project_id"`
|
||||
OwnerName string `json:"owner_name"`
|
||||
OwnerEmail string `json:"owner_email"`
|
||||
ProjectVisibility string `json:"project_visibility"`
|
||||
OldPathWithNamespace string `json:"old_path_with_namespace,omitempty"`
|
||||
}
|
||||
|
||||
// GroupSystemEvent represents a group system event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/system_hooks/system_hooks.html
|
||||
type GroupSystemEvent struct {
|
||||
BaseSystemEvent
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
PathWithNamespace string `json:"full_path"`
|
||||
GroupID int `json:"group_id"`
|
||||
OwnerName string `json:"owner_name"`
|
||||
OwnerEmail string `json:"owner_email"`
|
||||
ProjectVisibility string `json:"project_visibility"`
|
||||
OldPath string `json:"old_path,omitempty"`
|
||||
OldPathWithNamespace string `json:"old_full_path,omitempty"`
|
||||
}
|
||||
|
||||
// KeySystemEvent represents a key system event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/system_hooks/system_hooks.html
|
||||
type KeySystemEvent struct {
|
||||
BaseSystemEvent
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
// UserSystemEvent represents a user system event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/system_hooks/system_hooks.html
|
||||
type UserSystemEvent struct {
|
||||
BaseSystemEvent
|
||||
ID int `json:"user_id"`
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
OldUsername string `json:"old_username,omitempty"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
// UserGroupSystemEvent represents a user group system event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/system_hooks/system_hooks.html
|
||||
type UserGroupSystemEvent struct {
|
||||
BaseSystemEvent
|
||||
ID int `json:"user_id"`
|
||||
Name string `json:"user_name"`
|
||||
Username string `json:"user_username"`
|
||||
Email string `json:"user_email"`
|
||||
GroupID int `json:"group_id"`
|
||||
GroupName string `json:"group_name"`
|
||||
GroupPath string `json:"group_path"`
|
||||
GroupAccess string `json:"group_access"`
|
||||
}
|
||||
|
||||
// UserTeamSystemEvent represents a user team system event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/system_hooks/system_hooks.html
|
||||
type UserTeamSystemEvent struct {
|
||||
BaseSystemEvent
|
||||
ID int `json:"user_id"`
|
||||
Name string `json:"user_name"`
|
||||
Username string `json:"user_username"`
|
||||
Email string `json:"user_email"`
|
||||
ProjectID int `json:"project_id"`
|
||||
ProjectName string `json:"project_name"`
|
||||
ProjectPath string `json:"project_path"`
|
||||
ProjectPathWithNamespace string `json:"project_path_with_namespace"`
|
||||
ProjectVisibility string `json:"project_visibility"`
|
||||
AccessLevel string `json:"access_level"`
|
||||
}
|
||||
|
||||
// PushSystemEvent represents a push system event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/system_hooks/system_hooks.html
|
||||
type PushSystemEvent struct {
|
||||
BaseSystemEvent
|
||||
}
|
||||
|
||||
// TagPushSystemEvent represents a tag push system event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/system_hooks/system_hooks.html
|
||||
type TagPushSystemEvent struct {
|
||||
BaseSystemEvent
|
||||
}
|
||||
|
||||
// RepositoryUpdateSystemEvent represents a repository updated system event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/system_hooks/system_hooks.html
|
||||
type RepositoryUpdateSystemEvent struct {
|
||||
BaseSystemEvent
|
||||
}
|
951
vendor/github.com/xanzy/go-gitlab/event_webhook_types.go
generated
vendored
Normal file
951
vendor/github.com/xanzy/go-gitlab/event_webhook_types.go
generated
vendored
Normal file
|
@ -0,0 +1,951 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
//BuildEvent represents a build event
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#build-events
|
||||
type BuildEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
Ref string `json:"ref"`
|
||||
Tag bool `json:"tag"`
|
||||
BeforeSHA string `json:"before_sha"`
|
||||
SHA string `json:"sha"`
|
||||
BuildID int `json:"build_id"`
|
||||
BuildName string `json:"build_name"`
|
||||
BuildStage string `json:"build_stage"`
|
||||
BuildStatus string `json:"build_status"`
|
||||
BuildStartedAt string `json:"build_started_at"`
|
||||
BuildFinishedAt string `json:"build_finished_at"`
|
||||
BuildDuration float64 `json:"build_duration"`
|
||||
BuildAllowFailure bool `json:"build_allow_failure"`
|
||||
ProjectID int `json:"project_id"`
|
||||
ProjectName string `json:"project_name"`
|
||||
User *EventUser `json:"user"`
|
||||
Commit struct {
|
||||
ID int `json:"id"`
|
||||
SHA string `json:"sha"`
|
||||
Message string `json:"message"`
|
||||
AuthorName string `json:"author_name"`
|
||||
AuthorEmail string `json:"author_email"`
|
||||
Status string `json:"status"`
|
||||
Duration int `json:"duration"`
|
||||
StartedAt string `json:"started_at"`
|
||||
FinishedAt string `json:"finished_at"`
|
||||
} `json:"commit"`
|
||||
Repository *Repository `json:"repository"`
|
||||
}
|
||||
|
||||
// CommitCommentEvent represents a comment on a commit event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#comment-on-commit
|
||||
type CommitCommentEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
User *User `json:"user"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
Visibility VisibilityValue `json:"visibility"`
|
||||
} `json:"project"`
|
||||
Repository *Repository `json:"repository"`
|
||||
ObjectAttributes struct {
|
||||
ID int `json:"id"`
|
||||
Note string `json:"note"`
|
||||
NoteableType string `json:"noteable_type"`
|
||||
AuthorID int `json:"author_id"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Attachment string `json:"attachment"`
|
||||
LineCode string `json:"line_code"`
|
||||
CommitID string `json:"commit_id"`
|
||||
NoteableID int `json:"noteable_id"`
|
||||
System bool `json:"system"`
|
||||
StDiff struct {
|
||||
Diff string `json:"diff"`
|
||||
NewPath string `json:"new_path"`
|
||||
OldPath string `json:"old_path"`
|
||||
AMode string `json:"a_mode"`
|
||||
BMode string `json:"b_mode"`
|
||||
NewFile bool `json:"new_file"`
|
||||
RenamedFile bool `json:"renamed_file"`
|
||||
DeletedFile bool `json:"deleted_file"`
|
||||
} `json:"st_diff"`
|
||||
Description string `json:"description"`
|
||||
URL string `json:"url"`
|
||||
} `json:"object_attributes"`
|
||||
Commit *struct {
|
||||
ID string `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Message string `json:"message"`
|
||||
Timestamp *time.Time `json:"timestamp"`
|
||||
URL string `json:"url"`
|
||||
Author struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
} `json:"author"`
|
||||
} `json:"commit"`
|
||||
}
|
||||
|
||||
// DeploymentEvent represents a deployment event
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#deployment-events
|
||||
type DeploymentEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
Status string `json:"status"`
|
||||
DeployableID int `json:"deployable_id"`
|
||||
DeployableURL string `json:"deployable_url"`
|
||||
Environment string `json:"environment"`
|
||||
Project struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
WebURL string `json:"web_url"`
|
||||
AvatarURL *string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
VisibilityLevel int `json:"visibility_level"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
CIConfigPath string `json:"ci_config_path"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
} `json:"project"`
|
||||
ShortSHA string `json:"short_sha"`
|
||||
User *EventUser `json:"user"`
|
||||
UserURL string `json:"user_url"`
|
||||
CommitURL string `json:"commit_url"`
|
||||
CommitTitle string `json:"commit_title"`
|
||||
}
|
||||
|
||||
// IssueCommentEvent represents a comment on an issue event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#comment-on-issue
|
||||
type IssueCommentEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
User *User `json:"user"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
Visibility VisibilityValue `json:"visibility"`
|
||||
} `json:"project"`
|
||||
Repository *Repository `json:"repository"`
|
||||
ObjectAttributes struct {
|
||||
ID int `json:"id"`
|
||||
Note string `json:"note"`
|
||||
NoteableType string `json:"noteable_type"`
|
||||
AuthorID int `json:"author_id"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Attachment string `json:"attachment"`
|
||||
LineCode string `json:"line_code"`
|
||||
CommitID string `json:"commit_id"`
|
||||
NoteableID int `json:"noteable_id"`
|
||||
System bool `json:"system"`
|
||||
StDiff []*Diff `json:"st_diff"`
|
||||
Description string `json:"description"`
|
||||
URL string `json:"url"`
|
||||
} `json:"object_attributes"`
|
||||
Issue struct {
|
||||
ID int `json:"id"`
|
||||
IID int `json:"iid"`
|
||||
ProjectID int `json:"project_id"`
|
||||
MilestoneID int `json:"milestone_id"`
|
||||
AuthorID int `json:"author_id"`
|
||||
Description string `json:"description"`
|
||||
State string `json:"state"`
|
||||
Title string `json:"title"`
|
||||
Labels []Label `json:"labels"`
|
||||
LastEditedAt string `json:"last_edit_at"`
|
||||
LastEditedByID int `json:"last_edited_by_id"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
UpdatedByID int `json:"updated_by_id"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
ClosedAt string `json:"closed_at"`
|
||||
DueDate *ISOTime `json:"due_date"`
|
||||
URL string `json:"url"`
|
||||
TimeEstimate int `json:"time_estimate"`
|
||||
Confidential bool `json:"confidential"`
|
||||
TotalTimeSpent int `json:"total_time_spent"`
|
||||
HumanTotalTimeSpent string `json:"human_total_time_spent"`
|
||||
HumanTimeEstimate string `json:"human_time_estimate"`
|
||||
AssigneeIDs []int `json:"assignee_ids"`
|
||||
AssigneeID int `json:"assignee_id"`
|
||||
} `json:"issue"`
|
||||
}
|
||||
|
||||
// IssueEvent represents a issue event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#issues-events
|
||||
type IssueEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
User *EventUser `json:"user"`
|
||||
Project struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
Visibility VisibilityValue `json:"visibility"`
|
||||
} `json:"project"`
|
||||
Repository *Repository `json:"repository"`
|
||||
ObjectAttributes struct {
|
||||
ID int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
AssigneeID int `json:"assignee_id"`
|
||||
AuthorID int `json:"author_id"`
|
||||
ProjectID int `json:"project_id"`
|
||||
CreatedAt string `json:"created_at"` // Should be *time.Time (see Gitlab issue #21468)
|
||||
UpdatedAt string `json:"updated_at"` // Should be *time.Time (see Gitlab issue #21468)
|
||||
Position int `json:"position"`
|
||||
BranchName string `json:"branch_name"`
|
||||
Description string `json:"description"`
|
||||
MilestoneID int `json:"milestone_id"`
|
||||
State string `json:"state"`
|
||||
IID int `json:"iid"`
|
||||
URL string `json:"url"`
|
||||
Action string `json:"action"`
|
||||
} `json:"object_attributes"`
|
||||
Assignee *EventUser `json:"assignee"`
|
||||
Assignees *[]EventUser `json:"assignees"`
|
||||
Labels []Label `json:"labels"`
|
||||
Changes struct {
|
||||
Description struct {
|
||||
Previous string `json:"previous"`
|
||||
Current string `json:"current"`
|
||||
} `json:"description"`
|
||||
Labels struct {
|
||||
Previous []Label `json:"previous"`
|
||||
Current []Label `json:"current"`
|
||||
} `json:"labels"`
|
||||
Title struct {
|
||||
Previous string `json:"previous"`
|
||||
Current string `json:"current"`
|
||||
} `json:"title"`
|
||||
UpdatedByID struct {
|
||||
Previous int `json:"previous"`
|
||||
Current int `json:"current"`
|
||||
} `json:"updated_by_id"`
|
||||
TotalTimeSpent struct {
|
||||
Previous int `json:"previous"`
|
||||
Current int `json:"current"`
|
||||
} `json:"total_time_spent"`
|
||||
} `json:"changes"`
|
||||
}
|
||||
|
||||
// JobEvent represents a job event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// TODO: link to docs instead of src once they are published.
|
||||
// https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/gitlab/data_builder/build.rb
|
||||
type JobEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
Ref string `json:"ref"`
|
||||
Tag bool `json:"tag"`
|
||||
BeforeSHA string `json:"before_sha"`
|
||||
SHA string `json:"sha"`
|
||||
BuildID int `json:"build_id"`
|
||||
BuildName string `json:"build_name"`
|
||||
BuildStage string `json:"build_stage"`
|
||||
BuildStatus string `json:"build_status"`
|
||||
BuildStartedAt string `json:"build_started_at"`
|
||||
BuildFinishedAt string `json:"build_finished_at"`
|
||||
BuildDuration float64 `json:"build_duration"`
|
||||
BuildAllowFailure bool `json:"build_allow_failure"`
|
||||
BuildFailureReason string `json:"build_failure_reason"`
|
||||
PipelineID int `json:"pipeline_id"`
|
||||
ProjectID int `json:"project_id"`
|
||||
ProjectName string `json:"project_name"`
|
||||
User *EventUser `json:"user"`
|
||||
Commit struct {
|
||||
ID int `json:"id"`
|
||||
SHA string `json:"sha"`
|
||||
Message string `json:"message"`
|
||||
AuthorName string `json:"author_name"`
|
||||
AuthorEmail string `json:"author_email"`
|
||||
AuthorURL string `json:"author_url"`
|
||||
Status string `json:"status"`
|
||||
Duration int `json:"duration"`
|
||||
StartedAt string `json:"started_at"`
|
||||
FinishedAt string `json:"finished_at"`
|
||||
} `json:"commit"`
|
||||
Repository *Repository `json:"repository"`
|
||||
Runner struct {
|
||||
ID int `json:"id"`
|
||||
Active bool `json:"active"`
|
||||
Shared bool `json:"is_shared"`
|
||||
Description string `json:"description"`
|
||||
} `json:"runner"`
|
||||
}
|
||||
|
||||
// MergeCommentEvent represents a comment on a merge event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#comment-on-merge-request
|
||||
type MergeCommentEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
User *EventUser `json:"user"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
Visibility VisibilityValue `json:"visibility"`
|
||||
} `json:"project"`
|
||||
ObjectAttributes struct {
|
||||
Attachment string `json:"attachment"`
|
||||
AuthorID int `json:"author_id"`
|
||||
ChangePosition *NotePosition `json:"change_position"`
|
||||
CommitID string `json:"commit_id"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
DiscussionID string `json:"discussion_id"`
|
||||
ID int `json:"id"`
|
||||
LineCode string `json:"line_code"`
|
||||
Note string `json:"note"`
|
||||
NoteableID int `json:"noteable_id"`
|
||||
NoteableType string `json:"noteable_type"`
|
||||
OriginalPosition *NotePosition `json:"original_position"`
|
||||
Position *NotePosition `json:"position"`
|
||||
ProjectID int `json:"project_id"`
|
||||
ResolvedAt string `json:"resolved_at"`
|
||||
ResolvedByID int `json:"resolved_by_id"`
|
||||
ResolvedByPush bool `json:"resolved_by_push"`
|
||||
StDiff *Diff `json:"st_diff"`
|
||||
System bool `json:"system"`
|
||||
Type string `json:"type"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
UpdatedByID string `json:"updated_by_id"`
|
||||
Description string `json:"description"`
|
||||
URL string `json:"url"`
|
||||
} `json:"object_attributes"`
|
||||
Repository *Repository `json:"repository"`
|
||||
MergeRequest struct {
|
||||
ID int `json:"id"`
|
||||
TargetBranch string `json:"target_branch"`
|
||||
SourceBranch string `json:"source_branch"`
|
||||
SourceProjectID int `json:"source_project_id"`
|
||||
AuthorID int `json:"author_id"`
|
||||
AssigneeID int `json:"assignee_id"`
|
||||
AssigneeIDs []int `json:"assignee_ids"`
|
||||
Title string `json:"title"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
MilestoneID int `json:"milestone_id"`
|
||||
State string `json:"state"`
|
||||
MergeStatus string `json:"merge_status"`
|
||||
TargetProjectID int `json:"target_project_id"`
|
||||
IID int `json:"iid"`
|
||||
Description string `json:"description"`
|
||||
Position int `json:"position"`
|
||||
LockedAt string `json:"locked_at"`
|
||||
UpdatedByID int `json:"updated_by_id"`
|
||||
MergeError string `json:"merge_error"`
|
||||
MergeParams *MergeParams `json:"merge_params"`
|
||||
MergeWhenPipelineSucceeds bool `json:"merge_when_pipeline_succeeds"`
|
||||
MergeUserID int `json:"merge_user_id"`
|
||||
MergeCommitSHA string `json:"merge_commit_sha"`
|
||||
DeletedAt string `json:"deleted_at"`
|
||||
InProgressMergeCommitSHA string `json:"in_progress_merge_commit_sha"`
|
||||
LockVersion int `json:"lock_version"`
|
||||
ApprovalsBeforeMerge string `json:"approvals_before_merge"`
|
||||
RebaseCommitSHA string `json:"rebase_commit_sha"`
|
||||
TimeEstimate int `json:"time_estimate"`
|
||||
Squash bool `json:"squash"`
|
||||
LastEditedAt string `json:"last_edited_at"`
|
||||
LastEditedByID int `json:"last_edited_by_id"`
|
||||
Source *Repository `json:"source"`
|
||||
Target *Repository `json:"target"`
|
||||
LastCommit struct {
|
||||
ID string `json:"id"`
|
||||
Message string `json:"message"`
|
||||
Timestamp *time.Time `json:"timestamp"`
|
||||
URL string `json:"url"`
|
||||
Author struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
} `json:"author"`
|
||||
} `json:"last_commit"`
|
||||
WorkInProgress bool `json:"work_in_progress"`
|
||||
TotalTimeSpent int `json:"total_time_spent"`
|
||||
HeadPipelineID int `json:"head_pipeline_id"`
|
||||
} `json:"merge_request"`
|
||||
}
|
||||
|
||||
// MergeEvent represents a merge event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#merge-request-events
|
||||
type MergeEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
User *EventUser `json:"user"`
|
||||
Project struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
Visibility VisibilityValue `json:"visibility"`
|
||||
} `json:"project"`
|
||||
ObjectAttributes struct {
|
||||
ID int `json:"id"`
|
||||
TargetBranch string `json:"target_branch"`
|
||||
SourceBranch string `json:"source_branch"`
|
||||
SourceProjectID int `json:"source_project_id"`
|
||||
AuthorID int `json:"author_id"`
|
||||
AssigneeID int `json:"assignee_id"`
|
||||
AssigneeIDs []int `json:"assignee_ids"`
|
||||
Title string `json:"title"`
|
||||
CreatedAt string `json:"created_at"` // Should be *time.Time (see Gitlab issue #21468)
|
||||
UpdatedAt string `json:"updated_at"` // Should be *time.Time (see Gitlab issue #21468)
|
||||
StCommits []*Commit `json:"st_commits"`
|
||||
StDiffs []*Diff `json:"st_diffs"`
|
||||
MilestoneID int `json:"milestone_id"`
|
||||
State string `json:"state"`
|
||||
MergeStatus string `json:"merge_status"`
|
||||
TargetProjectID int `json:"target_project_id"`
|
||||
IID int `json:"iid"`
|
||||
Description string `json:"description"`
|
||||
Position int `json:"position"`
|
||||
LockedAt string `json:"locked_at"`
|
||||
UpdatedByID int `json:"updated_by_id"`
|
||||
MergeError string `json:"merge_error"`
|
||||
MergeParams *MergeParams `json:"merge_params"`
|
||||
MergeWhenBuildSucceeds bool `json:"merge_when_build_succeeds"`
|
||||
MergeUserID int `json:"merge_user_id"`
|
||||
MergeCommitSHA string `json:"merge_commit_sha"`
|
||||
DeletedAt string `json:"deleted_at"`
|
||||
ApprovalsBeforeMerge string `json:"approvals_before_merge"`
|
||||
RebaseCommitSHA string `json:"rebase_commit_sha"`
|
||||
InProgressMergeCommitSHA string `json:"in_progress_merge_commit_sha"`
|
||||
LockVersion int `json:"lock_version"`
|
||||
TimeEstimate int `json:"time_estimate"`
|
||||
Source *Repository `json:"source"`
|
||||
Target *Repository `json:"target"`
|
||||
HeadPipelineID *int `json:"head_pipeline_id"`
|
||||
LastCommit struct {
|
||||
ID string `json:"id"`
|
||||
Message string `json:"message"`
|
||||
Timestamp *time.Time `json:"timestamp"`
|
||||
URL string `json:"url"`
|
||||
Author struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
} `json:"author"`
|
||||
} `json:"last_commit"`
|
||||
WorkInProgress bool `json:"work_in_progress"`
|
||||
URL string `json:"url"`
|
||||
Action string `json:"action"`
|
||||
OldRev string `json:"oldrev"`
|
||||
Assignee *EventUser `json:"assignee"`
|
||||
} `json:"object_attributes"`
|
||||
Repository *Repository `json:"repository"`
|
||||
Assignee *EventUser `json:"assignee"`
|
||||
Assignees []*EventUser `json:"assignees"`
|
||||
Labels []*Label `json:"labels"`
|
||||
Changes struct {
|
||||
Assignees struct {
|
||||
Previous []*EventUser `json:"previous"`
|
||||
Current []*EventUser `json:"current"`
|
||||
} `json:"assignees"`
|
||||
Description struct {
|
||||
Previous string `json:"previous"`
|
||||
Current string `json:"current"`
|
||||
} `json:"description"`
|
||||
Labels struct {
|
||||
Previous []*Label `json:"previous"`
|
||||
Current []*Label `json:"current"`
|
||||
} `json:"labels"`
|
||||
SourceBranch struct {
|
||||
Previous string `json:"previous"`
|
||||
Current string `json:"current"`
|
||||
} `json:"source_branch"`
|
||||
SourceProjectID struct {
|
||||
Previous int `json:"previous"`
|
||||
Current int `json:"current"`
|
||||
} `json:"source_project_id"`
|
||||
StateID struct {
|
||||
Previous int `json:"previous"`
|
||||
Current int `json:"current"`
|
||||
} `json:"state_id"`
|
||||
TargetBranch struct {
|
||||
Previous string `json:"previous"`
|
||||
Current string `json:"current"`
|
||||
} `json:"target_branch"`
|
||||
TargetProjectID struct {
|
||||
Previous int `json:"previous"`
|
||||
Current int `json:"current"`
|
||||
} `json:"target_project_id"`
|
||||
Title struct {
|
||||
Previous string `json:"previous"`
|
||||
Current string `json:"current"`
|
||||
} `json:"title"`
|
||||
UpdatedByID struct {
|
||||
Previous int `json:"previous"`
|
||||
Current int `json:"current"`
|
||||
} `json:"updated_by_id"`
|
||||
MilestoneID struct {
|
||||
Previous int `json:"previous"`
|
||||
Current int `json:"current"`
|
||||
} `json:"milestone_id"`
|
||||
} `json:"changes"`
|
||||
}
|
||||
|
||||
// EventUser represents a user record in an event and is used as an even initiator or a merge assignee.
|
||||
type EventUser struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
// MergeParams represents the merge params.
|
||||
type MergeParams struct {
|
||||
ForceRemoveSourceBranch bool `json:"force_remove_source_branch"`
|
||||
}
|
||||
|
||||
// UnmarshalJSON decodes the merge parameters
|
||||
//
|
||||
// This allows support of ForceRemoveSourceBranch for both type bool (>11.9) and string (<11.9)
|
||||
func (p *MergeParams) UnmarshalJSON(b []byte) error {
|
||||
type Alias MergeParams
|
||||
raw := struct {
|
||||
*Alias
|
||||
ForceRemoveSourceBranch interface{} `json:"force_remove_source_branch"`
|
||||
}{
|
||||
Alias: (*Alias)(p),
|
||||
}
|
||||
|
||||
err := json.Unmarshal(b, &raw)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch v := raw.ForceRemoveSourceBranch.(type) {
|
||||
case nil:
|
||||
// No action needed.
|
||||
case bool:
|
||||
p.ForceRemoveSourceBranch = v
|
||||
case string:
|
||||
p.ForceRemoveSourceBranch, err = strconv.ParseBool(v)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("failed to unmarshal ForceRemoveSourceBranch of type: %T", v)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// PipelineEvent represents a pipeline event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#pipeline-events
|
||||
type PipelineEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
ObjectAttributes struct {
|
||||
ID int `json:"id"`
|
||||
Ref string `json:"ref"`
|
||||
Tag bool `json:"tag"`
|
||||
SHA string `json:"sha"`
|
||||
BeforeSHA string `json:"before_sha"`
|
||||
Source string `json:"source"`
|
||||
Status string `json:"status"`
|
||||
DetailedStatus string `json:"detailed_status"`
|
||||
Stages []string `json:"stages"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
FinishedAt string `json:"finished_at"`
|
||||
Duration int `json:"duration"`
|
||||
QueuedDuration int `json:"queued_duration"`
|
||||
} `json:"object_attributes"`
|
||||
MergeRequest struct {
|
||||
ID int `json:"id"`
|
||||
IID int `json:"iid"`
|
||||
Title string `json:"title"`
|
||||
SourceBranch string `json:"source_branch"`
|
||||
SourceProjectID int `json:"source_project_id"`
|
||||
TargetBranch string `json:"target_branch"`
|
||||
TargetProjectID int `json:"target_project_id"`
|
||||
State string `json:"state"`
|
||||
MergeRequestStatus string `json:"merge_status"`
|
||||
URL string `json:"url"`
|
||||
} `json:"merge_request"`
|
||||
User *EventUser `json:"user"`
|
||||
Project struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
Visibility VisibilityValue `json:"visibility"`
|
||||
} `json:"project"`
|
||||
Commit struct {
|
||||
ID string `json:"id"`
|
||||
Message string `json:"message"`
|
||||
Timestamp *time.Time `json:"timestamp"`
|
||||
URL string `json:"url"`
|
||||
Author struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
} `json:"author"`
|
||||
} `json:"commit"`
|
||||
Builds []struct {
|
||||
ID int `json:"id"`
|
||||
Stage string `json:"stage"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
StartedAt string `json:"started_at"`
|
||||
FinishedAt string `json:"finished_at"`
|
||||
When string `json:"when"`
|
||||
Manual bool `json:"manual"`
|
||||
AllowFailure bool `json:"allow_failure"`
|
||||
User *EventUser `json:"user"`
|
||||
Runner struct {
|
||||
ID int `json:"id"`
|
||||
Description string `json:"description"`
|
||||
Active bool `json:"active"`
|
||||
IsShared bool `json:"is_shared"`
|
||||
} `json:"runner"`
|
||||
ArtifactsFile struct {
|
||||
Filename string `json:"filename"`
|
||||
Size int `json:"size"`
|
||||
} `json:"artifacts_file"`
|
||||
} `json:"builds"`
|
||||
}
|
||||
|
||||
// PushEvent represents a push event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#push-events
|
||||
type PushEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
Before string `json:"before"`
|
||||
After string `json:"after"`
|
||||
Ref string `json:"ref"`
|
||||
CheckoutSHA string `json:"checkout_sha"`
|
||||
UserID int `json:"user_id"`
|
||||
UserName string `json:"user_name"`
|
||||
UserUsername string `json:"user_username"`
|
||||
UserEmail string `json:"user_email"`
|
||||
UserAvatar string `json:"user_avatar"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
Visibility VisibilityValue `json:"visibility"`
|
||||
} `json:"project"`
|
||||
Repository *Repository `json:"repository"`
|
||||
Commits []*struct {
|
||||
ID string `json:"id"`
|
||||
Message string `json:"message"`
|
||||
Timestamp *time.Time `json:"timestamp"`
|
||||
URL string `json:"url"`
|
||||
Author struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
} `json:"author"`
|
||||
Added []string `json:"added"`
|
||||
Modified []string `json:"modified"`
|
||||
Removed []string `json:"removed"`
|
||||
} `json:"commits"`
|
||||
TotalCommitsCount int `json:"total_commits_count"`
|
||||
}
|
||||
|
||||
// ReleaseEvent represents a release event
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#release-events
|
||||
type ReleaseEvent struct {
|
||||
ID int `json:"id"`
|
||||
CreatedAt string `json:"created_at"` // Should be *time.Time (see Gitlab issue #21468)
|
||||
Description string `json:"description"`
|
||||
Name string `json:"name"`
|
||||
Tag string `json:"tag"`
|
||||
ReleasedAt string `json:"released_at"` // Should be *time.Time (see Gitlab issue #21468)
|
||||
ObjectKind string `json:"object_kind"`
|
||||
Project struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
WebURL string `json:"web_url"`
|
||||
AvatarURL *string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
VisibilityLevel int `json:"visibility_level"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
CIConfigPath string `json:"ci_config_path"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
} `json:"project"`
|
||||
URL string `json:"url"`
|
||||
Action string `json:"action"`
|
||||
Assets struct {
|
||||
Count int `json:"count"`
|
||||
Links []struct {
|
||||
ID int `json:"id"`
|
||||
External bool `json:"external"`
|
||||
LinkType string `json:"link_type"`
|
||||
Name string `json:"name"`
|
||||
URL string `json:"url"`
|
||||
} `json:"links"`
|
||||
Sources []struct {
|
||||
Format string `json:"format"`
|
||||
URL string `json:"url"`
|
||||
} `json:"sources"`
|
||||
} `json:"assets"`
|
||||
Commit struct {
|
||||
ID string `json:"id"`
|
||||
Message string `json:"message"`
|
||||
Title string `json:"title"`
|
||||
Timestamp string `json:"timestamp"` // Should be *time.Time (see Gitlab issue #21468)
|
||||
URL string `json:"url"`
|
||||
Author struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
} `json:"author"`
|
||||
} `json:"commit"`
|
||||
}
|
||||
|
||||
// SnippetCommentEvent represents a comment on a snippet event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#comment-on-code-snippet
|
||||
type SnippetCommentEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
User *EventUser `json:"user"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
Visibility VisibilityValue `json:"visibility"`
|
||||
} `json:"project"`
|
||||
Repository *Repository `json:"repository"`
|
||||
ObjectAttributes struct {
|
||||
ID int `json:"id"`
|
||||
Note string `json:"note"`
|
||||
NoteableType string `json:"noteable_type"`
|
||||
AuthorID int `json:"author_id"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Attachment string `json:"attachment"`
|
||||
LineCode string `json:"line_code"`
|
||||
CommitID string `json:"commit_id"`
|
||||
NoteableID int `json:"noteable_id"`
|
||||
System bool `json:"system"`
|
||||
StDiff *Diff `json:"st_diff"`
|
||||
Description string `json:"description"`
|
||||
URL string `json:"url"`
|
||||
} `json:"object_attributes"`
|
||||
Snippet *Snippet `json:"snippet"`
|
||||
}
|
||||
|
||||
// TagEvent represents a tag event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#tag-events
|
||||
type TagEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
Before string `json:"before"`
|
||||
After string `json:"after"`
|
||||
Ref string `json:"ref"`
|
||||
CheckoutSHA string `json:"checkout_sha"`
|
||||
UserID int `json:"user_id"`
|
||||
UserName string `json:"user_name"`
|
||||
UserUsername string `json:"user_username"`
|
||||
UserAvatar string `json:"user_avatar"`
|
||||
UserEmail string `json:"user_email"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Message string `json:"message"`
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
Visibility VisibilityValue `json:"visibility"`
|
||||
} `json:"project"`
|
||||
Repository *Repository `json:"repository"`
|
||||
Commits []*struct {
|
||||
ID string `json:"id"`
|
||||
Message string `json:"message"`
|
||||
Timestamp *time.Time `json:"timestamp"`
|
||||
URL string `json:"url"`
|
||||
Author struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
} `json:"author"`
|
||||
Added []string `json:"added"`
|
||||
Modified []string `json:"modified"`
|
||||
Removed []string `json:"removed"`
|
||||
} `json:"commits"`
|
||||
TotalCommitsCount int `json:"total_commits_count"`
|
||||
}
|
||||
|
||||
// WikiPageEvent represents a wiki page event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/user/project/integrations/webhooks.html#wiki-page-events
|
||||
type WikiPageEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
User *EventUser `json:"user"`
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
Visibility VisibilityValue `json:"visibility"`
|
||||
} `json:"project"`
|
||||
Wiki struct {
|
||||
WebURL string `json:"web_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
} `json:"wiki"`
|
||||
ObjectAttributes struct {
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
Format string `json:"format"`
|
||||
Message string `json:"message"`
|
||||
Slug string `json:"slug"`
|
||||
URL string `json:"url"`
|
||||
Action string `json:"action"`
|
||||
} `json:"object_attributes"`
|
||||
}
|
148
vendor/github.com/xanzy/go-gitlab/events.go
generated
vendored
Normal file
148
vendor/github.com/xanzy/go-gitlab/events.go
generated
vendored
Normal file
|
@ -0,0 +1,148 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// EventsService handles communication with the event related methods of
|
||||
// the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/events.html
|
||||
type EventsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// ContributionEvent represents a user's contribution
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/events.html#get-user-contribution-events
|
||||
type ContributionEvent struct {
|
||||
ID int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
ProjectID int `json:"project_id"`
|
||||
ActionName string `json:"action_name"`
|
||||
TargetID int `json:"target_id"`
|
||||
TargetIID int `json:"target_iid"`
|
||||
TargetType string `json:"target_type"`
|
||||
AuthorID int `json:"author_id"`
|
||||
TargetTitle string `json:"target_title"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
PushData struct {
|
||||
CommitCount int `json:"commit_count"`
|
||||
Action string `json:"action"`
|
||||
RefType string `json:"ref_type"`
|
||||
CommitFrom string `json:"commit_from"`
|
||||
CommitTo string `json:"commit_to"`
|
||||
Ref string `json:"ref"`
|
||||
CommitTitle string `json:"commit_title"`
|
||||
} `json:"push_data"`
|
||||
Note *Note `json:"note"`
|
||||
Author struct {
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
ID int `json:"id"`
|
||||
State string `json:"state"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
} `json:"author"`
|
||||
AuthorUsername string `json:"author_username"`
|
||||
}
|
||||
|
||||
// ListContributionEventsOptions represents the options for GetUserContributionEvents
|
||||
//
|
||||
// GitLap API docs:
|
||||
// https://docs.gitlab.com/ce/api/events.html#get-user-contribution-events
|
||||
type ListContributionEventsOptions struct {
|
||||
ListOptions
|
||||
Action *EventTypeValue `url:"action,omitempty" json:"action,omitempty"`
|
||||
TargetType *EventTargetTypeValue `url:"target_type,omitempty" json:"target_type,omitempty"`
|
||||
Before *ISOTime `url:"before,omitempty" json:"before,omitempty"`
|
||||
After *ISOTime `url:"after,omitempty" json:"after,omitempty"`
|
||||
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
|
||||
}
|
||||
|
||||
// ListUserContributionEvents retrieves user contribution events
|
||||
// for the specified user, sorted from newest to oldest.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/events.html#get-user-contribution-events
|
||||
func (s *UsersService) ListUserContributionEvents(uid interface{}, opt *ListContributionEventsOptions, options ...RequestOptionFunc) ([]*ContributionEvent, *Response, error) {
|
||||
user, err := parseID(uid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("users/%s/events", user)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var cs []*ContributionEvent
|
||||
resp, err := s.client.Do(req, &cs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return cs, resp, err
|
||||
}
|
||||
|
||||
// ListCurrentUserContributionEvents gets a list currently authenticated user's events
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/events.html#list-currently-authenticated-user-39-s-events
|
||||
func (s *EventsService) ListCurrentUserContributionEvents(opt *ListContributionEventsOptions, options ...RequestOptionFunc) ([]*ContributionEvent, *Response, error) {
|
||||
req, err := s.client.NewRequest(http.MethodGet, "events", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var cs []*ContributionEvent
|
||||
resp, err := s.client.Do(req, &cs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return cs, resp, err
|
||||
}
|
||||
|
||||
// ListProjectVisibleEvents gets a list of visible events for a particular project
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/events.html#list-a-project-s-visible-events
|
||||
func (s *EventsService) ListProjectVisibleEvents(pid interface{}, opt *ListContributionEventsOptions, options ...RequestOptionFunc) ([]*ContributionEvent, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/events", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var cs []*ContributionEvent
|
||||
resp, err := s.client.Do(req, &cs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return cs, resp, err
|
||||
}
|
96
vendor/github.com/xanzy/go-gitlab/feature_flags.go
generated
vendored
Normal file
96
vendor/github.com/xanzy/go-gitlab/feature_flags.go
generated
vendored
Normal file
|
@ -0,0 +1,96 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// FeaturesService handles the communication with the application FeaturesService
|
||||
// related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/features.html
|
||||
type FeaturesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Feature represents a GitLab feature flag.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/features.html
|
||||
type Feature struct {
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
Gates []Gate
|
||||
}
|
||||
|
||||
// Gate represents a gate of a GitLab feature flag.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/features.html
|
||||
type Gate struct {
|
||||
Key string `json:"key"`
|
||||
Value interface{} `json:"value"`
|
||||
}
|
||||
|
||||
func (f Feature) String() string {
|
||||
return Stringify(f)
|
||||
}
|
||||
|
||||
// ListFeatures gets a list of feature flags
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/features.html#list-all-features
|
||||
func (s *FeaturesService) ListFeatures(options ...RequestOptionFunc) ([]*Feature, *Response, error) {
|
||||
req, err := s.client.NewRequest(http.MethodGet, "features", nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var f []*Feature
|
||||
resp, err := s.client.Do(req, &f)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
return f, resp, err
|
||||
}
|
||||
|
||||
// SetFeatureFlag sets or creates a feature flag gate
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/features.html#set-or-create-a-feature
|
||||
func (s *FeaturesService) SetFeatureFlag(name string, value interface{}, options ...RequestOptionFunc) (*Feature, *Response, error) {
|
||||
u := fmt.Sprintf("features/%s", url.PathEscape(name))
|
||||
|
||||
opt := struct {
|
||||
Value interface{} `url:"value" json:"value"`
|
||||
}{
|
||||
value,
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
f := &Feature{}
|
||||
resp, err := s.client.Do(req, f)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
return f, resp, err
|
||||
}
|
194
vendor/github.com/xanzy/go-gitlab/freeze_periods.go
generated
vendored
Normal file
194
vendor/github.com/xanzy/go-gitlab/freeze_periods.go
generated
vendored
Normal file
|
@ -0,0 +1,194 @@
|
|||
//
|
||||
// Copyright 2021 Paul Cioanca
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// FreezePeriodsService handles the communication with the freeze periods
|
||||
// related methods of the GitLab API.
|
||||
//
|
||||
// https://docs.gitlab.com/ce/api/freeze_periods.html
|
||||
type FreezePeriodsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// FreezePeriod represents a freeze period object.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/freeze_periods.html#list-freeze-periods
|
||||
type FreezePeriod struct {
|
||||
ID int `json:"id"`
|
||||
FreezeStart string `json:"freeze_start"`
|
||||
FreezeEnd string `json:"freeze_end"`
|
||||
CronTimezone string `json:"cron_timezone"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// ListFreezePeriodsOptions represents the available ListFreezePeriodsOptions()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/freeze_periods.html#list-freeze-periods
|
||||
type ListFreezePeriodsOptions ListOptions
|
||||
|
||||
// ListFreezePeriods gets a list of project project freeze periods.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/freeze_periods.html#list-freeze-periods
|
||||
func (s *FreezePeriodsService) ListFreezePeriods(pid interface{}, opt *ListFreezePeriodsOptions, options ...RequestOptionFunc) ([]*FreezePeriod, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/freeze_periods", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var fp []*FreezePeriod
|
||||
resp, err := s.client.Do(req, &fp)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return fp, resp, err
|
||||
}
|
||||
|
||||
// GetFreezePeriod gets a specific freeze period for a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/freeze_periods.html#get-a-freeze-period-by-a-freeze_period_id
|
||||
func (s *FreezePeriodsService) GetFreezePeriod(pid interface{}, freezePeriod int, options ...RequestOptionFunc) (*FreezePeriod, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/freeze_periods/%d", pathEscape(project), freezePeriod)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
fp := new(FreezePeriod)
|
||||
resp, err := s.client.Do(req, fp)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return fp, resp, err
|
||||
}
|
||||
|
||||
// CreateFreezePeriodOptions represents the available CreateFreezePeriodOptions()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/freeze_periods.html#create-a-freeze-period
|
||||
type CreateFreezePeriodOptions struct {
|
||||
FreezeStart *string `url:"freeze_start,omitempty" json:"freeze_start,omitempty"`
|
||||
FreezeEnd *string `url:"freeze_end,omitempty" json:"freeze_end,omitempty"`
|
||||
CronTimezone *string `url:"cron_timezone,omitempty" json:"cron_timezone,omitempty"`
|
||||
}
|
||||
|
||||
// CreateFreezePeriodOptions adds a freeze period to a specified project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/freeze_periods.html#create-a-freeze-period
|
||||
func (s *FreezePeriodsService) CreateFreezePeriodOptions(pid interface{}, opt *CreateFreezePeriodOptions, options ...RequestOptionFunc) (*FreezePeriod, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/freeze_periods", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
fp := new(FreezePeriod)
|
||||
resp, err := s.client.Do(req, fp)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return fp, resp, err
|
||||
}
|
||||
|
||||
// UpdateFreezePeriodOptions represents the available UpdateFreezePeriodOptions()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/freeze_periods.html#update-a-freeze-period
|
||||
type UpdateFreezePeriodOptions struct {
|
||||
FreezeStart *string `url:"freeze_start,omitempty" json:"freeze_start,omitempty"`
|
||||
FreezeEnd *string `url:"freeze_end,omitempty" json:"freeze_end,omitempty"`
|
||||
CronTimezone *string `url:"cron_timezone,omitempty" json:"cron_timezone,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateFreezePeriodOptions edits a freeze period for a specified project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/freeze_periods.html#update-a-freeze-period
|
||||
func (s *FreezePeriodsService) UpdateFreezePeriodOptions(pid interface{}, freezePeriod int, opt *UpdateFreezePeriodOptions, options ...RequestOptionFunc) (*FreezePeriod, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/freeze_periods/%d", pathEscape(project), freezePeriod)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
fp := new(FreezePeriod)
|
||||
resp, err := s.client.Do(req, fp)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return fp, resp, err
|
||||
}
|
||||
|
||||
// DeleteFreezePeriod removes a freeze period from a project. This is an
|
||||
// idempotent method and can be called multiple times. Either the hook is
|
||||
// available or not.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/freeze_periods.html#delete-a-freeze-period
|
||||
func (s *FreezePeriodsService) DeleteFreezePeriod(pid interface{}, freezePeriod int, options ...RequestOptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/freeze_periods/%d", pathEscape(project), freezePeriod)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
85
vendor/github.com/xanzy/go-gitlab/gitignore_templates.go
generated
vendored
Normal file
85
vendor/github.com/xanzy/go-gitlab/gitignore_templates.go
generated
vendored
Normal file
|
@ -0,0 +1,85 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// GitIgnoreTemplatesService handles communication with the gitignore
|
||||
// templates related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/templates/gitignores.html
|
||||
type GitIgnoreTemplatesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// GitIgnoreTemplate represents a GitLab gitignore template.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/templates/gitignores.html
|
||||
type GitIgnoreTemplate struct {
|
||||
Name string `json:"name"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
// ListTemplatesOptions represents the available ListAllTemplates() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/templates/gitignores.html#list-gitignore-templates
|
||||
type ListTemplatesOptions ListOptions
|
||||
|
||||
// ListTemplates get a list of available git ignore templates
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/templates/gitignores.html#list-gitignore-templates
|
||||
func (s *GitIgnoreTemplatesService) ListTemplates(opt *ListTemplatesOptions, options ...RequestOptionFunc) ([]*GitIgnoreTemplate, *Response, error) {
|
||||
req, err := s.client.NewRequest(http.MethodGet, "templates/gitignores", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var gs []*GitIgnoreTemplate
|
||||
resp, err := s.client.Do(req, &gs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gs, resp, err
|
||||
}
|
||||
|
||||
// GetTemplate get a git ignore template
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/templates/gitignores.html#get-a-single-gitignore-template
|
||||
func (s *GitIgnoreTemplatesService) GetTemplate(key string, options ...RequestOptionFunc) (*GitIgnoreTemplate, *Response, error) {
|
||||
u := fmt.Sprintf("templates/gitignores/%s", url.PathEscape(key))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(GitIgnoreTemplate)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
830
vendor/github.com/xanzy/go-gitlab/gitlab.go
generated
vendored
Normal file
830
vendor/github.com/xanzy/go-gitlab/gitlab.go
generated
vendored
Normal file
|
@ -0,0 +1,830 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
// Package gitlab implements a GitLab API client.
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
"github.com/hashicorp/go-cleanhttp"
|
||||
retryablehttp "github.com/hashicorp/go-retryablehttp"
|
||||
"golang.org/x/oauth2"
|
||||
"golang.org/x/time/rate"
|
||||
)
|
||||
|
||||
const (
|
||||
defaultBaseURL = "https://gitlab.com/"
|
||||
apiVersionPath = "api/v4/"
|
||||
userAgent = "go-gitlab"
|
||||
|
||||
headerRateLimit = "RateLimit-Limit"
|
||||
headerRateReset = "RateLimit-Reset"
|
||||
)
|
||||
|
||||
// authType represents an authentication type within GitLab.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/
|
||||
type authType int
|
||||
|
||||
// List of available authentication types.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/
|
||||
const (
|
||||
basicAuth authType = iota
|
||||
jobToken
|
||||
oAuthToken
|
||||
privateToken
|
||||
)
|
||||
|
||||
// A Client manages communication with the GitLab API.
|
||||
type Client struct {
|
||||
// HTTP client used to communicate with the API.
|
||||
client *retryablehttp.Client
|
||||
|
||||
// Base URL for API requests. Defaults to the public GitLab API, but can be
|
||||
// set to a domain endpoint to use with a self hosted GitLab server. baseURL
|
||||
// should always be specified with a trailing slash.
|
||||
baseURL *url.URL
|
||||
|
||||
// disableRetries is used to disable the default retry logic.
|
||||
disableRetries bool
|
||||
|
||||
// configureLimiterOnce is used to make sure the limiter is configured exactly
|
||||
// once and block all other calls until the initial (one) call is done.
|
||||
configureLimiterOnce sync.Once
|
||||
|
||||
// Limiter is used to limit API calls and prevent 429 responses.
|
||||
limiter RateLimiter
|
||||
|
||||
// Token type used to make authenticated API calls.
|
||||
authType authType
|
||||
|
||||
// Username and password used for basix authentication.
|
||||
username, password string
|
||||
|
||||
// Token used to make authenticated API calls.
|
||||
token string
|
||||
|
||||
// Protects the token field from concurrent read/write accesses.
|
||||
tokenLock sync.RWMutex
|
||||
|
||||
// User agent used when communicating with the GitLab API.
|
||||
UserAgent string
|
||||
|
||||
// Services used for talking to different parts of the GitLab API.
|
||||
AccessRequests *AccessRequestsService
|
||||
Applications *ApplicationsService
|
||||
AuditEvents *AuditEventsService
|
||||
Avatar *AvatarRequestsService
|
||||
AwardEmoji *AwardEmojiService
|
||||
Boards *IssueBoardsService
|
||||
Branches *BranchesService
|
||||
BroadcastMessage *BroadcastMessagesService
|
||||
CIYMLTemplate *CIYMLTemplatesService
|
||||
Commits *CommitsService
|
||||
ContainerRegistry *ContainerRegistryService
|
||||
CustomAttribute *CustomAttributesService
|
||||
DeployKeys *DeployKeysService
|
||||
DeployTokens *DeployTokensService
|
||||
Deployments *DeploymentsService
|
||||
Discussions *DiscussionsService
|
||||
Environments *EnvironmentsService
|
||||
EpicIssues *EpicIssuesService
|
||||
Epics *EpicsService
|
||||
Events *EventsService
|
||||
Features *FeaturesService
|
||||
FreezePeriods *FreezePeriodsService
|
||||
GitIgnoreTemplates *GitIgnoreTemplatesService
|
||||
GroupBadges *GroupBadgesService
|
||||
GroupCluster *GroupClustersService
|
||||
GroupImportExport *GroupImportExportService
|
||||
GroupIssueBoards *GroupIssueBoardsService
|
||||
GroupLabels *GroupLabelsService
|
||||
GroupMembers *GroupMembersService
|
||||
GroupMilestones *GroupMilestonesService
|
||||
GroupVariables *GroupVariablesService
|
||||
GroupWikis *GroupWikisService
|
||||
Groups *GroupsService
|
||||
InstanceCluster *InstanceClustersService
|
||||
InstanceVariables *InstanceVariablesService
|
||||
Invites *InvitesService
|
||||
IssueLinks *IssueLinksService
|
||||
Issues *IssuesService
|
||||
IssuesStatistics *IssuesStatisticsService
|
||||
Jobs *JobsService
|
||||
Keys *KeysService
|
||||
Labels *LabelsService
|
||||
License *LicenseService
|
||||
LicenseTemplates *LicenseTemplatesService
|
||||
ManagedLicenses *ManagedLicensesService
|
||||
MergeRequestApprovals *MergeRequestApprovalsService
|
||||
MergeRequests *MergeRequestsService
|
||||
Milestones *MilestonesService
|
||||
Namespaces *NamespacesService
|
||||
Notes *NotesService
|
||||
NotificationSettings *NotificationSettingsService
|
||||
Packages *PackagesService
|
||||
Pages *PagesService
|
||||
PagesDomains *PagesDomainsService
|
||||
PipelineSchedules *PipelineSchedulesService
|
||||
PipelineTriggers *PipelineTriggersService
|
||||
Pipelines *PipelinesService
|
||||
ProjectBadges *ProjectBadgesService
|
||||
ProjectAccessTokens *ProjectAccessTokensService
|
||||
ProjectCluster *ProjectClustersService
|
||||
ProjectImportExport *ProjectImportExportService
|
||||
ProjectMembers *ProjectMembersService
|
||||
ProjectMirrors *ProjectMirrorService
|
||||
ProjectSnippets *ProjectSnippetsService
|
||||
ProjectVariables *ProjectVariablesService
|
||||
Projects *ProjectsService
|
||||
ProtectedBranches *ProtectedBranchesService
|
||||
ProtectedEnvironments *ProtectedEnvironmentsService
|
||||
ProtectedTags *ProtectedTagsService
|
||||
ReleaseLinks *ReleaseLinksService
|
||||
Releases *ReleasesService
|
||||
Repositories *RepositoriesService
|
||||
RepositoryFiles *RepositoryFilesService
|
||||
ResourceLabelEvents *ResourceLabelEventsService
|
||||
ResourceStateEvents *ResourceStateEventsService
|
||||
Runners *RunnersService
|
||||
Search *SearchService
|
||||
Services *ServicesService
|
||||
Settings *SettingsService
|
||||
Sidekiq *SidekiqService
|
||||
Snippets *SnippetsService
|
||||
SystemHooks *SystemHooksService
|
||||
Tags *TagsService
|
||||
Todos *TodosService
|
||||
Users *UsersService
|
||||
Validate *ValidateService
|
||||
Version *VersionService
|
||||
Wikis *WikisService
|
||||
}
|
||||
|
||||
// ListOptions specifies the optional parameters to various List methods that
|
||||
// support pagination.
|
||||
type ListOptions struct {
|
||||
// For paginated result sets, page of results to retrieve.
|
||||
Page int `url:"page,omitempty" json:"page,omitempty"`
|
||||
|
||||
// For paginated result sets, the number of results to include per page.
|
||||
PerPage int `url:"per_page,omitempty" json:"per_page,omitempty"`
|
||||
}
|
||||
|
||||
// RateLimiter describes the interface that all (custom) rate limiters must implement.
|
||||
type RateLimiter interface {
|
||||
Wait(context.Context) error
|
||||
}
|
||||
|
||||
// NewClient returns a new GitLab API client. To use API methods which require
|
||||
// authentication, provide a valid private or personal token.
|
||||
func NewClient(token string, options ...ClientOptionFunc) (*Client, error) {
|
||||
client, err := newClient(options...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client.authType = privateToken
|
||||
client.token = token
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// NewBasicAuthClient returns a new GitLab API client. To use API methods which
|
||||
// require authentication, provide a valid username and password.
|
||||
func NewBasicAuthClient(username, password string, options ...ClientOptionFunc) (*Client, error) {
|
||||
client, err := newClient(options...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client.authType = basicAuth
|
||||
client.username = username
|
||||
client.password = password
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// NewJobClient returns a new GitLab API client. To use API methods which require
|
||||
// authentication, provide a valid job token.
|
||||
func NewJobClient(token string, options ...ClientOptionFunc) (*Client, error) {
|
||||
client, err := newClient(options...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client.authType = jobToken
|
||||
client.token = token
|
||||
return client, nil
|
||||
}
|
||||
|
||||
// NewOAuthClient returns a new GitLab API client. To use API methods which
|
||||
// require authentication, provide a valid oauth token.
|
||||
func NewOAuthClient(token string, options ...ClientOptionFunc) (*Client, error) {
|
||||
client, err := newClient(options...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
client.authType = oAuthToken
|
||||
client.token = token
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func newClient(options ...ClientOptionFunc) (*Client, error) {
|
||||
c := &Client{UserAgent: userAgent}
|
||||
|
||||
// Configure the HTTP client.
|
||||
c.client = &retryablehttp.Client{
|
||||
Backoff: c.retryHTTPBackoff,
|
||||
CheckRetry: c.retryHTTPCheck,
|
||||
ErrorHandler: retryablehttp.PassthroughErrorHandler,
|
||||
HTTPClient: cleanhttp.DefaultPooledClient(),
|
||||
RetryWaitMin: 100 * time.Millisecond,
|
||||
RetryWaitMax: 400 * time.Millisecond,
|
||||
RetryMax: 5,
|
||||
}
|
||||
|
||||
// Set the default base URL.
|
||||
c.setBaseURL(defaultBaseURL)
|
||||
|
||||
// Apply any given client options.
|
||||
for _, fn := range options {
|
||||
if fn == nil {
|
||||
continue
|
||||
}
|
||||
if err := fn(c); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Create the internal timeStats service.
|
||||
timeStats := &timeStatsService{client: c}
|
||||
|
||||
// Create all the public services.
|
||||
c.AccessRequests = &AccessRequestsService{client: c}
|
||||
c.Applications = &ApplicationsService{client: c}
|
||||
c.AuditEvents = &AuditEventsService{client: c}
|
||||
c.Avatar = &AvatarRequestsService{client: c}
|
||||
c.AwardEmoji = &AwardEmojiService{client: c}
|
||||
c.Boards = &IssueBoardsService{client: c}
|
||||
c.Branches = &BranchesService{client: c}
|
||||
c.BroadcastMessage = &BroadcastMessagesService{client: c}
|
||||
c.CIYMLTemplate = &CIYMLTemplatesService{client: c}
|
||||
c.Commits = &CommitsService{client: c}
|
||||
c.ContainerRegistry = &ContainerRegistryService{client: c}
|
||||
c.CustomAttribute = &CustomAttributesService{client: c}
|
||||
c.DeployKeys = &DeployKeysService{client: c}
|
||||
c.DeployTokens = &DeployTokensService{client: c}
|
||||
c.Deployments = &DeploymentsService{client: c}
|
||||
c.Discussions = &DiscussionsService{client: c}
|
||||
c.Environments = &EnvironmentsService{client: c}
|
||||
c.EpicIssues = &EpicIssuesService{client: c}
|
||||
c.Epics = &EpicsService{client: c}
|
||||
c.Events = &EventsService{client: c}
|
||||
c.Features = &FeaturesService{client: c}
|
||||
c.FreezePeriods = &FreezePeriodsService{client: c}
|
||||
c.GitIgnoreTemplates = &GitIgnoreTemplatesService{client: c}
|
||||
c.GroupBadges = &GroupBadgesService{client: c}
|
||||
c.GroupCluster = &GroupClustersService{client: c}
|
||||
c.GroupImportExport = &GroupImportExportService{client: c}
|
||||
c.GroupIssueBoards = &GroupIssueBoardsService{client: c}
|
||||
c.GroupLabels = &GroupLabelsService{client: c}
|
||||
c.GroupMembers = &GroupMembersService{client: c}
|
||||
c.GroupMilestones = &GroupMilestonesService{client: c}
|
||||
c.GroupVariables = &GroupVariablesService{client: c}
|
||||
c.GroupWikis = &GroupWikisService{client: c}
|
||||
c.Groups = &GroupsService{client: c}
|
||||
c.InstanceCluster = &InstanceClustersService{client: c}
|
||||
c.InstanceVariables = &InstanceVariablesService{client: c}
|
||||
c.Invites = &InvitesService{client: c}
|
||||
c.IssueLinks = &IssueLinksService{client: c}
|
||||
c.Issues = &IssuesService{client: c, timeStats: timeStats}
|
||||
c.IssuesStatistics = &IssuesStatisticsService{client: c}
|
||||
c.Jobs = &JobsService{client: c}
|
||||
c.Keys = &KeysService{client: c}
|
||||
c.Labels = &LabelsService{client: c}
|
||||
c.License = &LicenseService{client: c}
|
||||
c.LicenseTemplates = &LicenseTemplatesService{client: c}
|
||||
c.ManagedLicenses = &ManagedLicensesService{client: c}
|
||||
c.MergeRequestApprovals = &MergeRequestApprovalsService{client: c}
|
||||
c.MergeRequests = &MergeRequestsService{client: c, timeStats: timeStats}
|
||||
c.Milestones = &MilestonesService{client: c}
|
||||
c.Namespaces = &NamespacesService{client: c}
|
||||
c.Notes = &NotesService{client: c}
|
||||
c.NotificationSettings = &NotificationSettingsService{client: c}
|
||||
c.Packages = &PackagesService{client: c}
|
||||
c.Pages = &PagesService{client: c}
|
||||
c.PagesDomains = &PagesDomainsService{client: c}
|
||||
c.PipelineSchedules = &PipelineSchedulesService{client: c}
|
||||
c.PipelineTriggers = &PipelineTriggersService{client: c}
|
||||
c.Pipelines = &PipelinesService{client: c}
|
||||
c.ProjectBadges = &ProjectBadgesService{client: c}
|
||||
c.ProjectAccessTokens = &ProjectAccessTokensService{client: c}
|
||||
c.ProjectCluster = &ProjectClustersService{client: c}
|
||||
c.ProjectImportExport = &ProjectImportExportService{client: c}
|
||||
c.ProjectMembers = &ProjectMembersService{client: c}
|
||||
c.ProjectMirrors = &ProjectMirrorService{client: c}
|
||||
c.ProjectSnippets = &ProjectSnippetsService{client: c}
|
||||
c.ProjectVariables = &ProjectVariablesService{client: c}
|
||||
c.Projects = &ProjectsService{client: c}
|
||||
c.ProtectedBranches = &ProtectedBranchesService{client: c}
|
||||
c.ProtectedEnvironments = &ProtectedEnvironmentsService{client: c}
|
||||
c.ProtectedTags = &ProtectedTagsService{client: c}
|
||||
c.ReleaseLinks = &ReleaseLinksService{client: c}
|
||||
c.Releases = &ReleasesService{client: c}
|
||||
c.Repositories = &RepositoriesService{client: c}
|
||||
c.RepositoryFiles = &RepositoryFilesService{client: c}
|
||||
c.ResourceLabelEvents = &ResourceLabelEventsService{client: c}
|
||||
c.ResourceStateEvents = &ResourceStateEventsService{client: c}
|
||||
c.Runners = &RunnersService{client: c}
|
||||
c.Search = &SearchService{client: c}
|
||||
c.Services = &ServicesService{client: c}
|
||||
c.Settings = &SettingsService{client: c}
|
||||
c.Sidekiq = &SidekiqService{client: c}
|
||||
c.Snippets = &SnippetsService{client: c}
|
||||
c.SystemHooks = &SystemHooksService{client: c}
|
||||
c.Tags = &TagsService{client: c}
|
||||
c.Todos = &TodosService{client: c}
|
||||
c.Users = &UsersService{client: c}
|
||||
c.Validate = &ValidateService{client: c}
|
||||
c.Version = &VersionService{client: c}
|
||||
c.Wikis = &WikisService{client: c}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
// retryHTTPCheck provides a callback for Client.CheckRetry which
|
||||
// will retry both rate limit (429) and server (>= 500) errors.
|
||||
func (c *Client) retryHTTPCheck(ctx context.Context, resp *http.Response, err error) (bool, error) {
|
||||
if ctx.Err() != nil {
|
||||
return false, ctx.Err()
|
||||
}
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if !c.disableRetries && (resp.StatusCode == 429 || resp.StatusCode >= 500) {
|
||||
return true, nil
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// retryHTTPBackoff provides a generic callback for Client.Backoff which
|
||||
// will pass through all calls based on the status code of the response.
|
||||
func (c *Client) retryHTTPBackoff(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration {
|
||||
// Use the rate limit backoff function when we are rate limited.
|
||||
if resp != nil && resp.StatusCode == 429 {
|
||||
return rateLimitBackoff(min, max, attemptNum, resp)
|
||||
}
|
||||
|
||||
// Set custom duration's when we experience a service interruption.
|
||||
min = 700 * time.Millisecond
|
||||
max = 900 * time.Millisecond
|
||||
|
||||
return retryablehttp.LinearJitterBackoff(min, max, attemptNum, resp)
|
||||
}
|
||||
|
||||
// rateLimitBackoff provides a callback for Client.Backoff which will use the
|
||||
// RateLimit-Reset header to determine the time to wait. We add some jitter
|
||||
// to prevent a thundering herd.
|
||||
//
|
||||
// min and max are mainly used for bounding the jitter that will be added to
|
||||
// the reset time retrieved from the headers. But if the final wait time is
|
||||
// less then min, min will be used instead.
|
||||
func rateLimitBackoff(min, max time.Duration, attemptNum int, resp *http.Response) time.Duration {
|
||||
// rnd is used to generate pseudo-random numbers.
|
||||
rnd := rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
|
||||
// First create some jitter bounded by the min and max durations.
|
||||
jitter := time.Duration(rnd.Float64() * float64(max-min))
|
||||
|
||||
if resp != nil {
|
||||
if v := resp.Header.Get(headerRateReset); v != "" {
|
||||
if reset, _ := strconv.ParseInt(v, 10, 64); reset > 0 {
|
||||
// Only update min if the given time to wait is longer.
|
||||
if wait := time.Until(time.Unix(reset, 0)); wait > min {
|
||||
min = wait
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return min + jitter
|
||||
}
|
||||
|
||||
// configureLimiter configures the rate limiter.
|
||||
func (c *Client) configureLimiter(ctx context.Context) error {
|
||||
// Set default values for when rate limiting is disabled.
|
||||
limit := rate.Inf
|
||||
burst := 0
|
||||
|
||||
defer func() {
|
||||
// Create a new limiter using the calculated values.
|
||||
c.limiter = rate.NewLimiter(limit, burst)
|
||||
}()
|
||||
|
||||
// Create a new request.
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, c.baseURL.String(), nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Make a single request to retrieve the rate limit headers.
|
||||
resp, err := c.client.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
if v := resp.Header.Get(headerRateLimit); v != "" {
|
||||
if rateLimit, _ := strconv.ParseFloat(v, 64); rateLimit > 0 {
|
||||
// The rate limit is based on requests per minute, so for our limiter to
|
||||
// work correctly we divide the limit by 60 to get the limit per second.
|
||||
rateLimit /= 60
|
||||
// Configure the limit and burst using a split of 2/3 for the limit and
|
||||
// 1/3 for the burst. This enables clients to burst 1/3 of the allowed
|
||||
// calls before the limiter kicks in. The remaining calls will then be
|
||||
// spread out evenly using intervals of time.Second / limit which should
|
||||
// prevent hitting the rate limit.
|
||||
limit = rate.Limit(rateLimit * 0.66)
|
||||
burst = int(rateLimit * 0.33)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// BaseURL return a copy of the baseURL.
|
||||
func (c *Client) BaseURL() *url.URL {
|
||||
u := *c.baseURL
|
||||
return &u
|
||||
}
|
||||
|
||||
// setBaseURL sets the base URL for API requests to a custom endpoint.
|
||||
func (c *Client) setBaseURL(urlStr string) error {
|
||||
// Make sure the given URL end with a slash
|
||||
if !strings.HasSuffix(urlStr, "/") {
|
||||
urlStr += "/"
|
||||
}
|
||||
|
||||
baseURL, err := url.Parse(urlStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !strings.HasSuffix(baseURL.Path, apiVersionPath) {
|
||||
baseURL.Path += apiVersionPath
|
||||
}
|
||||
|
||||
// Update the base URL of the client.
|
||||
c.baseURL = baseURL
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// NewRequest creates an API request. A relative URL path can be provided in
|
||||
// path, in which case it is resolved relative to the base URL of the Client.
|
||||
// Relative URL paths should always be specified without a preceding slash. If
|
||||
// specified, the value pointed to by body is JSON encoded and included as the
|
||||
// request body.
|
||||
func (c *Client) NewRequest(method, path string, opt interface{}, options []RequestOptionFunc) (*retryablehttp.Request, error) {
|
||||
u := *c.baseURL
|
||||
unescaped, err := url.PathUnescape(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set the encoded path data
|
||||
u.RawPath = c.baseURL.Path + path
|
||||
u.Path = c.baseURL.Path + unescaped
|
||||
|
||||
// Create a request specific headers map.
|
||||
reqHeaders := make(http.Header)
|
||||
reqHeaders.Set("Accept", "application/json")
|
||||
|
||||
if c.UserAgent != "" {
|
||||
reqHeaders.Set("User-Agent", c.UserAgent)
|
||||
}
|
||||
|
||||
var body interface{}
|
||||
switch {
|
||||
case method == http.MethodPost || method == http.MethodPut:
|
||||
reqHeaders.Set("Content-Type", "application/json")
|
||||
|
||||
if opt != nil {
|
||||
body, err = json.Marshal(opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
case opt != nil:
|
||||
q, err := query.Values(opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
req, err := retryablehttp.NewRequest(method, u.String(), body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, fn := range options {
|
||||
if fn == nil {
|
||||
continue
|
||||
}
|
||||
if err := fn(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Set the request specific headers.
|
||||
for k, v := range reqHeaders {
|
||||
req.Header[k] = v
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// Response is a GitLab API response. This wraps the standard http.Response
|
||||
// returned from GitLab and provides convenient access to things like
|
||||
// pagination links.
|
||||
type Response struct {
|
||||
*http.Response
|
||||
|
||||
// These fields provide the page values for paginating through a set of
|
||||
// results. Any or all of these may be set to the zero value for
|
||||
// responses that are not part of a paginated set, or for which there
|
||||
// are no additional pages.
|
||||
TotalItems int
|
||||
TotalPages int
|
||||
ItemsPerPage int
|
||||
CurrentPage int
|
||||
NextPage int
|
||||
PreviousPage int
|
||||
}
|
||||
|
||||
// newResponse creates a new Response for the provided http.Response.
|
||||
func newResponse(r *http.Response) *Response {
|
||||
response := &Response{Response: r}
|
||||
response.populatePageValues()
|
||||
return response
|
||||
}
|
||||
|
||||
const (
|
||||
xTotal = "X-Total"
|
||||
xTotalPages = "X-Total-Pages"
|
||||
xPerPage = "X-Per-Page"
|
||||
xPage = "X-Page"
|
||||
xNextPage = "X-Next-Page"
|
||||
xPrevPage = "X-Prev-Page"
|
||||
)
|
||||
|
||||
// populatePageValues parses the HTTP Link response headers and populates the
|
||||
// various pagination link values in the Response.
|
||||
func (r *Response) populatePageValues() {
|
||||
if totalItems := r.Response.Header.Get(xTotal); totalItems != "" {
|
||||
r.TotalItems, _ = strconv.Atoi(totalItems)
|
||||
}
|
||||
if totalPages := r.Response.Header.Get(xTotalPages); totalPages != "" {
|
||||
r.TotalPages, _ = strconv.Atoi(totalPages)
|
||||
}
|
||||
if itemsPerPage := r.Response.Header.Get(xPerPage); itemsPerPage != "" {
|
||||
r.ItemsPerPage, _ = strconv.Atoi(itemsPerPage)
|
||||
}
|
||||
if currentPage := r.Response.Header.Get(xPage); currentPage != "" {
|
||||
r.CurrentPage, _ = strconv.Atoi(currentPage)
|
||||
}
|
||||
if nextPage := r.Response.Header.Get(xNextPage); nextPage != "" {
|
||||
r.NextPage, _ = strconv.Atoi(nextPage)
|
||||
}
|
||||
if previousPage := r.Response.Header.Get(xPrevPage); previousPage != "" {
|
||||
r.PreviousPage, _ = strconv.Atoi(previousPage)
|
||||
}
|
||||
}
|
||||
|
||||
// Do sends an API request and returns the API response. The API response is
|
||||
// JSON decoded and stored in the value pointed to by v, or returned as an
|
||||
// error if an API error has occurred. If v implements the io.Writer
|
||||
// interface, the raw response body will be written to v, without attempting to
|
||||
// first decode it.
|
||||
func (c *Client) Do(req *retryablehttp.Request, v interface{}) (*Response, error) {
|
||||
// If not yet configured, try to configure the rate limiter. Fail
|
||||
// silently as the limiter will be disabled in case of an error.
|
||||
c.configureLimiterOnce.Do(func() { c.configureLimiter(req.Context()) })
|
||||
|
||||
// Wait will block until the limiter can obtain a new token.
|
||||
err := c.limiter.Wait(req.Context())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set the correct authentication header. If using basic auth, then check
|
||||
// if we already have a token and if not first authenticate and get one.
|
||||
var basicAuthToken string
|
||||
switch c.authType {
|
||||
case basicAuth:
|
||||
c.tokenLock.RLock()
|
||||
basicAuthToken = c.token
|
||||
c.tokenLock.RUnlock()
|
||||
if basicAuthToken == "" {
|
||||
// If we don't have a token yet, we first need to request one.
|
||||
basicAuthToken, err = c.requestOAuthToken(req.Context(), basicAuthToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
req.Header.Set("Authorization", "Bearer "+basicAuthToken)
|
||||
case jobToken:
|
||||
req.Header.Set("JOB-TOKEN", c.token)
|
||||
case oAuthToken:
|
||||
req.Header.Set("Authorization", "Bearer "+c.token)
|
||||
case privateToken:
|
||||
req.Header.Set("PRIVATE-TOKEN", c.token)
|
||||
}
|
||||
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp.StatusCode == http.StatusUnauthorized && c.authType == basicAuth {
|
||||
resp.Body.Close()
|
||||
// The token most likely expired, so we need to request a new one and try again.
|
||||
if _, err := c.requestOAuthToken(req.Context(), basicAuthToken); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return c.Do(req, v)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
response := newResponse(resp)
|
||||
|
||||
err = CheckResponse(resp)
|
||||
if err != nil {
|
||||
// Even though there was an error, we still return the response
|
||||
// in case the caller wants to inspect it further.
|
||||
return response, err
|
||||
}
|
||||
|
||||
if v != nil {
|
||||
if w, ok := v.(io.Writer); ok {
|
||||
_, err = io.Copy(w, resp.Body)
|
||||
} else {
|
||||
err = json.NewDecoder(resp.Body).Decode(v)
|
||||
}
|
||||
}
|
||||
|
||||
return response, err
|
||||
}
|
||||
|
||||
func (c *Client) requestOAuthToken(ctx context.Context, token string) (string, error) {
|
||||
c.tokenLock.Lock()
|
||||
defer c.tokenLock.Unlock()
|
||||
|
||||
// Return early if the token was updated while waiting for the lock.
|
||||
if c.token != token {
|
||||
return c.token, nil
|
||||
}
|
||||
|
||||
config := &oauth2.Config{
|
||||
Endpoint: oauth2.Endpoint{
|
||||
AuthURL: strings.TrimSuffix(c.baseURL.String(), apiVersionPath) + "oauth/authorize",
|
||||
TokenURL: strings.TrimSuffix(c.baseURL.String(), apiVersionPath) + "oauth/token",
|
||||
},
|
||||
}
|
||||
|
||||
ctx = context.WithValue(ctx, oauth2.HTTPClient, c.client.HTTPClient)
|
||||
t, err := config.PasswordCredentialsToken(ctx, c.username, c.password)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
c.token = t.AccessToken
|
||||
|
||||
return c.token, nil
|
||||
}
|
||||
|
||||
// Helper function to accept and format both the project ID or name as project
|
||||
// identifier for all API calls.
|
||||
func parseID(id interface{}) (string, error) {
|
||||
switch v := id.(type) {
|
||||
case int:
|
||||
return strconv.Itoa(v), nil
|
||||
case string:
|
||||
return v, nil
|
||||
default:
|
||||
return "", fmt.Errorf("invalid ID type %#v, the ID must be an int or a string", id)
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to escape a project identifier.
|
||||
func pathEscape(s string) string {
|
||||
return strings.Replace(url.PathEscape(s), ".", "%2E", -1)
|
||||
}
|
||||
|
||||
// An ErrorResponse reports one or more errors caused by an API request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/README.html#data-validation-and-error-reporting
|
||||
type ErrorResponse struct {
|
||||
Body []byte
|
||||
Response *http.Response
|
||||
Message string
|
||||
}
|
||||
|
||||
func (e *ErrorResponse) Error() string {
|
||||
path, _ := url.QueryUnescape(e.Response.Request.URL.Path)
|
||||
u := fmt.Sprintf("%s://%s%s", e.Response.Request.URL.Scheme, e.Response.Request.URL.Host, path)
|
||||
return fmt.Sprintf("%s %s: %d %s", e.Response.Request.Method, u, e.Response.StatusCode, e.Message)
|
||||
}
|
||||
|
||||
// CheckResponse checks the API response for errors, and returns them if present.
|
||||
func CheckResponse(r *http.Response) error {
|
||||
switch r.StatusCode {
|
||||
case 200, 201, 202, 204, 304:
|
||||
return nil
|
||||
}
|
||||
|
||||
errorResponse := &ErrorResponse{Response: r}
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
if err == nil && data != nil {
|
||||
errorResponse.Body = data
|
||||
|
||||
var raw interface{}
|
||||
if err := json.Unmarshal(data, &raw); err != nil {
|
||||
errorResponse.Message = "failed to parse unknown error format"
|
||||
} else {
|
||||
errorResponse.Message = parseError(raw)
|
||||
}
|
||||
}
|
||||
|
||||
return errorResponse
|
||||
}
|
||||
|
||||
// Format:
|
||||
// {
|
||||
// "message": {
|
||||
// "<property-name>": [
|
||||
// "<error-message>",
|
||||
// "<error-message>",
|
||||
// ...
|
||||
// ],
|
||||
// "<embed-entity>": {
|
||||
// "<property-name>": [
|
||||
// "<error-message>",
|
||||
// "<error-message>",
|
||||
// ...
|
||||
// ],
|
||||
// }
|
||||
// },
|
||||
// "error": "<error-message>"
|
||||
// }
|
||||
func parseError(raw interface{}) string {
|
||||
switch raw := raw.(type) {
|
||||
case string:
|
||||
return raw
|
||||
|
||||
case []interface{}:
|
||||
var errs []string
|
||||
for _, v := range raw {
|
||||
errs = append(errs, parseError(v))
|
||||
}
|
||||
return fmt.Sprintf("[%s]", strings.Join(errs, ", "))
|
||||
|
||||
case map[string]interface{}:
|
||||
var errs []string
|
||||
for k, v := range raw {
|
||||
errs = append(errs, fmt.Sprintf("{%s: %s}", k, parseError(v)))
|
||||
}
|
||||
sort.Strings(errs)
|
||||
return strings.Join(errs, ", ")
|
||||
|
||||
default:
|
||||
return fmt.Sprintf("failed to parse unexpected error type: %T", raw)
|
||||
}
|
||||
}
|
15
vendor/github.com/xanzy/go-gitlab/go.mod
generated
vendored
Normal file
15
vendor/github.com/xanzy/go-gitlab/go.mod
generated
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
module github.com/xanzy/go-gitlab
|
||||
|
||||
require (
|
||||
github.com/google/go-querystring v1.0.0
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1
|
||||
github.com/hashicorp/go-retryablehttp v0.6.8
|
||||
github.com/stretchr/testify v1.4.0
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 // indirect
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0
|
||||
google.golang.org/appengine v1.3.0 // indirect
|
||||
)
|
||||
|
||||
go 1.13
|
48
vendor/github.com/xanzy/go-gitlab/go.sum
generated
vendored
Normal file
48
vendor/github.com/xanzy/go-gitlab/go.sum
generated
vendored
Normal file
|
@ -0,0 +1,48 @@
|
|||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
|
||||
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.8 h1:92lWxgpa+fF3FozM4B3UZtHZMJX8T5XT+TFdCxsPyWs=
|
||||
github.com/hashicorp/go-retryablehttp v0.6.8/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288 h1:JIqe8uIcRBHXDQVvZtHwp80ai3Lw3IJAeJEs55Dc1W0=
|
||||
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0 h1:/5xXl8Y5W96D+TtHSlonuFqGHIWVuyCkGJLwGh9JJFs=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e h1:FDhOuMEY4JVRztM/gsbk+IKUQ8kj74bxZrgw87eMMVc=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
|
||||
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
230
vendor/github.com/xanzy/go-gitlab/group_badges.go
generated
vendored
Normal file
230
vendor/github.com/xanzy/go-gitlab/group_badges.go
generated
vendored
Normal file
|
@ -0,0 +1,230 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// GroupBadgesService handles communication with the group badges
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_badges.html
|
||||
type GroupBadgesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// BadgeKind represents a GitLab Badge Kind
|
||||
type BadgeKind string
|
||||
|
||||
// all possible values Badge Kind
|
||||
const (
|
||||
ProjectBadgeKind BadgeKind = "project"
|
||||
GroupBadgeKind BadgeKind = "group"
|
||||
)
|
||||
|
||||
// GroupBadge represents a group badge.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_badges.html
|
||||
type GroupBadge struct {
|
||||
ID int `json:"id"`
|
||||
LinkURL string `json:"link_url"`
|
||||
ImageURL string `json:"image_url"`
|
||||
RenderedLinkURL string `json:"rendered_link_url"`
|
||||
RenderedImageURL string `json:"rendered_image_url"`
|
||||
Kind BadgeKind `json:"kind"`
|
||||
}
|
||||
|
||||
// ListGroupBadgesOptions represents the available ListGroupBadges() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_badges.html#list-all-badges-of-a-group
|
||||
type ListGroupBadgesOptions ListOptions
|
||||
|
||||
// ListGroupBadges gets a list of a group badges.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_badges.html#list-all-badges-of-a-group
|
||||
func (s *GroupBadgesService) ListGroupBadges(gid interface{}, opt *ListGroupBadgesOptions, options ...RequestOptionFunc) ([]*GroupBadge, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/badges", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var gb []*GroupBadge
|
||||
resp, err := s.client.Do(req, &gb)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gb, resp, err
|
||||
}
|
||||
|
||||
// GetGroupBadge gets a group badge.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_badges.html#get-a-badge-of-a-group
|
||||
func (s *GroupBadgesService) GetGroupBadge(gid interface{}, badge int, options ...RequestOptionFunc) (*GroupBadge, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/badges/%d", pathEscape(group), badge)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gb := new(GroupBadge)
|
||||
resp, err := s.client.Do(req, gb)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gb, resp, err
|
||||
}
|
||||
|
||||
// AddGroupBadgeOptions represents the available AddGroupBadge() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_badges.html#add-a-badge-to-a-group
|
||||
type AddGroupBadgeOptions struct {
|
||||
LinkURL *string `url:"link_url,omitempty" json:"link_url,omitempty"`
|
||||
ImageURL *string `url:"image_url,omitempty" json:"image_url,omitempty"`
|
||||
}
|
||||
|
||||
// AddGroupBadge adds a badge to a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_badges.html#add-a-badge-to-a-group
|
||||
func (s *GroupBadgesService) AddGroupBadge(gid interface{}, opt *AddGroupBadgeOptions, options ...RequestOptionFunc) (*GroupBadge, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/badges", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gb := new(GroupBadge)
|
||||
resp, err := s.client.Do(req, gb)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gb, resp, err
|
||||
}
|
||||
|
||||
// EditGroupBadgeOptions represents the available EditGroupBadge() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_badges.html#edit-a-badge-of-a-group
|
||||
type EditGroupBadgeOptions struct {
|
||||
LinkURL *string `url:"link_url,omitempty" json:"link_url,omitempty"`
|
||||
ImageURL *string `url:"image_url,omitempty" json:"image_url,omitempty"`
|
||||
}
|
||||
|
||||
// EditGroupBadge updates a badge of a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_badges.html#edit-a-badge-of-a-group
|
||||
func (s *GroupBadgesService) EditGroupBadge(gid interface{}, badge int, opt *EditGroupBadgeOptions, options ...RequestOptionFunc) (*GroupBadge, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/badges/%d", pathEscape(group), badge)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gb := new(GroupBadge)
|
||||
resp, err := s.client.Do(req, gb)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gb, resp, err
|
||||
}
|
||||
|
||||
// DeleteGroupBadge removes a badge from a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_badges.html#remove-a-badge-from-a-group
|
||||
func (s *GroupBadgesService) DeleteGroupBadge(gid interface{}, badge int, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/badges/%d", pathEscape(group), badge)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// GroupBadgePreviewOptions represents the available PreviewGroupBadge() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_badges.html#preview-a-badge-from-a-group
|
||||
type GroupBadgePreviewOptions struct {
|
||||
LinkURL *string `url:"link_url,omitempty" json:"link_url,omitempty"`
|
||||
ImageURL *string `url:"image_url,omitempty" json:"image_url,omitempty"`
|
||||
}
|
||||
|
||||
// PreviewGroupBadge returns how the link_url and image_url final URLs would be after
|
||||
// resolving the placeholder interpolation.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_badges.html#preview-a-badge-from-a-group
|
||||
func (s *GroupBadgesService) PreviewGroupBadge(gid interface{}, opt *GroupBadgePreviewOptions, options ...RequestOptionFunc) (*GroupBadge, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/badges/render", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gb := new(GroupBadge)
|
||||
resp, err := s.client.Do(req, &gb)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gb, resp, err
|
||||
}
|
352
vendor/github.com/xanzy/go-gitlab/group_boards.go
generated
vendored
Normal file
352
vendor/github.com/xanzy/go-gitlab/group_boards.go
generated
vendored
Normal file
|
@ -0,0 +1,352 @@
|
|||
//
|
||||
// Copyright 2021, Patrick Webster
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// GroupIssueBoardsService handles communication with the group issue board
|
||||
// related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_boards.html
|
||||
type GroupIssueBoardsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// GroupIssueBoard represents a GitLab group issue board.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_boards.html
|
||||
type GroupIssueBoard struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Group *Group `json:"group"`
|
||||
Milestone *Milestone `json:"milestone"`
|
||||
Lists []*BoardList `json:"lists"`
|
||||
}
|
||||
|
||||
func (b GroupIssueBoard) String() string {
|
||||
return Stringify(b)
|
||||
}
|
||||
|
||||
// ListGroupIssueBoardsOptions represents the available
|
||||
// ListGroupIssueBoards() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_boards.html#group-board
|
||||
type ListGroupIssueBoardsOptions ListOptions
|
||||
|
||||
// ListGroupIssueBoards gets a list of all issue boards in a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_boards.html#group-board
|
||||
func (s *GroupIssueBoardsService) ListGroupIssueBoards(gid interface{}, opt *ListGroupIssueBoardsOptions, options ...RequestOptionFunc) ([]*GroupIssueBoard, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/boards", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var gs []*GroupIssueBoard
|
||||
resp, err := s.client.Do(req, &gs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gs, resp, err
|
||||
}
|
||||
|
||||
// CreateGroupIssueBoardOptions represents the available
|
||||
// CreateGroupIssueBoard() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_boards.html#create-a-group-issue-board-premium
|
||||
type CreateGroupIssueBoardOptions struct {
|
||||
Name *string `url:"name" json:"name"`
|
||||
}
|
||||
|
||||
// CreateGroupIssueBoard creates a new issue board.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_boards.html#create-a-group-issue-board-premium
|
||||
func (s *GroupIssueBoardsService) CreateGroupIssueBoard(gid interface{}, opt *CreateGroupIssueBoardOptions, options ...RequestOptionFunc) (*GroupIssueBoard, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/boards", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gib := new(GroupIssueBoard)
|
||||
resp, err := s.client.Do(req, gib)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gib, resp, err
|
||||
}
|
||||
|
||||
// GetGroupIssueBoard gets a single issue board of a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_boards.html#single-board
|
||||
func (s *GroupIssueBoardsService) GetGroupIssueBoard(gid interface{}, board int, options ...RequestOptionFunc) (*GroupIssueBoard, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/boards/%d", pathEscape(group), board)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gib := new(GroupIssueBoard)
|
||||
resp, err := s.client.Do(req, gib)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gib, resp, err
|
||||
}
|
||||
|
||||
// UpdateGroupIssueBoardOptions represents a group issue board.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_boards.html#update-a-group-issue-board-premium
|
||||
type UpdateGroupIssueBoardOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
|
||||
MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"`
|
||||
Labels Labels `url:"labels,omitempty" json:"labels,omitempty"`
|
||||
Weight *int `url:"weight,omitempty" json:"weight,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateIssueBoard updates a single issue board of a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_boards.html#update-a-group-issue-board-premium
|
||||
func (s *GroupIssueBoardsService) UpdateIssueBoard(gid interface{}, board int, opt *UpdateGroupIssueBoardOptions, options ...RequestOptionFunc) (*GroupIssueBoard, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/boards/%d", pathEscape(group), board)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gib := new(GroupIssueBoard)
|
||||
resp, err := s.client.Do(req, gib)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gib, resp, err
|
||||
}
|
||||
|
||||
// DeleteIssueBoard delete a single issue board of a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_boards.html#delete-a-group-issue-board-premium
|
||||
func (s *GroupIssueBoardsService) DeleteIssueBoard(gid interface{}, board int, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/boards/%d", pathEscape(group), board)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// ListGroupIssueBoardListsOptions represents the available
|
||||
// ListGroupIssueBoardLists() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_boards.html#list-board-lists
|
||||
type ListGroupIssueBoardListsOptions ListOptions
|
||||
|
||||
// ListGroupIssueBoardLists gets a list of the issue board's lists. Does not include
|
||||
// backlog and closed lists.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/group_boards.html#list-board-lists
|
||||
func (s *GroupIssueBoardsService) ListGroupIssueBoardLists(gid interface{}, board int, opt *ListGroupIssueBoardListsOptions, options ...RequestOptionFunc) ([]*BoardList, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/boards/%d/lists", pathEscape(group), board)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var gbl []*BoardList
|
||||
resp, err := s.client.Do(req, &gbl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gbl, resp, err
|
||||
}
|
||||
|
||||
// GetGroupIssueBoardList gets a single issue board list.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_boards.html#single-board-list
|
||||
func (s *GroupIssueBoardsService) GetGroupIssueBoardList(gid interface{}, board, list int, options ...RequestOptionFunc) (*BoardList, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/boards/%d/lists/%d",
|
||||
pathEscape(group),
|
||||
board,
|
||||
list,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gbl := new(BoardList)
|
||||
resp, err := s.client.Do(req, gbl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gbl, resp, err
|
||||
}
|
||||
|
||||
// CreateGroupIssueBoardListOptions represents the available
|
||||
// CreateGroupIssueBoardList() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_boards.html#new-board-list
|
||||
type CreateGroupIssueBoardListOptions struct {
|
||||
LabelID *int `url:"label_id" json:"label_id"`
|
||||
}
|
||||
|
||||
// CreateGroupIssueBoardList creates a new issue board list.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_boards.html#new-board-list
|
||||
func (s *GroupIssueBoardsService) CreateGroupIssueBoardList(gid interface{}, board int, opt *CreateGroupIssueBoardListOptions, options ...RequestOptionFunc) (*BoardList, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/boards/%d/lists", pathEscape(group), board)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gbl := new(BoardList)
|
||||
resp, err := s.client.Do(req, gbl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gbl, resp, err
|
||||
}
|
||||
|
||||
// UpdateGroupIssueBoardListOptions represents the available
|
||||
// UpdateGroupIssueBoardList() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_boards.html#edit-board-list
|
||||
type UpdateGroupIssueBoardListOptions struct {
|
||||
Position *int `url:"position" json:"position"`
|
||||
}
|
||||
|
||||
// UpdateIssueBoardList updates the position of an existing
|
||||
// group issue board list.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_boards.html#edit-board-list
|
||||
func (s *GroupIssueBoardsService) UpdateIssueBoardList(gid interface{}, board, list int, opt *UpdateGroupIssueBoardListOptions, options ...RequestOptionFunc) ([]*BoardList, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/boards/%d/lists/%d",
|
||||
pathEscape(group),
|
||||
board,
|
||||
list,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var gbl []*BoardList
|
||||
resp, err := s.client.Do(req, gbl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gbl, resp, err
|
||||
}
|
||||
|
||||
// DeleteGroupIssueBoardList soft deletes a group issue board list.
|
||||
// Only for admins and group owners.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_boards.html#delete-a-board-list
|
||||
func (s *GroupIssueBoardsService) DeleteGroupIssueBoardList(gid interface{}, board, list int, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/boards/%d/lists/%d",
|
||||
pathEscape(group),
|
||||
board,
|
||||
list,
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
217
vendor/github.com/xanzy/go-gitlab/group_clusters.go
generated
vendored
Normal file
217
vendor/github.com/xanzy/go-gitlab/group_clusters.go
generated
vendored
Normal file
|
@ -0,0 +1,217 @@
|
|||
//
|
||||
// Copyright 2021, Paul Shoemaker
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GroupClustersService handles communication with the
|
||||
// group clusters related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_clusters.html
|
||||
type GroupClustersService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// GroupCluster represents a GitLab Group Cluster.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/group_clusters.html
|
||||
type GroupCluster struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Domain string `json:"domain"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
Managed bool `json:"managed"`
|
||||
Enabled bool `json:"enabled"`
|
||||
ProviderType string `json:"provider_type"`
|
||||
PlatformType string `json:"platform_type"`
|
||||
EnvironmentScope string `json:"environment_scope"`
|
||||
ClusterType string `json:"cluster_type"`
|
||||
User *User `json:"user"`
|
||||
PlatformKubernetes *PlatformKubernetes `json:"platform_kubernetes"`
|
||||
ManagementProject *ManagementProject `json:"management_project"`
|
||||
Group *Group `json:"group"`
|
||||
}
|
||||
|
||||
func (v GroupCluster) String() string {
|
||||
return Stringify(v)
|
||||
}
|
||||
|
||||
// ListClusters gets a list of all clusters in a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_clusters.html#list-group-clusters
|
||||
func (s *GroupClustersService) ListClusters(pid interface{}, options ...RequestOptionFunc) ([]*GroupCluster, *Response, error) {
|
||||
group, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/clusters", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var pcs []*GroupCluster
|
||||
resp, err := s.client.Do(req, &pcs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pcs, resp, err
|
||||
}
|
||||
|
||||
// GetCluster gets a cluster.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_clusters.html#get-a-single-group-cluster
|
||||
func (s *GroupClustersService) GetCluster(pid interface{}, cluster int, options ...RequestOptionFunc) (*GroupCluster, *Response, error) {
|
||||
group, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/clusters/%d", pathEscape(group), cluster)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gc := new(GroupCluster)
|
||||
resp, err := s.client.Do(req, &gc)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gc, resp, err
|
||||
}
|
||||
|
||||
// AddGroupClusterOptions represents the available AddCluster() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_clusters.html#add-existing-cluster-to-group
|
||||
type AddGroupClusterOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Domain *string `url:"domain,omitempty" json:"domain,omitempty"`
|
||||
ManagementProjectID *string `url:"management_project_id,omitempty" json:"management_project_id,omitempty"`
|
||||
Enabled *bool `url:"enabled,omitempty" json:"enabled,omitempty"`
|
||||
Managed *bool `url:"managed,omitempty" json:"managed,omitempty"`
|
||||
EnvironmentScope *string `url:"environment_scope,omitempty" json:"environment_scope,omitempty"`
|
||||
PlatformKubernetes *AddGroupPlatformKubernetesOptions `url:"platform_kubernetes_attributes,omitempty" json:"platform_kubernetes_attributes,omitempty"`
|
||||
}
|
||||
|
||||
// AddGroupPlatformKubernetesOptions represents the available PlatformKubernetes options for adding.
|
||||
type AddGroupPlatformKubernetesOptions struct {
|
||||
APIURL *string `url:"api_url,omitempty" json:"api_url,omitempty"`
|
||||
Token *string `url:"token,omitempty" json:"token,omitempty"`
|
||||
CaCert *string `url:"ca_cert,omitempty" json:"ca_cert,omitempty"`
|
||||
Namespace *string `url:"namespace,omitempty" json:"namespace,omitempty"`
|
||||
AuthorizationType *string `url:"authorization_type,omitempty" json:"authorization_type,omitempty"`
|
||||
}
|
||||
|
||||
// AddCluster adds an existing cluster to the group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_clusters.html#add-existing-cluster-to-group
|
||||
func (s *GroupClustersService) AddCluster(pid interface{}, opt *AddGroupClusterOptions, options ...RequestOptionFunc) (*GroupCluster, *Response, error) {
|
||||
group, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/clusters/user", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gc := new(GroupCluster)
|
||||
resp, err := s.client.Do(req, gc)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gc, resp, err
|
||||
}
|
||||
|
||||
// EditGroupClusterOptions represents the available EditCluster() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_clusters.html#edit-group-cluster
|
||||
type EditGroupClusterOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Domain *string `url:"domain,omitempty" json:"domain,omitempty"`
|
||||
EnvironmentScope *string `url:"environment_scope,omitempty" json:"environment_scope,omitempty"`
|
||||
PlatformKubernetes *EditGroupPlatformKubernetesOptions `url:"platform_kubernetes_attributes,omitempty" json:"platform_kubernetes_attributes,omitempty"`
|
||||
ManagementProjectID *string `url:"management_project_id,omitempty" json:"management_project_id,omitempty"`
|
||||
}
|
||||
|
||||
// EditGroupPlatformKubernetesOptions represents the available PlatformKubernetes options for editing.
|
||||
type EditGroupPlatformKubernetesOptions struct {
|
||||
APIURL *string `url:"api_url,omitempty" json:"api_url,omitempty"`
|
||||
Token *string `url:"token,omitempty" json:"token,omitempty"`
|
||||
CaCert *string `url:"ca_cert,omitempty" json:"ca_cert,omitempty"`
|
||||
}
|
||||
|
||||
// EditCluster updates an existing group cluster.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_clusters.html#edit-group-cluster
|
||||
func (s *GroupClustersService) EditCluster(pid interface{}, cluster int, opt *EditGroupClusterOptions, options ...RequestOptionFunc) (*GroupCluster, *Response, error) {
|
||||
group, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/clusters/%d", pathEscape(group), cluster)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gc := new(GroupCluster)
|
||||
resp, err := s.client.Do(req, gc)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gc, resp, err
|
||||
}
|
||||
|
||||
// DeleteCluster deletes an existing group cluster.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_clusters.html#delete-group-cluster
|
||||
func (s *GroupClustersService) DeleteCluster(pid interface{}, cluster int, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/clusters/%d", pathEscape(group), cluster)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
206
vendor/github.com/xanzy/go-gitlab/group_hooks.go
generated
vendored
Normal file
206
vendor/github.com/xanzy/go-gitlab/group_hooks.go
generated
vendored
Normal file
|
@ -0,0 +1,206 @@
|
|||
//
|
||||
// Copyright 2021, Eric Stevens
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GroupHook represents a GitLab group hook.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#list-group-hooks
|
||||
type GroupHook struct {
|
||||
ID int `json:"id"`
|
||||
URL string `json:"url"`
|
||||
GroupID int `json:"group_id"`
|
||||
PushEvents bool `json:"push_events"`
|
||||
IssuesEvents bool `json:"issues_events"`
|
||||
ConfidentialIssuesEvents bool `json:"confidential_issues_events"`
|
||||
ConfidentialNoteEvents bool `json:"confidential_note_events"`
|
||||
MergeRequestsEvents bool `json:"merge_requests_events"`
|
||||
TagPushEvents bool `json:"tag_push_events"`
|
||||
NoteEvents bool `json:"note_events"`
|
||||
JobEvents bool `json:"job_events"`
|
||||
PipelineEvents bool `json:"pipeline_events"`
|
||||
WikiPageEvents bool `json:"wiki_page_events"`
|
||||
DeploymentEvents bool `json:"deployment_events"`
|
||||
ReleasesEvents bool `json:"releases_events"`
|
||||
EnableSSLVerification bool `json:"enable_ssl_verification"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// ListGroupHooks gets a list of group hooks.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#list-group-hooks
|
||||
func (s *GroupsService) ListGroupHooks(gid interface{}) ([]*GroupHook, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/hooks", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, nil)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
var gh []*GroupHook
|
||||
resp, err := s.client.Do(req, &gh)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gh, resp, err
|
||||
}
|
||||
|
||||
// GetGroupHook gets a specific hook for a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#get-group-hook
|
||||
func (s *GroupsService) GetGroupHook(pid interface{}, hook int, options ...RequestOptionFunc) (*GroupHook, *Response, error) {
|
||||
group, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/hooks/%d", pathEscape(group), hook)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gh := new(GroupHook)
|
||||
resp, err := s.client.Do(req, gh)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gh, resp, err
|
||||
}
|
||||
|
||||
// AddGroupHookOptions represents the available AddGroupHook() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/groups.html#add-group-hook
|
||||
type AddGroupHookOptions struct {
|
||||
URL *string `url:"url,omitempty" json:"url,omitempty"`
|
||||
PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"`
|
||||
IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"`
|
||||
ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"`
|
||||
ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"`
|
||||
MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"`
|
||||
TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"`
|
||||
NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"`
|
||||
JobEvents *bool `url:"job_events,omitempty" json:"job_events,omitempty"`
|
||||
PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"`
|
||||
WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"`
|
||||
DeploymentEvents *bool `url:"deployment_events,omitempty" json:"deployment_events,omitempty"`
|
||||
ReleasesEvents *bool `url:"releases_events,omitempty" json:"releases_events,omitempty"`
|
||||
EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"`
|
||||
Token *string `url:"token,omitempty" json:"token,omitempty"`
|
||||
}
|
||||
|
||||
// AddGroupHook create a new group scoped webhook.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/groups.html#add-group-hook
|
||||
func (s *GroupsService) AddGroupHook(gid interface{}, opt *AddGroupHookOptions, options ...RequestOptionFunc) (*GroupHook, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/hooks", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gh := new(GroupHook)
|
||||
resp, err := s.client.Do(req, gh)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gh, resp, err
|
||||
}
|
||||
|
||||
// EditGroupHookOptions represents the available EditGroupHook() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#edit-group-hook
|
||||
type EditGroupHookOptions struct {
|
||||
URL *string `url:"url,omitempty" json:"url,omitempty"`
|
||||
PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"`
|
||||
IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"`
|
||||
ConfidentialIssuesEvents *bool `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"`
|
||||
ConfidentialNoteEvents *bool `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"`
|
||||
MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"`
|
||||
TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"`
|
||||
NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"`
|
||||
JobEvents *bool `url:"job_events,omitempty" json:"job_events,omitempty"`
|
||||
PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"`
|
||||
WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"`
|
||||
DeploymentEvents *bool `url:"deployment_events,omitempty" json:"deployment_events,omitempty"`
|
||||
ReleasesEvents *bool `url:"releases_events,omitempty" json:"releases_events,omitempty"`
|
||||
EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"`
|
||||
Token *string `url:"token,omitempty" json:"token,omitempty"`
|
||||
}
|
||||
|
||||
// EditGroupHook edits a hook for a specified group.
|
||||
//
|
||||
// Gitlab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#edit-group-hook
|
||||
func (s *GroupsService) EditGroupHook(pid interface{}, hook int, opt *EditGroupHookOptions, options ...RequestOptionFunc) (*GroupHook, *Response, error) {
|
||||
group, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/hooks/%d", pathEscape(group), hook)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gh := new(GroupHook)
|
||||
resp, err := s.client.Do(req, gh)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gh, resp, err
|
||||
}
|
||||
|
||||
// DeleteGroupHook removes a hook from a group. This is an idempotent
|
||||
// method and can be called multiple times.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#delete-group-hook
|
||||
func (s *GroupsService) DeleteGroupHook(pid interface{}, hook int, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/hooks/%d", pathEscape(group), hook)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
180
vendor/github.com/xanzy/go-gitlab/group_import_export.go
generated
vendored
Normal file
180
vendor/github.com/xanzy/go-gitlab/group_import_export.go
generated
vendored
Normal file
|
@ -0,0 +1,180 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
// GroupImportExportService handles communication with the group import export
|
||||
// related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/group_import_export.html
|
||||
type GroupImportExportService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// ScheduleExport starts a new group export.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_import_export.html#schedule-new-export
|
||||
func (s *GroupImportExportService) ScheduleExport(gid interface{}, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/export", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// ExportDownload downloads the finished export.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_import_export.html#export-download
|
||||
func (s *GroupImportExportService) ExportDownload(gid interface{}, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/export/download", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
exportDownload := new(bytes.Buffer)
|
||||
resp, err := s.client.Do(req, exportDownload)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return bytes.NewReader(exportDownload.Bytes()), resp, err
|
||||
}
|
||||
|
||||
// GroupImportFileOptions represents the available ImportFile() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_import_export.html#import-a-file
|
||||
type GroupImportFileOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Path *string `url:"path,omitempty" json:"path,omitempty"`
|
||||
File *string `url:"file,omitempty" json:"file,omitempty"`
|
||||
ParentID *int `url:"parent_id,omitempty" json:"parent_id,omitempty"`
|
||||
}
|
||||
|
||||
// ImportFile imports a file.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_import_export.html#import-a-file
|
||||
func (s *GroupImportExportService) ImportFile(opt *GroupImportFileOptions, options ...RequestOptionFunc) (*Response, error) {
|
||||
// First check if we got all required options.
|
||||
if opt.Name == nil || *opt.Name == "" {
|
||||
return nil, fmt.Errorf("Missing required option: Name")
|
||||
}
|
||||
if opt.Path == nil || *opt.Path == "" {
|
||||
return nil, fmt.Errorf("Missing required option: Path")
|
||||
}
|
||||
if opt.File == nil || *opt.File == "" {
|
||||
return nil, fmt.Errorf("Missing required option: File")
|
||||
}
|
||||
|
||||
f, err := os.Open(*opt.File)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
b := &bytes.Buffer{}
|
||||
w := multipart.NewWriter(b)
|
||||
|
||||
_, filename := filepath.Split(*opt.File)
|
||||
fw, err := w.CreateFormFile("file", filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = io.Copy(fw, f)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Populate the additional fields.
|
||||
fw, err = w.CreateFormField("name")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = fw.Write([]byte(*opt.Name))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fw, err = w.CreateFormField("path")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = fw.Write([]byte(*opt.Path))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if opt.ParentID != nil {
|
||||
fw, err = w.CreateFormField("parent_id")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = fw.Write([]byte(strconv.Itoa(*opt.ParentID)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if err = w.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, "groups/import", nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Set the buffer as the request body.
|
||||
if err = req.SetBody(b); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Overwrite the default content type.
|
||||
req.Header.Set("Content-Type", w.FormDataContentType())
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
242
vendor/github.com/xanzy/go-gitlab/group_labels.go
generated
vendored
Normal file
242
vendor/github.com/xanzy/go-gitlab/group_labels.go
generated
vendored
Normal file
|
@ -0,0 +1,242 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
// GroupLabelsService handles communication with the label related methods of the
|
||||
// GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/group_labels.html
|
||||
type GroupLabelsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// GroupLabel represents a GitLab group label.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/group_labels.html
|
||||
type GroupLabel Label
|
||||
|
||||
func (l GroupLabel) String() string {
|
||||
return Stringify(l)
|
||||
}
|
||||
|
||||
// ListGroupLabelsOptions represents the available ListGroupLabels() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#list-labels
|
||||
type ListGroupLabelsOptions ListOptions
|
||||
|
||||
// ListGroupLabels gets all labels for given group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_labels.html#list-group-labels
|
||||
func (s *GroupLabelsService) ListGroupLabels(gid interface{}, opt *ListGroupLabelsOptions, options ...RequestOptionFunc) ([]*GroupLabel, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/labels", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var l []*GroupLabel
|
||||
resp, err := s.client.Do(req, &l)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return l, resp, err
|
||||
}
|
||||
|
||||
// GetGroupLabel get a single label for a given group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_labels.html#get-a-single-group-label
|
||||
func (s *GroupLabelsService) GetGroupLabel(gid interface{}, labelID interface{}, options ...RequestOptionFunc) (*GroupLabel, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
label, err := parseID(labelID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/labels/%s", pathEscape(group), label)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var l *GroupLabel
|
||||
resp, err := s.client.Do(req, &l)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return l, resp, err
|
||||
}
|
||||
|
||||
// CreateGroupLabelOptions represents the available CreateGroupLabel() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_labels.html#create-a-new-group-label
|
||||
type CreateGroupLabelOptions CreateLabelOptions
|
||||
|
||||
// CreateGroupLabel creates a new label for given group with given name and
|
||||
// color.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_labels.html#create-a-new-group-label
|
||||
func (s *GroupLabelsService) CreateGroupLabel(gid interface{}, opt *CreateGroupLabelOptions, options ...RequestOptionFunc) (*GroupLabel, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/labels", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
l := new(GroupLabel)
|
||||
resp, err := s.client.Do(req, l)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return l, resp, err
|
||||
}
|
||||
|
||||
// DeleteGroupLabelOptions represents the available DeleteGroupLabel() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_labels.html#delete-a-group-label
|
||||
type DeleteGroupLabelOptions DeleteLabelOptions
|
||||
|
||||
// DeleteGroupLabel deletes a group label given by its name.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#delete-a-label
|
||||
func (s *GroupLabelsService) DeleteGroupLabel(gid interface{}, opt *DeleteGroupLabelOptions, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/labels", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// UpdateGroupLabelOptions represents the available UpdateGroupLabel() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_labels.html#update-a-group-label
|
||||
type UpdateGroupLabelOptions UpdateLabelOptions
|
||||
|
||||
// UpdateGroupLabel updates an existing label with new name or now color. At least
|
||||
// one parameter is required, to update the label.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_labels.html#update-a-group-label
|
||||
func (s *GroupLabelsService) UpdateGroupLabel(gid interface{}, opt *UpdateGroupLabelOptions, options ...RequestOptionFunc) (*GroupLabel, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/labels", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
l := new(GroupLabel)
|
||||
resp, err := s.client.Do(req, l)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return l, resp, err
|
||||
}
|
||||
|
||||
// SubscribeToGroupLabel subscribes the authenticated user to a label to receive
|
||||
// notifications. If the user is already subscribed to the label, the status
|
||||
// code 304 is returned.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_labels.html#subscribe-to-a-group-label
|
||||
func (s *GroupLabelsService) SubscribeToGroupLabel(gid interface{}, labelID interface{}, options ...RequestOptionFunc) (*GroupLabel, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
label, err := parseID(labelID)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/labels/%s/subscribe", pathEscape(group), label)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
l := new(GroupLabel)
|
||||
resp, err := s.client.Do(req, l)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return l, resp, err
|
||||
}
|
||||
|
||||
// UnsubscribeFromGroupLabel unsubscribes the authenticated user from a label to not
|
||||
// receive notifications from it. If the user is not subscribed to the label, the
|
||||
// status code 304 is returned.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_labels.html#unsubscribe-from-a-group-label
|
||||
func (s *GroupLabelsService) UnsubscribeFromGroupLabel(gid interface{}, labelID interface{}, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
label, err := parseID(labelID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/labels/%s/unsubscribe", pathEscape(group), label)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
347
vendor/github.com/xanzy/go-gitlab/group_members.go
generated
vendored
Normal file
347
vendor/github.com/xanzy/go-gitlab/group_members.go
generated
vendored
Normal file
|
@ -0,0 +1,347 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GroupMembersService handles communication with the group members
|
||||
// related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/members.html
|
||||
type GroupMembersService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// GroupMemberSAMLIdentity represents the SAML Identity link for the group member.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/members.html#list-all-members-of-a-group-or-project
|
||||
// Gitlab MR for API change: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/20357
|
||||
// Gitlab MR for API Doc change: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/25652
|
||||
type GroupMemberSAMLIdentity struct {
|
||||
ExternUID string `json:"extern_uid"`
|
||||
Provider string `json:"provider"`
|
||||
SAMLProviderID int `json:"saml_provider_id"`
|
||||
}
|
||||
|
||||
// GroupMember represents a GitLab group member.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/members.html
|
||||
type GroupMember struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
ExpiresAt *ISOTime `json:"expires_at"`
|
||||
AccessLevel AccessLevelValue `json:"access_level"`
|
||||
GroupSAMLIdentity *GroupMemberSAMLIdentity `json:"group_saml_identity"`
|
||||
}
|
||||
|
||||
// ListGroupMembersOptions represents the available ListGroupMembers() and
|
||||
// ListAllGroupMembers() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#list-all-members-of-a-group-or-project
|
||||
type ListGroupMembersOptions struct {
|
||||
ListOptions
|
||||
Query *string `url:"query,omitempty" json:"query,omitempty"`
|
||||
}
|
||||
|
||||
// ListGroupMembers get a list of group members viewable by the authenticated
|
||||
// user. Inherited members through ancestor groups are not included.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#list-all-members-of-a-group-or-project
|
||||
func (s *GroupsService) ListGroupMembers(gid interface{}, opt *ListGroupMembersOptions, options ...RequestOptionFunc) ([]*GroupMember, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/members", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var gm []*GroupMember
|
||||
resp, err := s.client.Do(req, &gm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gm, resp, err
|
||||
}
|
||||
|
||||
// ListAllGroupMembers get a list of group members viewable by the authenticated
|
||||
// user. Returns a list including inherited members through ancestor groups.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#list-all-members-of-a-group-or-project-including-inherited-members
|
||||
func (s *GroupsService) ListAllGroupMembers(gid interface{}, opt *ListGroupMembersOptions, options ...RequestOptionFunc) ([]*GroupMember, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/members/all", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var gm []*GroupMember
|
||||
resp, err := s.client.Do(req, &gm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gm, resp, err
|
||||
}
|
||||
|
||||
// AddGroupMemberOptions represents the available AddGroupMember() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#add-a-member-to-a-group-or-project
|
||||
type AddGroupMemberOptions struct {
|
||||
UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"`
|
||||
AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"`
|
||||
ExpiresAt *string `url:"expires_at,omitempty" json:"expires_at"`
|
||||
}
|
||||
|
||||
// GetGroupMember gets a member of a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#get-a-member-of-a-group-or-project
|
||||
func (s *GroupMembersService) GetGroupMember(gid interface{}, user int, options ...RequestOptionFunc) (*GroupMember, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/members/%d", pathEscape(group), user)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gm := new(GroupMember)
|
||||
resp, err := s.client.Do(req, gm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gm, resp, err
|
||||
}
|
||||
|
||||
// BillableGroupMember represents a GitLab billable group member.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/members.html#list-all-billable-members-of-a-group
|
||||
type BillableGroupMember struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
Email string `json:"email"`
|
||||
LastActivityOn ISOTime `json:"last_activity_on"`
|
||||
}
|
||||
|
||||
// ListBillableGroupMembersOptions represents the available ListBillableGroupMembers() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/members.html#list-all-billable-members-of-a-group
|
||||
type ListBillableGroupMembersOptions struct {
|
||||
ListOptions
|
||||
Search *string `url:"search,omitempty" json:"search,omitempty"`
|
||||
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
|
||||
}
|
||||
|
||||
// ListBillableGroupMembers Gets a list of group members that count as billable.
|
||||
// The list includes members in the subgroup or subproject.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/members.html#list-all-billable-members-of-a-group
|
||||
func (s *GroupsService) ListBillableGroupMembers(gid interface{}, opt *ListBillableGroupMembersOptions, options ...RequestOptionFunc) ([]*BillableGroupMember, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/billable_members", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var bgm []*BillableGroupMember
|
||||
resp, err := s.client.Do(req, &bgm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return bgm, resp, err
|
||||
}
|
||||
|
||||
// RemoveBillableGroupMember removes a given group members that count as billable.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/members.html#remove-a-billable-member-from-a-group
|
||||
func (s *GroupsService) RemoveBillableGroupMember(gid interface{}, user int, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/billable_members/%d", pathEscape(group), user)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// AddGroupMember adds a user to the list of group members.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#add-a-member-to-a-group-or-project
|
||||
func (s *GroupMembersService) AddGroupMember(gid interface{}, opt *AddGroupMemberOptions, options ...RequestOptionFunc) (*GroupMember, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/members", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gm := new(GroupMember)
|
||||
resp, err := s.client.Do(req, gm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gm, resp, err
|
||||
}
|
||||
|
||||
// ShareWithGroup shares a group with the group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#share-groups-with-groups
|
||||
func (s *GroupMembersService) ShareWithGroup(gid interface{}, opt *ShareWithGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/share", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(Group)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// DeleteShareWithGroup allows to unshare a group from a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#delete-link-sharing-group-with-another-group
|
||||
func (s *GroupMembersService) DeleteShareWithGroup(gid interface{}, groupID int, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/share/%d", pathEscape(group), groupID)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// EditGroupMemberOptions represents the available EditGroupMember()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#edit-a-member-of-a-group-or-project
|
||||
type EditGroupMemberOptions struct {
|
||||
AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"`
|
||||
ExpiresAt *string `url:"expires_at,omitempty" json:"expires_at"`
|
||||
}
|
||||
|
||||
// EditGroupMember updates a member of a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#edit-a-member-of-a-group-or-project
|
||||
func (s *GroupMembersService) EditGroupMember(gid interface{}, user int, opt *EditGroupMemberOptions, options ...RequestOptionFunc) (*GroupMember, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/members/%d", pathEscape(group), user)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gm := new(GroupMember)
|
||||
resp, err := s.client.Do(req, gm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gm, resp, err
|
||||
}
|
||||
|
||||
// RemoveGroupMember removes user from user team.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/members.html#remove-a-member-from-a-group-or-project
|
||||
func (s *GroupMembersService) RemoveGroupMember(gid interface{}, user int, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/members/%d", pathEscape(group), user)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
296
vendor/github.com/xanzy/go-gitlab/group_milestones.go
generated
vendored
Normal file
296
vendor/github.com/xanzy/go-gitlab/group_milestones.go
generated
vendored
Normal file
|
@ -0,0 +1,296 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GroupMilestonesService handles communication with the milestone related
|
||||
// methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/group_milestones.html
|
||||
type GroupMilestonesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// GroupMilestone represents a GitLab milestone.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/group_milestones.html
|
||||
type GroupMilestone struct {
|
||||
ID int `json:"id"`
|
||||
IID int `json:"iid"`
|
||||
GroupID int `json:"group_id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
StartDate *ISOTime `json:"start_date"`
|
||||
DueDate *ISOTime `json:"due_date"`
|
||||
State string `json:"state"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
Expired *bool `json:"expired"`
|
||||
}
|
||||
|
||||
func (m GroupMilestone) String() string {
|
||||
return Stringify(m)
|
||||
}
|
||||
|
||||
// ListGroupMilestonesOptions represents the available
|
||||
// ListGroupMilestones() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#list-group-milestones
|
||||
type ListGroupMilestonesOptions struct {
|
||||
ListOptions
|
||||
IIDs []int `url:"iids[],omitempty" json:"iids,omitempty"`
|
||||
State *string `url:"state,omitempty" json:"state,omitempty"`
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Search *string `url:"search,omitempty" json:"search,omitempty"`
|
||||
IncludeParentMilestones *bool `url:"include_parent_milestones,omitempty" json:"include_parent_milestones,omitempty"`
|
||||
}
|
||||
|
||||
// ListGroupMilestones returns a list of group milestones.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#list-group-milestones
|
||||
func (s *GroupMilestonesService) ListGroupMilestones(gid interface{}, opt *ListGroupMilestonesOptions, options ...RequestOptionFunc) ([]*GroupMilestone, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/milestones", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var m []*GroupMilestone
|
||||
resp, err := s.client.Do(req, &m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// GetGroupMilestone gets a single group milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#get-single-milestone
|
||||
func (s *GroupMilestonesService) GetGroupMilestone(gid interface{}, milestone int, options ...RequestOptionFunc) (*GroupMilestone, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/milestones/%d", pathEscape(group), milestone)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(GroupMilestone)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// CreateGroupMilestoneOptions represents the available CreateGroupMilestone() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#create-new-milestone
|
||||
type CreateGroupMilestoneOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
StartDate *ISOTime `url:"start_date,omitempty" json:"start_date,omitempty"`
|
||||
DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"`
|
||||
}
|
||||
|
||||
// CreateGroupMilestone creates a new group milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#create-new-milestone
|
||||
func (s *GroupMilestonesService) CreateGroupMilestone(gid interface{}, opt *CreateGroupMilestoneOptions, options ...RequestOptionFunc) (*GroupMilestone, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/milestones", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(GroupMilestone)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// UpdateGroupMilestoneOptions represents the available UpdateGroupMilestone() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#edit-milestone
|
||||
type UpdateGroupMilestoneOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
StartDate *ISOTime `url:"start_date,omitempty" json:"start_date,omitempty"`
|
||||
DueDate *ISOTime `url:"due_date,omitempty" json:"due_date,omitempty"`
|
||||
StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateGroupMilestone updates an existing group milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#edit-milestone
|
||||
func (s *GroupMilestonesService) UpdateGroupMilestone(gid interface{}, milestone int, opt *UpdateGroupMilestoneOptions, options ...RequestOptionFunc) (*GroupMilestone, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/milestones/%d", pathEscape(group), milestone)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(GroupMilestone)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// GetGroupMilestoneIssuesOptions represents the available GetGroupMilestoneIssues() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#get-all-issues-assigned-to-a-single-milestone
|
||||
type GetGroupMilestoneIssuesOptions ListOptions
|
||||
|
||||
// GetGroupMilestoneIssues gets all issues assigned to a single group milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#get-all-issues-assigned-to-a-single-milestone
|
||||
func (s *GroupMilestonesService) GetGroupMilestoneIssues(gid interface{}, milestone int, opt *GetGroupMilestoneIssuesOptions, options ...RequestOptionFunc) ([]*Issue, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/milestones/%d/issues", pathEscape(group), milestone)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var i []*Issue
|
||||
resp, err := s.client.Do(req, &i)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return i, resp, err
|
||||
}
|
||||
|
||||
// GetGroupMilestoneMergeRequestsOptions represents the available
|
||||
// GetGroupMilestoneMergeRequests() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#get-all-merge-requests-assigned-to-a-single-milestone
|
||||
type GetGroupMilestoneMergeRequestsOptions ListOptions
|
||||
|
||||
// GetGroupMilestoneMergeRequests gets all merge requests assigned to a
|
||||
// single group milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/group_milestones.html#get-all-merge-requests-assigned-to-a-single-milestone
|
||||
func (s *GroupMilestonesService) GetGroupMilestoneMergeRequests(gid interface{}, milestone int, opt *GetGroupMilestoneMergeRequestsOptions, options ...RequestOptionFunc) ([]*MergeRequest, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/milestones/%d/merge_requests", pathEscape(group), milestone)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var mr []*MergeRequest
|
||||
resp, err := s.client.Do(req, &mr)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return mr, resp, err
|
||||
}
|
||||
|
||||
// BurndownChartEvent reprensents a burnout chart event
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_milestones.html#get-all-burndown-chart-events-for-a-single-milestone-starter
|
||||
type BurndownChartEvent struct {
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
Weight *int `json:"weight"`
|
||||
Action *string `json:"action"`
|
||||
}
|
||||
|
||||
// GetGroupMilestoneBurndownChartEventsOptions represents the available
|
||||
// GetGroupMilestoneBurndownChartEventsOptions() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_milestones.html#get-all-burndown-chart-events-for-a-single-milestone-starter
|
||||
type GetGroupMilestoneBurndownChartEventsOptions ListOptions
|
||||
|
||||
// GetGroupMilestoneBurndownChartEvents gets all merge requests assigned to a
|
||||
// single group milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_milestones.html#get-all-burndown-chart-events-for-a-single-milestone-starter
|
||||
func (s *GroupMilestonesService) GetGroupMilestoneBurndownChartEvents(gid interface{}, milestone int, opt *GetGroupMilestoneBurndownChartEventsOptions, options ...RequestOptionFunc) ([]*BurndownChartEvent, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/milestones/%d/burndown_events", pathEscape(group), milestone)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var be []*BurndownChartEvent
|
||||
resp, err := s.client.Do(req, &be)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return be, resp, err
|
||||
}
|
203
vendor/github.com/xanzy/go-gitlab/group_variables.go
generated
vendored
Normal file
203
vendor/github.com/xanzy/go-gitlab/group_variables.go
generated
vendored
Normal file
|
@ -0,0 +1,203 @@
|
|||
//
|
||||
// Copyright 2021, Patrick Webster
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// GroupVariablesService handles communication with the
|
||||
// group variables related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_level_variables.html
|
||||
type GroupVariablesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// GroupVariable represents a GitLab group Variable.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_level_variables.html
|
||||
type GroupVariable struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
VariableType VariableTypeValue `json:"variable_type"`
|
||||
Protected bool `json:"protected"`
|
||||
Masked bool `json:"masked"`
|
||||
EnvironmentScope string `json:"environment_scope"`
|
||||
}
|
||||
|
||||
func (v GroupVariable) String() string {
|
||||
return Stringify(v)
|
||||
}
|
||||
|
||||
// ListGroupVariablesOptions represents the available options for listing variables
|
||||
// for a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_level_variables.html#list-group-variables
|
||||
type ListGroupVariablesOptions ListOptions
|
||||
|
||||
// ListVariables gets a list of all variables for a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_level_variables.html#list-group-variables
|
||||
func (s *GroupVariablesService) ListVariables(gid interface{}, opt *ListGroupVariablesOptions, options ...RequestOptionFunc) ([]*GroupVariable, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/variables", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var vs []*GroupVariable
|
||||
resp, err := s.client.Do(req, &vs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return vs, resp, err
|
||||
}
|
||||
|
||||
// GetVariable gets a variable.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_level_variables.html#show-variable-details
|
||||
func (s *GroupVariablesService) GetVariable(gid interface{}, key string, options ...RequestOptionFunc) (*GroupVariable, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/variables/%s", pathEscape(group), url.PathEscape(key))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
v := new(GroupVariable)
|
||||
resp, err := s.client.Do(req, v)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return v, resp, err
|
||||
}
|
||||
|
||||
// CreateGroupVariableOptions represents the available CreateVariable()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_level_variables.html#create-variable
|
||||
type CreateGroupVariableOptions struct {
|
||||
Key *string `url:"key,omitempty" json:"key,omitempty"`
|
||||
Value *string `url:"value,omitempty" json:"value,omitempty"`
|
||||
VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"`
|
||||
Protected *bool `url:"protected,omitempty" json:"protected,omitempty"`
|
||||
Masked *bool `url:"masked,omitempty" json:"masked,omitempty"`
|
||||
EnvironmentScope *string `url:"environment_scope,omitempty" json:"environment_scope,omitempty"`
|
||||
}
|
||||
|
||||
// CreateVariable creates a new group variable.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_level_variables.html#create-variable
|
||||
func (s *GroupVariablesService) CreateVariable(gid interface{}, opt *CreateGroupVariableOptions, options ...RequestOptionFunc) (*GroupVariable, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/variables", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
v := new(GroupVariable)
|
||||
resp, err := s.client.Do(req, v)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return v, resp, err
|
||||
}
|
||||
|
||||
// UpdateGroupVariableOptions represents the available UpdateVariable()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_level_variables.html#update-variable
|
||||
type UpdateGroupVariableOptions struct {
|
||||
Value *string `url:"value,omitempty" json:"value,omitempty"`
|
||||
VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"`
|
||||
Protected *bool `url:"protected,omitempty" json:"protected,omitempty"`
|
||||
Masked *bool `url:"masked,omitempty" json:"masked,omitempty"`
|
||||
EnvironmentScope *string `url:"environment_scope,omitempty" json:"environment_scope,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateVariable updates the position of an existing
|
||||
// group issue board list.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_level_variables.html#update-variable
|
||||
func (s *GroupVariablesService) UpdateVariable(gid interface{}, key string, opt *UpdateGroupVariableOptions, options ...RequestOptionFunc) (*GroupVariable, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/variables/%s", pathEscape(group), url.PathEscape(key))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
v := new(GroupVariable)
|
||||
resp, err := s.client.Do(req, v)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return v, resp, err
|
||||
}
|
||||
|
||||
// RemoveVariable removes a group's variable.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_level_variables.html#remove-variable
|
||||
func (s *GroupVariablesService) RemoveVariable(gid interface{}, key string, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/variables/%s", pathEscape(group), url.PathEscape(key))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
194
vendor/github.com/xanzy/go-gitlab/group_wikis.go
generated
vendored
Normal file
194
vendor/github.com/xanzy/go-gitlab/group_wikis.go
generated
vendored
Normal file
|
@ -0,0 +1,194 @@
|
|||
//
|
||||
// Copyright 2021, Markus Lackner
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// GroupWikisService handles communication with the group wikis related methods of
|
||||
// the Gitlab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/group_wikis.html
|
||||
type GroupWikisService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// GroupWiki represents a GitLab groups wiki.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/group_wikis.html
|
||||
type GroupWiki struct {
|
||||
Content string `json:"content"`
|
||||
Format WikiFormatValue `json:"format"`
|
||||
Slug string `json:"slug"`
|
||||
Title string `json:"title"`
|
||||
}
|
||||
|
||||
func (w GroupWiki) String() string {
|
||||
return Stringify(w)
|
||||
}
|
||||
|
||||
// ListGroupWikisOptions represents the available ListGroupWikis options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_wikis.html#list-wiki-pages
|
||||
type ListGroupWikisOptions struct {
|
||||
WithContent *bool `url:"with_content,omitempty" json:"with_content,omitempty"`
|
||||
}
|
||||
|
||||
// ListGroupWikis lists all pages of the wiki of the given group id.
|
||||
// When with_content is set, it also returns the content of the pages.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_wikis.html#list-wiki-pages
|
||||
func (s *GroupWikisService) ListGroupWikis(gid interface{}, opt *ListGroupWikisOptions, options ...RequestOptionFunc) ([]*GroupWiki, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/wikis", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var gws []*GroupWiki
|
||||
resp, err := s.client.Do(req, &gws)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gws, resp, err
|
||||
}
|
||||
|
||||
// GetGroupWikiPage gets a wiki page for a given group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_wikis.html#get-a-wiki-page
|
||||
func (s *GroupWikisService) GetGroupWikiPage(gid interface{}, slug string, options ...RequestOptionFunc) (*GroupWiki, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/wikis/%s", pathEscape(group), url.PathEscape(slug))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gw := new(GroupWiki)
|
||||
resp, err := s.client.Do(req, gw)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gw, resp, err
|
||||
}
|
||||
|
||||
// CreateGroupWikiPageOptions represents options to CreateGroupWikiPage.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_wikis.html#create-a-new-wiki-page
|
||||
type CreateGroupWikiPageOptions struct {
|
||||
Content *string `url:"content,omitempty" json:"content,omitempty"`
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Format *WikiFormatValue `url:"format,omitempty" json:"format,omitempty"`
|
||||
}
|
||||
|
||||
// CreateGroupWikiPage creates a new wiki page for the given group with
|
||||
// the given title, slug, and content.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/13.8/ee/api/group_wikis.html#create-a-new-wiki-page
|
||||
func (s *GroupWikisService) CreateGroupWikiPage(gid interface{}, opt *CreateGroupWikiPageOptions, options ...RequestOptionFunc) (*GroupWiki, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/wikis", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
w := new(GroupWiki)
|
||||
resp, err := s.client.Do(req, w)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return w, resp, err
|
||||
}
|
||||
|
||||
// EditGroupWikiPageOptions represents options to EditGroupWikiPage.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_wikis.html#edit-an-existing-wiki-page
|
||||
type EditGroupWikiPageOptions struct {
|
||||
Content *string `url:"content,omitempty" json:"content,omitempty"`
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Format *WikiFormatValue `url:"format,omitempty" json:"format,omitempty"`
|
||||
}
|
||||
|
||||
// EditGroupWikiPage Updates an existing wiki page. At least one parameter is
|
||||
// required to update the wiki page.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_wikis.html#edit-an-existing-wiki-page
|
||||
func (s *GroupWikisService) EditGroupWikiPage(gid interface{}, slug string, opt *EditGroupWikiPageOptions, options ...RequestOptionFunc) (*GroupWiki, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/wikis/%s", pathEscape(group), url.PathEscape(slug))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
w := new(GroupWiki)
|
||||
resp, err := s.client.Do(req, w)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return w, resp, err
|
||||
}
|
||||
|
||||
// DeleteGroupWikiPage deletes a wiki page with a given slug.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/group_wikis.html#delete-a-wiki-page
|
||||
func (s *GroupWikisService) DeleteGroupWikiPage(gid interface{}, slug string, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/wikis/%s", pathEscape(group), url.PathEscape(slug))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
805
vendor/github.com/xanzy/go-gitlab/groups.go
generated
vendored
Normal file
805
vendor/github.com/xanzy/go-gitlab/groups.go
generated
vendored
Normal file
|
@ -0,0 +1,805 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// GroupsService handles communication with the group related methods of
|
||||
// the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html
|
||||
type GroupsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Group represents a GitLab group.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html
|
||||
type Group struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
Description string `json:"description"`
|
||||
MembershipLock bool `json:"membership_lock"`
|
||||
Visibility VisibilityValue `json:"visibility"`
|
||||
LFSEnabled bool `json:"lfs_enabled"`
|
||||
DefaultBranchProtection int `json:"default_branch_protection"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
RequestAccessEnabled bool `json:"request_access_enabled"`
|
||||
FullName string `json:"full_name"`
|
||||
FullPath string `json:"full_path"`
|
||||
ParentID int `json:"parent_id"`
|
||||
Projects []*Project `json:"projects"`
|
||||
Statistics *StorageStatistics `json:"statistics"`
|
||||
CustomAttributes []*CustomAttribute `json:"custom_attributes"`
|
||||
ShareWithGroupLock bool `json:"share_with_group_lock"`
|
||||
RequireTwoFactorAuth bool `json:"require_two_factor_authentication"`
|
||||
TwoFactorGracePeriod int `json:"two_factor_grace_period"`
|
||||
ProjectCreationLevel ProjectCreationLevelValue `json:"project_creation_level"`
|
||||
AutoDevopsEnabled bool `json:"auto_devops_enabled"`
|
||||
SubGroupCreationLevel SubGroupCreationLevelValue `json:"subgroup_creation_level"`
|
||||
EmailsDisabled bool `json:"emails_disabled"`
|
||||
MentionsDisabled bool `json:"mentions_disabled"`
|
||||
RunnersToken string `json:"runners_token"`
|
||||
SharedProjects []*Project `json:"shared_projects"`
|
||||
SharedWithGroups []struct {
|
||||
GroupID int `json:"group_id"`
|
||||
GroupName string `json:"group_name"`
|
||||
GroupFullPath string `json:"group_full_path"`
|
||||
GroupAccessLevel int `json:"group_access_level"`
|
||||
ExpiresAt *ISOTime `json:"expires_at"`
|
||||
} `json:"shared_with_groups"`
|
||||
LDAPCN string `json:"ldap_cn"`
|
||||
LDAPAccess AccessLevelValue `json:"ldap_access"`
|
||||
LDAPGroupLinks []*LDAPGroupLink `json:"ldap_group_links"`
|
||||
SharedRunnersMinutesLimit int `json:"shared_runners_minutes_limit"`
|
||||
ExtraSharedRunnersMinutesLimit int `json:"extra_shared_runners_minutes_limit"`
|
||||
MarkedForDeletionOn *ISOTime `json:"marked_for_deletion_on"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// LDAPGroupLink represents a GitLab LDAP group link.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#ldap-group-links
|
||||
type LDAPGroupLink struct {
|
||||
CN string `json:"cn"`
|
||||
Filter string `json:"filter"`
|
||||
GroupAccess AccessLevelValue `json:"group_access"`
|
||||
Provider string `json:"provider"`
|
||||
}
|
||||
|
||||
// ListGroupsOptions represents the available ListGroups() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#list-project-groups
|
||||
type ListGroupsOptions struct {
|
||||
ListOptions
|
||||
AllAvailable *bool `url:"all_available,omitempty" json:"all_available,omitempty"`
|
||||
MinAccessLevel *AccessLevelValue `url:"min_access_level,omitempty" json:"min_access_level,omitempty"`
|
||||
OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
|
||||
Owned *bool `url:"owned,omitempty" json:"owned,omitempty"`
|
||||
Search *string `url:"search,omitempty" json:"search,omitempty"`
|
||||
SkipGroups []int `url:"skip_groups,omitempty" json:"skip_groups,omitempty"`
|
||||
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
|
||||
Statistics *bool `url:"statistics,omitempty" json:"statistics,omitempty"`
|
||||
TopLevelOnly *bool `url:"top_level_only,omitempty" json:"top_level_only,omitempty"`
|
||||
WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"`
|
||||
}
|
||||
|
||||
// ListGroups gets a list of groups (as user: my groups, as admin: all groups).
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-project-groups
|
||||
func (s *GroupsService) ListGroups(opt *ListGroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) {
|
||||
req, err := s.client.NewRequest(http.MethodGet, "groups", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var g []*Group
|
||||
resp, err := s.client.Do(req, &g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// GetGroupOptions represents the available GetGroup() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#details-of-a-group
|
||||
type GetGroupOptions struct {
|
||||
ListOptions
|
||||
WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"`
|
||||
WithProjects *bool `url:"with_projects,omitempty" json:"with_projects,omitempty"`
|
||||
}
|
||||
|
||||
// GetGroup gets all details of a group.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#details-of-a-group
|
||||
func (s *GroupsService) GetGroup(gid interface{}, opt *GetGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(Group)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// CreateGroupOptions represents the available CreateGroup() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#new-group
|
||||
type CreateGroupOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Path *string `url:"path,omitempty" json:"path,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
MembershipLock *bool `url:"membership_lock,omitempty" json:"membership_lock,omitempty"`
|
||||
Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"`
|
||||
ShareWithGroupLock *bool `url:"share_with_group_lock,omitempty" json:"share_with_group_lock,omitempty"`
|
||||
RequireTwoFactorAuth *bool `url:"require_two_factor_authentication,omitempty" json:"require_two_factor_authentication,omitempty"`
|
||||
TwoFactorGracePeriod *int `url:"two_factor_grace_period,omitempty" json:"two_factor_grace_period,omitempty"`
|
||||
ProjectCreationLevel *ProjectCreationLevelValue `url:"project_creation_level,omitempty" json:"project_creation_level,omitempty"`
|
||||
AutoDevopsEnabled *bool `url:"auto_devops_enabled,omitempty" json:"auto_devops_enabled,omitempty"`
|
||||
SubGroupCreationLevel *SubGroupCreationLevelValue `url:"subgroup_creation_level,omitempty" json:"subgroup_creation_level,omitempty"`
|
||||
EmailsDisabled *bool `url:"emails_disabled,omitempty" json:"emails_disabled,omitempty"`
|
||||
MentionsDisabled *bool `url:"mentions_disabled,omitempty" json:"mentions_disabled,omitempty"`
|
||||
LFSEnabled *bool `url:"lfs_enabled,omitempty" json:"lfs_enabled,omitempty"`
|
||||
DefaultBranchProtection *int `url:"default_branch_protection,omitempty" json:"default_branch_protection"`
|
||||
RequestAccessEnabled *bool `url:"request_access_enabled,omitempty" json:"request_access_enabled,omitempty"`
|
||||
ParentID *int `url:"parent_id,omitempty" json:"parent_id,omitempty"`
|
||||
SharedRunnersMinutesLimit *int `url:"shared_runners_minutes_limit,omitempty" json:"shared_runners_minutes_limit,omitempty"`
|
||||
ExtraSharedRunnersMinutesLimit *int `url:"extra_shared_runners_minutes_limit,omitempty" json:"extra_shared_runners_minutes_limit,omitempty"`
|
||||
}
|
||||
|
||||
// CreateGroup creates a new project group. Available only for users who can
|
||||
// create groups.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#new-group
|
||||
func (s *GroupsService) CreateGroup(opt *CreateGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) {
|
||||
req, err := s.client.NewRequest(http.MethodPost, "groups", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(Group)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// TransferGroup transfers a project to the Group namespace. Available only
|
||||
// for admin.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#transfer-project-to-group
|
||||
func (s *GroupsService) TransferGroup(gid interface{}, pid interface{}, options ...RequestOptionFunc) (*Group, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/projects/%s", pathEscape(group), pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(Group)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// UpdateGroupOptions represents the available UpdateGroup() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/groups.html#update-group
|
||||
type UpdateGroupOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Path *string `url:"path,omitempty" json:"path,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
MembershipLock *bool `url:"membership_lock,omitempty" json:"membership_lock,omitempty"`
|
||||
Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"`
|
||||
ShareWithGroupLock *bool `url:"share_with_group_lock,omitempty" json:"share_with_group_lock,omitempty"`
|
||||
RequireTwoFactorAuth *bool `url:"require_two_factor_authentication,omitempty" json:"require_two_factor_authentication,omitempty"`
|
||||
TwoFactorGracePeriod *int `url:"two_factor_grace_period,omitempty" json:"two_factor_grace_period,omitempty"`
|
||||
ProjectCreationLevel *ProjectCreationLevelValue `url:"project_creation_level,omitempty" json:"project_creation_level,omitempty"`
|
||||
AutoDevopsEnabled *bool `url:"auto_devops_enabled,omitempty" json:"auto_devops_enabled,omitempty"`
|
||||
SubGroupCreationLevel *SubGroupCreationLevelValue `url:"subgroup_creation_level,omitempty" json:"subgroup_creation_level,omitempty"`
|
||||
EmailsDisabled *bool `url:"emails_disabled,omitempty" json:"emails_disabled,omitempty"`
|
||||
MentionsDisabled *bool `url:"mentions_disabled,omitempty" json:"mentions_disabled,omitempty"`
|
||||
LFSEnabled *bool `url:"lfs_enabled,omitempty" json:"lfs_enabled,omitempty"`
|
||||
RequestAccessEnabled *bool `url:"request_access_enabled,omitempty" json:"request_access_enabled,omitempty"`
|
||||
DefaultBranchProtection *int `url:"default_branch_protection,omitempty" json:"default_branch_protection,omitempty"`
|
||||
FileTemplateProjectID *int `url:"file_template_project_id,omitempty" json:"file_template_project_id,omitempty"`
|
||||
SharedRunnersMinutesLimit *int `url:"shared_runners_minutes_limit,omitempty" json:"shared_runners_minutes_limit,omitempty"`
|
||||
ExtraSharedRunnersMinutesLimit *int `url:"extra_shared_runners_minutes_limit,omitempty" json:"extra_shared_runners_minutes_limit,omitempty"`
|
||||
PreventForkingOutsideGroup *bool `url:"prevent_forking_outside_group,omitempty" json:"prevent_forking_outside_group,omitempty"`
|
||||
SharedRunnersSetting *SharedRunnersSettingValue `url:"shared_runners_setting,omitempty" json:"shared_runners_setting,omitempty"`
|
||||
PreventSharingGroupsOutsideHierarchy *bool `url:"prevent_sharing_groups_outside_hierarchy,omitempty" json:"prevent_sharing_groups_outside_hierarchy,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateGroup updates an existing group; only available to group owners and
|
||||
// administrators.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#update-group
|
||||
func (s *GroupsService) UpdateGroup(gid interface{}, opt *UpdateGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(Group)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// DeleteGroup removes group with all projects inside.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#remove-group
|
||||
func (s *GroupsService) DeleteGroup(gid interface{}, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// RestoreGroup restores a previously deleted group
|
||||
//
|
||||
// GitLap API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#restore-group-marked-for-deletion
|
||||
func (s *GroupsService) RestoreGroup(gid interface{}, options ...RequestOptionFunc) (*Group, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/restore", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(Group)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, nil
|
||||
}
|
||||
|
||||
// SearchGroup get all groups that match your string in their name or path.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#search-for-group
|
||||
func (s *GroupsService) SearchGroup(query string, options ...RequestOptionFunc) ([]*Group, *Response, error) {
|
||||
var q struct {
|
||||
Search string `url:"search,omitempty" json:"search,omitempty"`
|
||||
}
|
||||
q.Search = query
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, "groups", &q, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var g []*Group
|
||||
resp, err := s.client.Do(req, &g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// ListGroupProjectsOptions represents the available ListGroup() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-a-group-39-s-projects
|
||||
type ListGroupProjectsOptions struct {
|
||||
ListOptions
|
||||
Archived *bool `url:"archived,omitempty" json:"archived,omitempty"`
|
||||
IncludeSubgroups *bool `url:"include_subgroups,omitempty" json:"include_subgroups,omitempty"`
|
||||
MinAccessLevel *AccessLevelValue `url:"min_access_level,omitempty" json:"min_access_level,omitempty"`
|
||||
OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
|
||||
Owned *bool `url:"owned,omitempty" json:"owned,omitempty"`
|
||||
Search *string `url:"search,omitempty" json:"search,omitempty"`
|
||||
Simple *bool `url:"simple,omitempty" json:"simple,omitempty"`
|
||||
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
|
||||
Starred *bool `url:"starred,omitempty" json:"starred,omitempty"`
|
||||
Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"`
|
||||
WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"`
|
||||
WithIssuesEnabled *bool `url:"with_issues_enabled,omitempty" json:"with_issues_enabled,omitempty"`
|
||||
WithMergeRequestsEnabled *bool `url:"with_merge_requests_enabled,omitempty" json:"with_merge_requests_enabled,omitempty"`
|
||||
WithSecurityReports *bool `url:"with_security_reports,omitempty" json:"with_security_reports,omitempty"`
|
||||
WithShared *bool `url:"with_shared,omitempty" json:"with_shared,omitempty"`
|
||||
}
|
||||
|
||||
// ListGroupProjects get a list of group projects
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-a-group-39-s-projects
|
||||
func (s *GroupsService) ListGroupProjects(gid interface{}, opt *ListGroupProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/projects", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var p []*Project
|
||||
resp, err := s.client.Do(req, &p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// ListSubgroupsOptions represents the available ListSubgroups() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-a-groups-s-subgroups
|
||||
type ListSubgroupsOptions ListGroupsOptions
|
||||
|
||||
// ListSubgroups gets a list of subgroups for a given group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-a-groups-s-subgroups
|
||||
func (s *GroupsService) ListSubgroups(gid interface{}, opt *ListSubgroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/subgroups", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var g []*Group
|
||||
resp, err := s.client.Do(req, &g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// ListDescendantGroupsOptions represents the available ListDescendantGroups()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-a-groups-descendant-groups
|
||||
type ListDescendantGroupsOptions ListGroupsOptions
|
||||
|
||||
// ListDescendantGroups gets a list of subgroups for a given project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-a-groups-descendant-groups
|
||||
func (s *GroupsService) ListDescendantGroups(gid interface{}, opt *ListDescendantGroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/descendant_groups", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var g []*Group
|
||||
resp, err := s.client.Do(req, &g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// ListGroupLDAPLinks lists the group's LDAP links. Available only for users who
|
||||
// can edit groups.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#list-ldap-group-links-starter
|
||||
func (s *GroupsService) ListGroupLDAPLinks(gid interface{}, options ...RequestOptionFunc) ([]*LDAPGroupLink, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/ldap_group_links", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var gl []*LDAPGroupLink
|
||||
resp, err := s.client.Do(req, &gl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gl, resp, nil
|
||||
}
|
||||
|
||||
// AddGroupLDAPLinkOptions represents the available AddGroupLDAPLink() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#add-ldap-group-link-starter
|
||||
type AddGroupLDAPLinkOptions struct {
|
||||
CN *string `url:"cn,omitempty" json:"cn,omitempty"`
|
||||
Filter *string `url:"filter,omitempty" json:"filter,omitempty"`
|
||||
GroupAccess *AccessLevelValue `url:"group_access,omitempty" json:"group_access,omitempty"`
|
||||
Provider *string `url:"provider,omitempty" json:"provider,omitempty"`
|
||||
}
|
||||
|
||||
// DeleteGroupLDAPLinkWithCNOrFilterOptions represents the available DeleteGroupLDAPLinkWithCNOrFilter() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#delete-ldap-group-link-with-cn-or-filter
|
||||
type DeleteGroupLDAPLinkWithCNOrFilterOptions struct {
|
||||
CN *string `url:"cn,omitempty" json:"cn,omitempty"`
|
||||
Filter *string `url:"filter,omitempty" json:"filter,omitempty"`
|
||||
Provider *string `url:"provider,omitempty" json:"provider,omitempty"`
|
||||
}
|
||||
|
||||
// AddGroupLDAPLink creates a new group LDAP link. Available only for users who
|
||||
// can edit groups.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#add-ldap-group-link-starter
|
||||
func (s *GroupsService) AddGroupLDAPLink(gid interface{}, opt *AddGroupLDAPLinkOptions, options ...RequestOptionFunc) (*LDAPGroupLink, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/ldap_group_links", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gl := new(LDAPGroupLink)
|
||||
resp, err := s.client.Do(req, gl)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gl, resp, err
|
||||
}
|
||||
|
||||
// DeleteGroupLDAPLink deletes a group LDAP link. Available only for users who
|
||||
// can edit groups.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#delete-ldap-group-link-starter
|
||||
func (s *GroupsService) DeleteGroupLDAPLink(gid interface{}, cn string, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/ldap_group_links/%s", pathEscape(group), pathEscape(cn))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// DeleteGroupLDAPLinkWithCNOrFilter deletes a group LDAP link. Available only for users who
|
||||
// can edit groups.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#delete-ldap-group-link-with-cn-or-filter
|
||||
func (s *GroupsService) DeleteGroupLDAPLinkWithCNOrFilter(gid interface{}, opts *DeleteGroupLDAPLinkWithCNOrFilterOptions, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/ldap_group_links", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, opts, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// DeleteGroupLDAPLinkForProvider deletes a group LDAP link from a specific
|
||||
// provider. Available only for users who can edit groups.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#delete-ldap-group-link-starter
|
||||
func (s *GroupsService) DeleteGroupLDAPLinkForProvider(gid interface{}, provider, cn string, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf(
|
||||
"groups/%s/ldap_group_links/%s/%s",
|
||||
pathEscape(group),
|
||||
pathEscape(provider),
|
||||
pathEscape(cn),
|
||||
)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// ShareGroupWithGroupOptions represents the available ShareGroupWithGroup() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#share-groups-with-groups
|
||||
type ShareGroupWithGroupOptions struct {
|
||||
GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"`
|
||||
GroupAccess *AccessLevelValue `url:"group_access,omitempty" json:"group_access,omitempty"`
|
||||
ExpiresAt *ISOTime `url:"expires_at,omitempty" json:"expires_at,omitempty"`
|
||||
}
|
||||
|
||||
// ShareGroupWithGroup shares a group with another group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#create-a-link-to-share-a-group-with-another-group
|
||||
func (s *GroupsService) ShareGroupWithGroup(gid interface{}, opt *ShareGroupWithGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/share", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(Group)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// UnshareGroupFromGroup unshares a group from another group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#delete-link-sharing-group-with-another-group
|
||||
func (s *GroupsService) UnshareGroupFromGroup(gid interface{}, groupID int, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/share/%d", pathEscape(group), groupID)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// GroupPushRules represents a group push rule.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#get-group-push-rules
|
||||
type GroupPushRules struct {
|
||||
ID int `json:"id"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
CommitMessageRegex string `json:"commit_message_regex"`
|
||||
CommitMessageNegativeRegex string `json:"commit_message_negative_regex"`
|
||||
BranchNameRegex string `json:"branch_name_regex"`
|
||||
DenyDeleteTag bool `json:"deny_delete_tag"`
|
||||
MemberCheck bool `json:"member_check"`
|
||||
PreventSecrets bool `json:"prevent_secrets"`
|
||||
AuthorEmailRegex string `json:"author_email_regex"`
|
||||
FileNameRegex string `json:"file_name_regex"`
|
||||
MaxFileSize int `json:"max_file_size"`
|
||||
CommitCommitterCheck bool `json:"commit_committer_check"`
|
||||
RejectUnsignedCommits bool `json:"reject_unsigned_commits"`
|
||||
}
|
||||
|
||||
// GetGroupPushRules gets the push rules of a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#get-group-push-rules
|
||||
func (s *GroupsService) GetGroupPushRules(gid interface{}, options ...RequestOptionFunc) (*GroupPushRules, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/push_rule", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gpr := new(GroupPushRules)
|
||||
resp, err := s.client.Do(req, gpr)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gpr, resp, err
|
||||
}
|
||||
|
||||
// AddGroupPushRuleOptions represents the available AddGroupPushRule()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#add-group-push-rule
|
||||
type AddGroupPushRuleOptions struct {
|
||||
AuthorEmailRegex *string `url:"author_email_regex,omitempty" json:"author_email_regex,omitempty"`
|
||||
BranchNameRegex *string `url:"branch_name_regex,omitempty" json:"branch_name_regex,omitempty"`
|
||||
CommitCommitterCheck *bool `url:"commit_committer_check,omitempty" json:"commit_committer_check,omitempty"`
|
||||
CommitMessageNegativeRegex *string `url:"commit_message_negative_regex,omitempty" json:"commit_message_negative_regex,omitempty"`
|
||||
CommitMessageRegex *string `url:"commit_message_regex,omitempty" json:"commit_message_regex,omitempty"`
|
||||
DenyDeleteTag *bool `url:"deny_delete_tag,omitempty" json:"deny_delete_tag,omitempty"`
|
||||
FileNameRegex *string `url:"file_name_regex,omitempty" json:"file_name_regex,omitempty"`
|
||||
MaxFileSize *int `url:"max_file_size,omitempty" json:"max_file_size,omitempty"`
|
||||
MemberCheck *bool `url:"member_check,omitempty" json:"member_check,omitempty"`
|
||||
PreventSecrets *bool `url:"prevent_secrets,omitempty" json:"prevent_secrets,omitempty"`
|
||||
RejectUnsignedCommits *bool `url:"reject_unsigned_commits,omitempty" json:"reject_unsigned_commits,omitempty"`
|
||||
}
|
||||
|
||||
// AddGroupPushRule adds push rules to the specified group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#add-group-push-rule
|
||||
func (s *GroupsService) AddGroupPushRule(gid interface{}, opt *AddGroupPushRuleOptions, options ...RequestOptionFunc) (*GroupPushRules, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/push_rule", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gpr := new(GroupPushRules)
|
||||
resp, err := s.client.Do(req, gpr)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gpr, resp, err
|
||||
}
|
||||
|
||||
// EditGroupPushRuleOptions represents the available EditGroupPushRule()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#edit-group-push-rule
|
||||
type EditGroupPushRuleOptions struct {
|
||||
AuthorEmailRegex *string `url:"author_email_regex,omitempty" json:"author_email_regex,omitempty"`
|
||||
BranchNameRegex *string `url:"branch_name_regex,omitempty" json:"branch_name_regex,omitempty"`
|
||||
CommitCommitterCheck *bool `url:"commit_committer_check,omitempty" json:"commit_committer_check,omitempty"`
|
||||
CommitMessageNegativeRegex *string `url:"commit_message_negative_regex,omitempty" json:"commit_message_negative_regex,omitempty"`
|
||||
CommitMessageRegex *string `url:"commit_message_regex,omitempty" json:"commit_message_regex,omitempty"`
|
||||
DenyDeleteTag *bool `url:"deny_delete_tag,omitempty" json:"deny_delete_tag,omitempty"`
|
||||
FileNameRegex *string `url:"file_name_regex,omitempty" json:"file_name_regex,omitempty"`
|
||||
MaxFileSize *int `url:"max_file_size,omitempty" json:"max_file_size,omitempty"`
|
||||
MemberCheck *bool `url:"member_check,omitempty" json:"member_check,omitempty"`
|
||||
PreventSecrets *bool `url:"prevent_secrets,omitempty" json:"prevent_secrets,omitempty"`
|
||||
RejectUnsignedCommits *bool `url:"reject_unsigned_commits,omitempty" json:"reject_unsigned_commits,omitempty"`
|
||||
}
|
||||
|
||||
// EditGroupPushRule edits a push rule for a specified group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#edit-group-push-rule
|
||||
func (s *GroupsService) EditGroupPushRule(gid interface{}, opt *EditGroupPushRuleOptions, options ...RequestOptionFunc) (*GroupPushRules, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/push_rule", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
gpr := new(GroupPushRules)
|
||||
resp, err := s.client.Do(req, gpr)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return gpr, resp, err
|
||||
}
|
||||
|
||||
// DeleteGroupPushRule deletes the push rules of a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/groups.html#delete-group-push-rule
|
||||
func (s *GroupsService) DeleteGroupPushRule(gid interface{}, options ...RequestOptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/push_rule", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
153
vendor/github.com/xanzy/go-gitlab/instance_clusters.go
generated
vendored
Normal file
153
vendor/github.com/xanzy/go-gitlab/instance_clusters.go
generated
vendored
Normal file
|
@ -0,0 +1,153 @@
|
|||
//
|
||||
// Copyright 2021, Serena Fang
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// InstanceClustersService handles communication with the
|
||||
// instance clusters related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/instance_clusters.html
|
||||
type InstanceClustersService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// InstanceCluster represents a GitLab Instance Cluster.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/instance_clusters.html
|
||||
type InstanceCluster struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Domain string `json:"domain"`
|
||||
Managed bool `json:"managed"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
ProviderType string `json:"provider_type"`
|
||||
PlatformType string `json:"platform_type"`
|
||||
EnvironmentScope string `json:"environment_scope"`
|
||||
ClusterType string `json:"cluster_type"`
|
||||
User *User `json:"user"`
|
||||
PlatformKubernetes *PlatformKubernetes `json:"platform_kubernetes"`
|
||||
ManagementProject *ManagementProject `json:"management_project"`
|
||||
}
|
||||
|
||||
func (v InstanceCluster) String() string {
|
||||
return Stringify(v)
|
||||
}
|
||||
|
||||
// ListClusters gets a list of all instance clusters.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/instance_clusters.html#list-instance-clusters
|
||||
func (s *InstanceClustersService) ListClusters(options ...RequestOptionFunc) ([]*InstanceCluster, *Response, error) {
|
||||
u := "admin/clusters"
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ics []*InstanceCluster
|
||||
resp, err := s.client.Do(req, &ics)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ics, resp, err
|
||||
}
|
||||
|
||||
// GetCluster gets an instance cluster.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/instance_clusters.html#get-a-single-instance-cluster
|
||||
func (s *InstanceClustersService) GetCluster(cluster int, options ...RequestOptionFunc) (*InstanceCluster, *Response, error) {
|
||||
u := fmt.Sprintf("admin/clusters/%d", cluster)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ic := new(InstanceCluster)
|
||||
resp, err := s.client.Do(req, &ic)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ic, resp, err
|
||||
}
|
||||
|
||||
// AddCluster adds an existing cluster to the instance.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/instance_clusters.html#add-existing-instance-cluster
|
||||
func (s *InstanceClustersService) AddCluster(opt *AddClusterOptions, options ...RequestOptionFunc) (*InstanceCluster, *Response, error) {
|
||||
u := "admin/clusters/add"
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ic := new(InstanceCluster)
|
||||
resp, err := s.client.Do(req, ic)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ic, resp, err
|
||||
}
|
||||
|
||||
// EditCluster updates an existing instance cluster.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/instance_clusters.html#edit-instance-cluster
|
||||
func (s *InstanceClustersService) EditCluster(cluster int, opt *EditClusterOptions, options ...RequestOptionFunc) (*InstanceCluster, *Response, error) {
|
||||
u := fmt.Sprintf("admin/clusters/%d", cluster)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ic := new(InstanceCluster)
|
||||
resp, err := s.client.Do(req, ic)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ic, resp, err
|
||||
}
|
||||
|
||||
// DeleteCluster deletes an existing instance cluster.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/instance_clusters.html#delete-instance-cluster
|
||||
func (s *InstanceClustersService) DeleteCluster(cluster int, options ...RequestOptionFunc) (*Response, error) {
|
||||
u := fmt.Sprintf("admin/clusters/%d", cluster)
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
180
vendor/github.com/xanzy/go-gitlab/instance_variables.go
generated
vendored
Normal file
180
vendor/github.com/xanzy/go-gitlab/instance_variables.go
generated
vendored
Normal file
|
@ -0,0 +1,180 @@
|
|||
//
|
||||
// Copyright 2021, Patrick Webster
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// InstanceVariablesService handles communication with the
|
||||
// instance level CI variables related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html
|
||||
type InstanceVariablesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// InstanceVariable represents a GitLab instance level CI Variable.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html
|
||||
type InstanceVariable struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
VariableType VariableTypeValue `json:"variable_type"`
|
||||
Protected bool `json:"protected"`
|
||||
Masked bool `json:"masked"`
|
||||
}
|
||||
|
||||
func (v InstanceVariable) String() string {
|
||||
return Stringify(v)
|
||||
}
|
||||
|
||||
// ListInstanceVariablesOptions represents the available options for listing variables
|
||||
// for an instance.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html#list-all-instance-variables
|
||||
type ListInstanceVariablesOptions ListOptions
|
||||
|
||||
// ListVariables gets a list of all variables for an instance.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html#list-all-instance-variables
|
||||
func (s *InstanceVariablesService) ListVariables(opt *ListInstanceVariablesOptions, options ...RequestOptionFunc) ([]*InstanceVariable, *Response, error) {
|
||||
u := "admin/ci/variables"
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var vs []*InstanceVariable
|
||||
resp, err := s.client.Do(req, &vs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return vs, resp, err
|
||||
}
|
||||
|
||||
// GetVariable gets a variable.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html#show-instance-variable-details
|
||||
func (s *InstanceVariablesService) GetVariable(key string, options ...RequestOptionFunc) (*InstanceVariable, *Response, error) {
|
||||
u := fmt.Sprintf("admin/ci/variables/%s", url.PathEscape(key))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
v := new(InstanceVariable)
|
||||
resp, err := s.client.Do(req, v)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return v, resp, err
|
||||
}
|
||||
|
||||
// CreateInstanceVariableOptions represents the available CreateVariable()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html#create-instance-variable
|
||||
type CreateInstanceVariableOptions struct {
|
||||
Key *string `url:"key,omitempty" json:"key,omitempty"`
|
||||
Value *string `url:"value,omitempty" json:"value,omitempty"`
|
||||
VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"`
|
||||
Protected *bool `url:"protected,omitempty" json:"protected,omitempty"`
|
||||
Masked *bool `url:"masked,omitempty" json:"masked,omitempty"`
|
||||
}
|
||||
|
||||
// CreateVariable creates a new instance level CI variable.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html#create-instance-variable
|
||||
func (s *InstanceVariablesService) CreateVariable(opt *CreateInstanceVariableOptions, options ...RequestOptionFunc) (*InstanceVariable, *Response, error) {
|
||||
u := "admin/ci/variables"
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
v := new(InstanceVariable)
|
||||
resp, err := s.client.Do(req, v)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return v, resp, err
|
||||
}
|
||||
|
||||
// UpdateInstanceVariableOptions represents the available UpdateVariable()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html#update-instance-variable
|
||||
type UpdateInstanceVariableOptions struct {
|
||||
Value *string `url:"value,omitempty" json:"value,omitempty"`
|
||||
VariableType *VariableTypeValue `url:"variable_type,omitempty" json:"variable_type,omitempty"`
|
||||
Protected *bool `url:"protected,omitempty" json:"protected,omitempty"`
|
||||
Masked *bool `url:"masked,omitempty" json:"masked,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateVariable updates the position of an existing
|
||||
// instance level CI variable.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html#update-instance-variable
|
||||
func (s *InstanceVariablesService) UpdateVariable(key string, opt *UpdateInstanceVariableOptions, options ...RequestOptionFunc) (*InstanceVariable, *Response, error) {
|
||||
u := fmt.Sprintf("admin/ci/variables/%s", url.PathEscape(key))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
v := new(InstanceVariable)
|
||||
resp, err := s.client.Do(req, v)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return v, resp, err
|
||||
}
|
||||
|
||||
// RemoveVariable removes an instance level CI variable.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/instance_level_ci_variables.html#remove-instance-variable
|
||||
func (s *InstanceVariablesService) RemoveVariable(key string, options ...RequestOptionFunc) (*Response, error) {
|
||||
u := fmt.Sprintf("admin/ci/variables/%s", url.PathEscape(key))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
175
vendor/github.com/xanzy/go-gitlab/invites.go
generated
vendored
Normal file
175
vendor/github.com/xanzy/go-gitlab/invites.go
generated
vendored
Normal file
|
@ -0,0 +1,175 @@
|
|||
//
|
||||
// Copyright 2021, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
)
|
||||
|
||||
// InvitesService handles communication with the invitation related
|
||||
// methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/invitations.html
|
||||
type InvitesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// PendingInvite represents a pending invite.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ee/api/invitations.html
|
||||
type PendingInvite struct {
|
||||
ID int `json:"id"`
|
||||
InviteEmail string `json:"invite_email"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
AccessLevel AccessLevelValue `json:"access_level"`
|
||||
ExpiresAt *time.Time `json:"expires_at"`
|
||||
UserName string `json:"user_name"`
|
||||
CreatedByName string `json:"created_by_name"`
|
||||
}
|
||||
|
||||
// ListPendingInvitationsOptions represents the available
|
||||
// ListPendingInvitations() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/invitations.html#list-all-invitations-pending-for-a-group-or-project
|
||||
type ListPendingInvitationsOptions struct {
|
||||
ListOptions
|
||||
Query *string `url:"query,omitempty" json:"query,omitempty"`
|
||||
}
|
||||
|
||||
// ListPendingGroupInvitations gets a list of invited group members.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/invitations.html#list-all-invitations-pending-for-a-group-or-project
|
||||
func (s *InvitesService) ListPendingGroupInvitations(gid interface{}, opt *ListPendingInvitationsOptions, options ...RequestOptionFunc) ([]*PendingInvite, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/invitations", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var pis []*PendingInvite
|
||||
resp, err := s.client.Do(req, &pis)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pis, resp, err
|
||||
}
|
||||
|
||||
// ListPendingProjectInvitations gets a list of invited project members.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/invitations.html#list-all-invitations-pending-for-a-group-or-project
|
||||
func (s *InvitesService) ListPendingProjectInvitations(pid interface{}, opt *ListPendingInvitationsOptions, options ...RequestOptionFunc) ([]*PendingInvite, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/invitations", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var pis []*PendingInvite
|
||||
resp, err := s.client.Do(req, &pis)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pis, resp, err
|
||||
}
|
||||
|
||||
// InvitesOptions represents the available GroupInvites() and ProjectInvites()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/invitations.html#invite-by-email-to-group-or-project
|
||||
type InvitesOptions struct {
|
||||
ID interface{} `url:"id,omitempty" json:"id,omitempty"`
|
||||
Email *string `url:"email,omitempty" json:"email,omitempty"`
|
||||
AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"`
|
||||
ExpiresAt *ISOTime `url:"expires_at,omitempty" json:"expires_at,omitempty"`
|
||||
}
|
||||
|
||||
// InvitesResult represents an invitations result.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/invitations.html#invite-by-email-to-group-or-project
|
||||
type InvitesResult struct {
|
||||
Status string `json:"status"`
|
||||
Message map[string]string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// GroupInvites invites new users by email to join a group.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/invitations.html#invite-by-email-to-group-or-project
|
||||
func (s *InvitesService) GroupInvites(gid interface{}, opt *InvitesOptions, options ...RequestOptionFunc) (*InvitesResult, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/invitations", pathEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ir := new(InvitesResult)
|
||||
resp, err := s.client.Do(req, ir)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ir, resp, err
|
||||
}
|
||||
|
||||
// ProjectInvites invites new users by email to join a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ee/api/invitations.html#invite-by-email-to-group-or-project
|
||||
func (s *InvitesService) ProjectInvites(pid interface{}, opt *InvitesOptions, options ...RequestOptionFunc) (*InvitesResult, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/invitations", pathEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ir := new(InvitesResult)
|
||||
resp, err := s.client.Do(req, ir)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ir, resp, err
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue