Add support for migrating from Gitlab (#9084)
* First stab at a Gitlab migrations interface. * Modify JS to show migration for Gitlab * Properly strip out #gitlab tag from repo name * Working Gitlab migrations! Still need to figure out how to hide tokens/etc from showing up in opts.CloneAddr * Try #2 at trying to hide credentials. CloneAddr was being used as OriginalURL. Now passing OriginalURL through from the form and saving it. * Add go-gitlab dependency * Vendor go-gitlab * Use gitlab.BasicAuthClient Correct CloneURL. This should be functioning! Previous commits fixed "Migrated from" from including the migration credentials. * Replaced repoPath with repoID globally. RepoID is grabbed in NewGitlabDownloader * Logging touchup * Properly set private repo status. Properly set milestone deadline time. Consistently use Gitlab username for 'Name'. * Add go-gitlab vendor cache * Fix PR migrations: - Count of issues is kept to set a non-conflicting PR.ID - Bool is used to tell whether to fetch Issue or PR comments * Ensure merged PRs are closed and set with the proper time * Remove copyright and some commented code * Rip out '#gitlab' based self-hosted Gitlab support * Hide given credentials for migrated repos. CloneAddr was being saved as OriginalURL. Now passing OriginalURL through from the form and saving it in it's place * Use asset.URL directly, no point in parsing. Opened PRs should fall through to false. * Fix importing Milestones. Allow importing using Personal Tokens or anonymous access. * Fix Gitlab Milestone migration if DueDate isn't set * Empty Milestone due dates properly return nil, not zero time * Add GITLAB_READ_TOKEN to drone unit-test step * Add working gitlab_test.go. A Personal Access Token, given in env variable GITLAB_READ_TOKEN is required to run the test. * Fix linting issues * Add modified JS files * Remove pre-build JS files * Only merged PRs are marged as merged/closed * Test topics * Skip test if gitlab is inaccessible * Grab personal token from username, not password. Matches Github migration implementation * Add SetContext() to GitlabDownloader. * Checking Updated field in Issues. * Actually fetch Issue Updated time from Gitlab * Add Gitlab migration GetReviews() stub * Fix Patch and Clone URLs * check Updated too * fix mod * make vendor with go1.14 Co-authored-by: techknowlogick <techknowlogick@gitea.io> Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Lauris BH <lauris@nix.lv> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
+12
@@ -100,6 +100,18 @@ services:
|
||||
environment:
|
||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
||||
MYSQL_DATABASE: test
|
||||
GOPROXY: off
|
||||
TAGS: bindata sqlite sqlite_unlock_notify
|
||||
GITLAB_READ_TOKEN:
|
||||
from_secret: gitlab_read_token
|
||||
depends_on:
|
||||
- build
|
||||
when:
|
||||
branch:
|
||||
- master
|
||||
event:
|
||||
- push
|
||||
- pull_request
|
||||
|
||||
- name: mysql8
|
||||
pull: default
|
||||
|
||||
@@ -104,6 +104,7 @@ require (
|
||||
github.com/unknwon/i18n v0.0.0-20190805065654-5c6446a380b6
|
||||
github.com/unknwon/paginater v0.0.0-20151104151617-7748a72e0141
|
||||
github.com/urfave/cli v1.20.0
|
||||
github.com/xanzy/go-gitlab v0.22.1
|
||||
github.com/yohcop/openid-go v0.0.0-20160914080427-2c050d2dae53
|
||||
github.com/yuin/goldmark v1.1.25
|
||||
github.com/yuin/goldmark-meta v0.0.0-20191126180153-f0638e958b60
|
||||
|
||||
@@ -608,6 +608,8 @@ github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/willf/bitset v1.1.10 h1:NotGKqX0KwQ72NUzqrjZq5ipPNDQex9lo3WpaS8L2sc=
|
||||
github.com/willf/bitset v1.1.10/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4=
|
||||
github.com/xanzy/go-gitlab v0.22.1 h1:TVxgHmoa35jQL+9FCkG0nwPDxU9dQZXknBTDtGaSFno=
|
||||
github.com/xanzy/go-gitlab v0.22.1/go.mod h1:t4Bmvnxj7k37S4Y17lfLx+nLqkf/oQwT2HagfWKv5Og=
|
||||
github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70=
|
||||
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
|
||||
@@ -669,6 +671,7 @@ golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73r
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181108082009-03003ca0c849/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
@@ -692,6 +695,7 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e h1:3G+cUijn7XD+S4eJFddp53Pv7
|
||||
golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/oauth2 v0.0.0-20180620175406-ef147856a6dd/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
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 h1:SVwTIAaPC2U/AvvLNZ2a7OVsmBpC8L5BlwK1whH3hm0=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -770,6 +774,7 @@ google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEn
|
||||
google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
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.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,246 @@
|
||||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/migrations/base"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestGitlabDownloadRepo(t *testing.T) {
|
||||
// Skip tests if Gitlab token is not found
|
||||
gitlabPersonalAccessToken := os.Getenv("GITLAB_READ_TOKEN")
|
||||
if gitlabPersonalAccessToken == "" {
|
||||
t.Skip("skipped test because GITLAB_READ_TOKEN was not in the environment")
|
||||
}
|
||||
|
||||
resp, err := http.Get("https://gitlab.com/gitea/test_repo")
|
||||
if err != nil || resp.StatusCode != 200 {
|
||||
t.Skipf("Can't access test repo, skipping %s", t.Name())
|
||||
}
|
||||
|
||||
downloader := NewGitlabDownloader("https://gitlab.com", "gitea/test_repo", gitlabPersonalAccessToken, "")
|
||||
if downloader == nil {
|
||||
t.Fatal("NewGitlabDownloader is nil")
|
||||
}
|
||||
repo, err := downloader.GetRepoInfo()
|
||||
assert.NoError(t, err)
|
||||
// Repo Owner is blank in Gitlab Group repos
|
||||
assert.EqualValues(t, &base.Repository{
|
||||
Name: "test_repo",
|
||||
Owner: "",
|
||||
Description: "Test repository for testing migration from gitlab to gitea",
|
||||
CloneURL: "https://gitlab.com/gitea/test_repo.git",
|
||||
OriginalURL: "https://gitlab.com/gitea/test_repo",
|
||||
}, repo)
|
||||
|
||||
topics, err := downloader.GetTopics()
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, len(topics) == 2)
|
||||
assert.EqualValues(t, []string{"migration", "test"}, topics)
|
||||
|
||||
milestones, err := downloader.GetMilestones()
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, len(milestones) >= 2)
|
||||
|
||||
for _, milestone := range milestones {
|
||||
switch milestone.Title {
|
||||
case "1.0":
|
||||
assertMilestoneEqual(t, "", "1.0",
|
||||
"",
|
||||
"2019-11-28 08:42:30.301 +0000 UTC",
|
||||
"2019-11-28 15:57:52.401 +0000 UTC",
|
||||
"",
|
||||
"closed", milestone)
|
||||
case "1.1.0":
|
||||
assertMilestoneEqual(t, "", "1.1.0",
|
||||
"",
|
||||
"2019-11-28 08:42:44.575 +0000 UTC",
|
||||
"2019-11-28 08:42:44.575 +0000 UTC",
|
||||
"",
|
||||
"active", milestone)
|
||||
}
|
||||
}
|
||||
|
||||
labels, err := downloader.GetLabels()
|
||||
assert.NoError(t, err)
|
||||
assert.True(t, len(labels) >= 9)
|
||||
for _, l := range labels {
|
||||
switch l.Name {
|
||||
case "bug":
|
||||
assertLabelEqual(t, "bug", "d9534f", "", l)
|
||||
case "documentation":
|
||||
assertLabelEqual(t, "documentation", "f0ad4e", "", l)
|
||||
case "confirmed":
|
||||
assertLabelEqual(t, "confirmed", "d9534f", "", l)
|
||||
case "enhancement":
|
||||
assertLabelEqual(t, "enhancement", "5cb85c", "", l)
|
||||
case "critical":
|
||||
assertLabelEqual(t, "critical", "d9534f", "", l)
|
||||
case "discussion":
|
||||
assertLabelEqual(t, "discussion", "428bca", "", l)
|
||||
case "suggestion":
|
||||
assertLabelEqual(t, "suggestion", "428bca", "", l)
|
||||
case "support":
|
||||
assertLabelEqual(t, "support", "f0ad4e", "", l)
|
||||
case "duplicate":
|
||||
assertLabelEqual(t, "duplicate", "7F8C8D", "", l)
|
||||
}
|
||||
}
|
||||
|
||||
releases, err := downloader.GetReleases()
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, []*base.Release{
|
||||
{
|
||||
TagName: "v0.9.99",
|
||||
TargetCommitish: "0720a3ec57c1f843568298117b874319e7deee75",
|
||||
Name: "First Release",
|
||||
Body: "A test release",
|
||||
Created: time.Date(2019, 11, 28, 9, 9, 48, 840000000, time.UTC),
|
||||
PublisherID: 1241334,
|
||||
PublisherName: "lafriks",
|
||||
},
|
||||
}, releases[len(releases)-1:])
|
||||
|
||||
// downloader.GetIssues()
|
||||
issues, isEnd, err := downloader.GetIssues(1, 2)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 2, len(issues))
|
||||
assert.False(t, isEnd)
|
||||
|
||||
var (
|
||||
closed1 = time.Date(2019, 11, 28, 8, 46, 23, 275000000, time.UTC)
|
||||
closed2 = time.Date(2019, 11, 28, 8, 45, 44, 959000000, time.UTC)
|
||||
)
|
||||
assert.EqualValues(t, []*base.Issue{
|
||||
{
|
||||
Number: 1,
|
||||
Title: "Please add an animated gif icon to the merge button",
|
||||
Content: "I just want the merge button to hurt my eyes a little. :stuck_out_tongue_closed_eyes:",
|
||||
Milestone: "1.0.0",
|
||||
PosterID: 1241334,
|
||||
PosterName: "lafriks",
|
||||
State: "closed",
|
||||
Created: time.Date(2019, 11, 28, 8, 43, 35, 459000000, time.UTC),
|
||||
Updated: time.Date(2019, 11, 28, 8, 46, 23, 275000000, time.UTC),
|
||||
Labels: []*base.Label{
|
||||
{
|
||||
Name: "bug",
|
||||
},
|
||||
{
|
||||
Name: "discussion",
|
||||
},
|
||||
},
|
||||
Reactions: nil,
|
||||
Closed: &closed1,
|
||||
},
|
||||
{
|
||||
Number: 2,
|
||||
Title: "Test issue",
|
||||
Content: "This is test issue 2, do not touch!",
|
||||
Milestone: "1.1.0",
|
||||
PosterID: 1241334,
|
||||
PosterName: "lafriks",
|
||||
State: "closed",
|
||||
Created: time.Date(2019, 11, 28, 8, 44, 46, 277000000, time.UTC),
|
||||
Updated: time.Date(2019, 11, 28, 8, 45, 44, 987000000, time.UTC),
|
||||
Labels: []*base.Label{
|
||||
{
|
||||
Name: "duplicate",
|
||||
},
|
||||
},
|
||||
Reactions: nil,
|
||||
Closed: &closed2,
|
||||
},
|
||||
}, issues)
|
||||
|
||||
// downloader.GetComments()
|
||||
comments, err := downloader.GetComments(2)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 4, len(comments))
|
||||
assert.EqualValues(t, []*base.Comment{
|
||||
{
|
||||
IssueIndex: 2,
|
||||
PosterID: 1241334,
|
||||
PosterName: "lafriks",
|
||||
Created: time.Date(2019, 11, 28, 8, 44, 52, 501000000, time.UTC),
|
||||
Updated: time.Date(2019, 11, 28, 8, 44, 52, 501000000, time.UTC),
|
||||
Content: "This is a comment",
|
||||
Reactions: nil,
|
||||
},
|
||||
{
|
||||
IssueIndex: 2,
|
||||
PosterID: 1241334,
|
||||
PosterName: "lafriks",
|
||||
Created: time.Date(2019, 11, 28, 8, 45, 2, 329000000, time.UTC),
|
||||
Content: "changed milestone to %2",
|
||||
Reactions: nil,
|
||||
},
|
||||
{
|
||||
IssueIndex: 2,
|
||||
PosterID: 1241334,
|
||||
PosterName: "lafriks",
|
||||
Created: time.Date(2019, 11, 28, 8, 45, 45, 7000000, time.UTC),
|
||||
Content: "closed",
|
||||
Reactions: nil,
|
||||
},
|
||||
{
|
||||
IssueIndex: 2,
|
||||
PosterID: 1241334,
|
||||
PosterName: "lafriks",
|
||||
Created: time.Date(2019, 11, 28, 8, 45, 53, 501000000, time.UTC),
|
||||
Content: "A second comment",
|
||||
Reactions: nil,
|
||||
},
|
||||
}, comments[:4])
|
||||
|
||||
// downloader.GetPullRequests()
|
||||
prs, err := downloader.GetPullRequests(1, 1)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, len(prs))
|
||||
|
||||
assert.EqualValues(t, []*base.PullRequest{
|
||||
{
|
||||
Number: 4,
|
||||
Title: "Test branch",
|
||||
Content: "do not merge this PR",
|
||||
Milestone: "1.0.0",
|
||||
PosterID: 1241334,
|
||||
PosterName: "lafriks",
|
||||
State: "opened",
|
||||
Created: time.Date(2019, 11, 28, 15, 56, 54, 104000000, time.UTC),
|
||||
Updated: time.Date(2019, 11, 28, 15, 56, 54, 104000000, time.UTC),
|
||||
Labels: []*base.Label{
|
||||
{
|
||||
Name: "bug",
|
||||
},
|
||||
},
|
||||
PatchURL: "https://gitlab.com/gitea/test_repo/-/merge_requests/2.patch",
|
||||
Head: base.PullRequestBranch{
|
||||
Ref: "feat/test",
|
||||
CloneURL: "https://gitlab.com/gitea/test_repo/-/merge_requests/2",
|
||||
SHA: "9f733b96b98a4175276edf6a2e1231489c3bdd23",
|
||||
RepoName: "test_repo",
|
||||
OwnerName: "lafriks",
|
||||
},
|
||||
Base: base.PullRequestBranch{
|
||||
Ref: "master",
|
||||
SHA: "",
|
||||
OwnerName: "lafriks",
|
||||
RepoName: "test_repo",
|
||||
},
|
||||
Closed: nil,
|
||||
Merged: false,
|
||||
MergedTime: nil,
|
||||
MergeCommitSHA: "",
|
||||
},
|
||||
}, prs)
|
||||
}
|
||||
@@ -203,6 +203,7 @@ var (
|
||||
// TODO: add to this list after new git service added
|
||||
SupportedFullGitService = []GitServiceType{
|
||||
GithubService,
|
||||
GitlabService,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
+28
@@ -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
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
language: go
|
||||
|
||||
go:
|
||||
- 1.10.x
|
||||
- 1.11.x
|
||||
- 1.12.x
|
||||
- 1.13.x
|
||||
- master
|
||||
|
||||
stages:
|
||||
- lint
|
||||
- test
|
||||
|
||||
jobs:
|
||||
include:
|
||||
- stage: lint
|
||||
script:
|
||||
- go get golang.org/x/lint/golint
|
||||
- golint -set_exit_status
|
||||
- go vet -v
|
||||
- stage: test
|
||||
script:
|
||||
- go test -v
|
||||
|
||||
matrix:
|
||||
allow_failures:
|
||||
- go: master
|
||||
fast_finish: true
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
go-github CHANGELOG
|
||||
===================
|
||||
|
||||
0.6.0
|
||||
-----
|
||||
- Add support for the V4 Gitlab API. This means the older V3 API is no longer fully supported
|
||||
with this version. If you still need that version, please use the `f-api-v3` branch.
|
||||
|
||||
0.4.0
|
||||
-----
|
||||
- Add support to use [`sudo`](https://docs.gitlab.com/ce/api/README.html#sudo) for all API calls.
|
||||
- Add support for the Notification Settings API.
|
||||
- Add support for the Time Tracking API.
|
||||
- Make sure that the error response correctly outputs any returned errors.
|
||||
- And a reasonable number of smaller enhanchements and bugfixes.
|
||||
|
||||
0.3.0
|
||||
-----
|
||||
- Moved the tags related API calls to their own service, following the Gitlab API structure.
|
||||
|
||||
0.2.0
|
||||
-----
|
||||
- Convert all Option structs to use pointers for their fields.
|
||||
|
||||
0.1.0
|
||||
-----
|
||||
- Initial release.
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
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.
|
||||
|
||||
+173
@@ -0,0 +1,173 @@
|
||||
# go-gitlab
|
||||
|
||||
A GitLab API client enabling Go programs to interact with GitLab in a simple and uniform way
|
||||
|
||||
[](https://travis-ci.org/xanzy/go-gitlab)
|
||||
[](https://github.com/xanzy/go-gitlab/blob/master/LICENSE)
|
||||
[](https://sourcegraph.com/github.com/xanzy/go-gitlab?badge)
|
||||
[](https://godoc.org/github.com/xanzy/go-gitlab)
|
||||
[](https://goreportcard.com/report/github.com/xanzy/go-gitlab)
|
||||
[](https://github.com/xanzy/go-gitlab/issues)
|
||||
|
||||
## 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] 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-Level Variables
|
||||
- [x] Groups
|
||||
- [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 Domains
|
||||
- [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 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 := gitlab.NewClient(nil, "yourtokengoeshere")
|
||||
//git.SetBaseURL("https://git.mydomain.com/api/v4")
|
||||
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(nil)
|
||||
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 := gitlab.NewClient(nil, "yourtokengoeshere")
|
||||
|
||||
// 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"),
|
||||
Code: 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@xanzy.io>)
|
||||
|
||||
## 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>
|
||||
+236
@@ -0,0 +1,236 @@
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"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 ...OptionFunc) ([]*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("GET", 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 ...OptionFunc) ([]*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("GET", 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 ...OptionFunc) (*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("POST", 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 ...OptionFunc) (*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("POST", 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 ...OptionFunc) (*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("PUT", 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 ...OptionFunc) (*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("PUT", 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 ...OptionFunc) (*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("DELETE", 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 ...OptionFunc) (*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("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
+467
File diff suppressed because it is too large
Load Diff
+344
File diff suppressed because it is too large
Load Diff
+242
@@ -0,0 +1,242 @@
|
||||
//
|
||||
// Copyright 2017, 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/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"`
|
||||
DevelopersCanPush bool `json:"developers_can_push"`
|
||||
DevelopersCanMerge bool `json:"developers_can_merge"`
|
||||
}
|
||||
|
||||
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 ...OptionFunc) ([]*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("GET", 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 ...OptionFunc) (*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("GET", 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 ...OptionFunc) (*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("PUT", 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 ...OptionFunc) (*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("PUT", 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 ...OptionFunc) (*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("POST", 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 ...OptionFunc) (*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("DELETE", 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 ...OptionFunc) (*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("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
//
|
||||
// Copyright 2018, 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"
|
||||
"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 ...OptionFunc) ([]*BroadcastMessage, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "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 ...OptionFunc) (*BroadcastMessage, *Response, error) {
|
||||
u := fmt.Sprintf("broadcast_messages/%d", broadcast)
|
||||
|
||||
req, err := s.client.NewRequest("GET", 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 ...OptionFunc) (*BroadcastMessage, *Response, error) {
|
||||
req, err := s.client.NewRequest("POST", "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 ...OptionFunc) (*BroadcastMessage, *Response, error) {
|
||||
u := fmt.Sprintf("broadcast_messages/%d", broadcast)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", 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 ...OptionFunc) (*Response, error) {
|
||||
u := fmt.Sprintf("broadcast_messages/%d", broadcast)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// 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 ...OptionFunc) ([]*CIYMLTemplate, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "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 ...OptionFunc) (*CIYMLTemplate, *Response, error) {
|
||||
u := fmt.Sprintf("templates/gitlab_ci_ymls/%s", pathEscape(key))
|
||||
|
||||
req, err := s.client.NewRequest("GET", 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
|
||||
}
|
||||
+593
File diff suppressed because it is too large
Load Diff
+171
@@ -0,0 +1,171 @@
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// 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 ...OptionFunc) ([]*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 ...OptionFunc) ([]*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 ...OptionFunc) ([]*CustomAttribute, *Response, error) {
|
||||
return s.listCustomAttributes("projects", project, options...)
|
||||
}
|
||||
|
||||
func (s *CustomAttributesService) listCustomAttributes(resource string, id int, options ...OptionFunc) ([]*CustomAttribute, *Response, error) {
|
||||
u := fmt.Sprintf("%s/%d/custom_attributes", resource, id)
|
||||
req, err := s.client.NewRequest("GET", 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 ...OptionFunc) (*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 ...OptionFunc) (*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 ...OptionFunc) (*CustomAttribute, *Response, error) {
|
||||
return s.getCustomAttribute("projects", project, key, options...)
|
||||
}
|
||||
|
||||
func (s *CustomAttributesService) getCustomAttribute(resource string, id int, key string, options ...OptionFunc) (*CustomAttribute, *Response, error) {
|
||||
u := fmt.Sprintf("%s/%d/custom_attributes/%s", resource, id, key)
|
||||
req, err := s.client.NewRequest("GET", 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 ...OptionFunc) (*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 ...OptionFunc) (*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 ...OptionFunc) (*CustomAttribute, *Response, error) {
|
||||
return s.setCustomAttribute("projects", project, c, options...)
|
||||
}
|
||||
|
||||
func (s *CustomAttributesService) setCustomAttribute(resource string, id int, c CustomAttribute, options ...OptionFunc) (*CustomAttribute, *Response, error) {
|
||||
u := fmt.Sprintf("%s/%d/custom_attributes/%s", resource, id, c.Key)
|
||||
req, err := s.client.NewRequest("PUT", 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 ...OptionFunc) (*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 ...OptionFunc) (*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 ...OptionFunc) (*Response, error) {
|
||||
return s.deleteCustomAttribute("projects", project, key, options...)
|
||||
}
|
||||
|
||||
func (s *CustomAttributesService) deleteCustomAttribute(resource string, id int, key string, options ...OptionFunc) (*Response, error) {
|
||||
u := fmt.Sprintf("%s/%d/custom_attributes/%s", resource, id, key)
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
//
|
||||
// Copyright 2017, 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"
|
||||
"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 ...OptionFunc) ([]*DeployKey, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "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 ...OptionFunc) ([]*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("GET", 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 ...OptionFunc) (*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("GET", 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 ...OptionFunc) (*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("POST", 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 ...OptionFunc) (*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("DELETE", 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-deploy-key
|
||||
func (s *DeployKeysService) EnableDeployKey(pid interface{}, deployKey int, options ...OptionFunc) (*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("POST", 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
|
||||
}
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
//
|
||||
// Copyright 2018, 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"
|
||||
"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"`
|
||||
CreatedAt *time.Time `json:"created_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"`
|
||||
} `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"`
|
||||
}
|
||||
|
||||
// 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 ...OptionFunc) ([]*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("GET", 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 ...OptionFunc) (*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("GET", 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
|
||||
}
|
||||
+1112
File diff suppressed because it is too large
Load Diff
+212
@@ -0,0 +1,212 @@
|
||||
//
|
||||
// Copyright 2017, 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"
|
||||
)
|
||||
|
||||
// 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 ListOptions
|
||||
|
||||
// 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 ...OptionFunc) ([]*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("GET", 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 ...OptionFunc) (*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("GET", 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 ...OptionFunc) (*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("POST", 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 ...OptionFunc) (*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("PUT", 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 ...OptionFunc) (*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("DELETE", 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 ...OptionFunc) (*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("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
+211
@@ -0,0 +1,211 @@
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"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"`
|
||||
Author *EpicAuthor `json:"author"`
|
||||
Description string `json:"description"`
|
||||
State string `json:"state"`
|
||||
Upvotes int `json:"upvotes"`
|
||||
Downvotes int `json:"downvotes"`
|
||||
Labels []string `json:"labels"`
|
||||
Title string `json:"title"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
UserNotesCount int `json:"user_notes_count"`
|
||||
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"`
|
||||
}
|
||||
|
||||
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
|
||||
State *string `url:"state,omitempty" json:"state,omitempty"`
|
||||
Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
|
||||
AuthorID *int `url:"author_id,omitempty" json:"author_id,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"`
|
||||
}
|
||||
|
||||
// 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 ...OptionFunc) ([]*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("GET", 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 ...OptionFunc) (*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("GET", 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
|
||||
}
|
||||
|
||||
// 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 ...OptionFunc) (*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("POST", 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 ...OptionFunc) (*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("PUT", 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 ...OptionFunc) (*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("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
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"
|
||||
EventTypeIssue EventType = "Issue Hook"
|
||||
EventTypeJob EventType = "Job Hook"
|
||||
EventTypeMergeRequest EventType = "Merge Request Hook"
|
||||
EventTypeNote EventType = "Note Hook"
|
||||
EventTypePipeline EventType = "Pipeline Hook"
|
||||
EventTypePush EventType = "Push 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"
|
||||
|
||||
// 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.WebhookEventType(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 EventTypeIssue:
|
||||
event = &IssueEvent{}
|
||||
case EventTypeJob:
|
||||
event = &JobEvent{}
|
||||
case EventTypeMergeRequest:
|
||||
event = &MergeEvent{}
|
||||
case EventTypePipeline:
|
||||
event = &PipelineEvent{}
|
||||
case EventTypePush:
|
||||
event = &PushEvent{}
|
||||
case EventTypeTagPush:
|
||||
event = &TagEvent{}
|
||||
case EventTypeWikiPage:
|
||||
event = &WikiPageEvent{}
|
||||
case EventTypeNote:
|
||||
note := ¬eEvent{}
|
||||
err := json.Unmarshal(payload, note)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if note.ObjectKind != "note" {
|
||||
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
|
||||
}
|
||||
+815
File diff suppressed because it is too large
Load Diff
+146
@@ -0,0 +1,146 @@
|
||||
//
|
||||
// Copyright 2017, 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"
|
||||
"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 {
|
||||
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 ...OptionFunc) ([]*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("GET", 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 ...OptionFunc) ([]*ContributionEvent, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "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 ...OptionFunc) ([]*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("GET", 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
|
||||
}
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"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 ...OptionFunc) ([]*Feature, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "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 ...OptionFunc) (*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("POST", 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
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
//
|
||||
// Copyright 2018, 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/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 ...OptionFunc) ([]*GitIgnoreTemplate, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "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#single-gitignore-template
|
||||
func (s *GitIgnoreTemplatesService) GetTemplate(key string, options ...OptionFunc) (*GitIgnoreTemplate, *Response, error) {
|
||||
u := fmt.Sprintf("templates/gitignores/%s", url.PathEscape(key))
|
||||
|
||||
req, err := s.client.NewRequest("GET", 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
|
||||
}
|
||||
+955
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user