Merge branch 'feature/gitlab_provider' of https://github.com/richardc/terraform into richardc-feature/gitlab_provider
This commit is contained in:
commit
898ac02854
|
@ -0,0 +1,12 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform/builtin/providers/gitlab"
|
||||
"github.com/hashicorp/terraform/plugin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
plugin.Serve(&plugin.ServeOpts{
|
||||
ProviderFunc: gitlab.Provider,
|
||||
})
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package gitlab
|
||||
|
||||
import (
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
// Config is per-provider, specifies where to connect to gitlab
|
||||
type Config struct {
|
||||
Token string
|
||||
BaseURL string
|
||||
}
|
||||
|
||||
// Client returns a *gitlab.Client to interact with the configured gitlab instance
|
||||
func (c *Config) Client() (interface{}, error) {
|
||||
client := gitlab.NewClient(nil, c.Token)
|
||||
if c.BaseURL != "" {
|
||||
err := client.SetBaseURL(c.BaseURL)
|
||||
if err != nil {
|
||||
// The BaseURL supplied wasn't valid, bail.
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
// Test the credentials by checking we can get information about the authenticated user.
|
||||
_, _, err := client.Users.CurrentUser()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
package gitlab
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
// Provider returns a terraform.ResourceProvider.
|
||||
func Provider() terraform.ResourceProvider {
|
||||
|
||||
// The actual provider
|
||||
return &schema.Provider{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"token": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("GITLAB_TOKEN", nil),
|
||||
Description: descriptions["token"],
|
||||
},
|
||||
"base_url": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("GITLAB_BASE_URL", ""),
|
||||
Description: descriptions["base_url"],
|
||||
},
|
||||
},
|
||||
ResourcesMap: map[string]*schema.Resource{
|
||||
"gitlab_project": resourceGitlabProject(),
|
||||
},
|
||||
|
||||
ConfigureFunc: providerConfigure,
|
||||
}
|
||||
}
|
||||
|
||||
var descriptions map[string]string
|
||||
|
||||
func init() {
|
||||
descriptions = map[string]string{
|
||||
"token": "The OAuth token used to connect to GitLab.",
|
||||
|
||||
"base_url": "The GitLab Base API URL",
|
||||
}
|
||||
}
|
||||
|
||||
func providerConfigure(d *schema.ResourceData) (interface{}, error) {
|
||||
config := Config{
|
||||
Token: d.Get("token").(string),
|
||||
BaseURL: d.Get("base_url").(string),
|
||||
}
|
||||
|
||||
return config.Client()
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package gitlab
|
||||
|
||||
import (
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
)
|
||||
|
||||
var testAccProviders map[string]terraform.ResourceProvider
|
||||
var testAccProvider *schema.Provider
|
||||
|
||||
func init() {
|
||||
testAccProvider = Provider().(*schema.Provider)
|
||||
testAccProviders = map[string]terraform.ResourceProvider{
|
||||
"gitlab": testAccProvider,
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider(t *testing.T) {
|
||||
if err := Provider().(*schema.Provider).InternalValidate(); err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvider_impl(t *testing.T) {
|
||||
var _ terraform.ResourceProvider = Provider()
|
||||
}
|
||||
|
||||
func testAccPreCheck(t *testing.T) {
|
||||
if v := os.Getenv("GITLAB_TOKEN"); v == "" {
|
||||
t.Fatal("GITLAB_TOKEN must be set for acceptance tests")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,207 @@
|
|||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
gitlab "github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
func resourceGitlabProject() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceGitlabProjectCreate,
|
||||
Read: resourceGitlabProjectRead,
|
||||
Update: resourceGitlabProjectUpdate,
|
||||
Delete: resourceGitlabProjectDelete,
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
},
|
||||
"description": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"default_branch": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"issues_enabled": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: true,
|
||||
},
|
||||
"merge_requests_enabled": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: true,
|
||||
},
|
||||
"wiki_enabled": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: true,
|
||||
},
|
||||
"snippets_enabled": &schema.Schema{
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: true,
|
||||
},
|
||||
"visibility_level": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
ValidateFunc: validateValueFunc([]string{"private", "internal", "public"}),
|
||||
Default: "private",
|
||||
},
|
||||
|
||||
"ssh_url_to_repo": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"http_url_to_repo": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"web_url": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceGitlabProjectUpdateFromAPI(d *schema.ResourceData, project *gitlab.Project) {
|
||||
d.Set("name", project.Name)
|
||||
d.Set("description", project.Description)
|
||||
d.Set("default_branch", project.DefaultBranch)
|
||||
d.Set("issues_enabled", project.IssuesEnabled)
|
||||
d.Set("merge_requests_enabled", project.MergeRequestsEnabled)
|
||||
d.Set("wiki_enabled", project.WikiEnabled)
|
||||
d.Set("snippets_enabled", project.SnippetsEnabled)
|
||||
d.Set("visibility_level", visibilityLevelToString(project.VisibilityLevel))
|
||||
|
||||
d.Set("ssh_url_to_repo", project.SSHURLToRepo)
|
||||
d.Set("http_url_to_repo", project.HTTPURLToRepo)
|
||||
d.Set("web_url", project.WebURL)
|
||||
}
|
||||
|
||||
func resourceGitlabProjectCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*gitlab.Client)
|
||||
options := &gitlab.CreateProjectOptions{
|
||||
Name: gitlab.String(d.Get("name").(string)),
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("description"); ok {
|
||||
options.Description = gitlab.String(v.(string))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("issues_enabled"); ok {
|
||||
options.IssuesEnabled = gitlab.Bool(v.(bool))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("merge_requests_enabled"); ok {
|
||||
options.MergeRequestsEnabled = gitlab.Bool(v.(bool))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("wiki_enabled"); ok {
|
||||
options.WikiEnabled = gitlab.Bool(v.(bool))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("snippets_enabled"); ok {
|
||||
options.SnippetsEnabled = gitlab.Bool(v.(bool))
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("visibility_level"); ok {
|
||||
options.VisibilityLevel = stringToVisibilityLevel(v.(string))
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] create gitlab project %q", options.Name)
|
||||
|
||||
project, _, err := client.Projects.CreateProject(options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(fmt.Sprintf("%d", project.ID))
|
||||
|
||||
resourceGitlabProjectUpdateFromAPI(d, project)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceGitlabProjectRead(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*gitlab.Client)
|
||||
log.Printf("[DEBUG] read gitlab project %s", d.Id())
|
||||
|
||||
project, response, err := client.Projects.GetProject(d.Id())
|
||||
if err != nil {
|
||||
if response.StatusCode == 404 {
|
||||
log.Printf("[WARN] removing project %s from state because it no longer exists in gitlab", d.Id())
|
||||
d.SetId("")
|
||||
return nil
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
resourceGitlabProjectUpdateFromAPI(d, project)
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceGitlabProjectUpdate(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*gitlab.Client)
|
||||
|
||||
options := &gitlab.EditProjectOptions{}
|
||||
|
||||
if d.HasChange("name") {
|
||||
options.Name = gitlab.String(d.Get("name").(string))
|
||||
}
|
||||
|
||||
if d.HasChange("description") {
|
||||
options.Description = gitlab.String(d.Get("description").(string))
|
||||
}
|
||||
|
||||
if d.HasChange("default_branch") {
|
||||
options.DefaultBranch = gitlab.String(d.Get("description").(string))
|
||||
}
|
||||
|
||||
if d.HasChange("visibility_level") {
|
||||
options.VisibilityLevel = stringToVisibilityLevel(d.Get("visibility_level").(string))
|
||||
}
|
||||
|
||||
if d.HasChange("issues_enabled") {
|
||||
options.IssuesEnabled = gitlab.Bool(d.Get("issues_enabled").(bool))
|
||||
}
|
||||
|
||||
if d.HasChange("merge_requests_enabled") {
|
||||
options.MergeRequestsEnabled = gitlab.Bool(d.Get("merge_requests_enabled").(bool))
|
||||
}
|
||||
|
||||
if d.HasChange("wiki_enabled") {
|
||||
options.WikiEnabled = gitlab.Bool(d.Get("wiki_enabled").(bool))
|
||||
}
|
||||
|
||||
if d.HasChange("snippets_enabled") {
|
||||
options.SnippetsEnabled = gitlab.Bool(d.Get("snippets_enabled").(bool))
|
||||
}
|
||||
|
||||
log.Printf("[DEBUG] update gitlab project %s", d.Id())
|
||||
|
||||
project, _, err := client.Projects.EditProject(d.Id(), options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resourceGitlabProjectUpdateFromAPI(d, project)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceGitlabProjectDelete(d *schema.ResourceData, meta interface{}) error {
|
||||
client := meta.(*gitlab.Client)
|
||||
log.Printf("[DEBUG] update gitlab project %s", d.Id())
|
||||
|
||||
_, err := client.Projects.DeleteProject(d.Id())
|
||||
return err
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/resource"
|
||||
"github.com/hashicorp/terraform/terraform"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
func TestAccGitlabProject_basic(t *testing.T) {
|
||||
var project gitlab.Project
|
||||
|
||||
resource.Test(t, resource.TestCase{
|
||||
PreCheck: func() { testAccPreCheck(t) },
|
||||
Providers: testAccProviders,
|
||||
CheckDestroy: testAccCheckGitlabProjectDestroy,
|
||||
Steps: []resource.TestStep{
|
||||
// Create a project with all the features on
|
||||
resource.TestStep{
|
||||
Config: testAccGitlabProjectConfig,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGitlabProjectExists("gitlab_project.foo", &project),
|
||||
testAccCheckGitlabProjectAttributes(&project, &testAccGitlabProjectExpectedAttributes{
|
||||
Name: "foo",
|
||||
Description: "Terraform acceptance tests",
|
||||
IssuesEnabled: true,
|
||||
MergeRequestsEnabled: true,
|
||||
WikiEnabled: true,
|
||||
SnippetsEnabled: true,
|
||||
VisibilityLevel: 20,
|
||||
}),
|
||||
),
|
||||
},
|
||||
// Update the project to turn the features off
|
||||
resource.TestStep{
|
||||
Config: testAccGitlabProjectUpdateConfig,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGitlabProjectExists("gitlab_project.foo", &project),
|
||||
testAccCheckGitlabProjectAttributes(&project, &testAccGitlabProjectExpectedAttributes{
|
||||
Name: "foo",
|
||||
Description: "Terraform acceptance tests!",
|
||||
VisibilityLevel: 20,
|
||||
}),
|
||||
),
|
||||
},
|
||||
// Update the project to turn the features on again
|
||||
resource.TestStep{
|
||||
Config: testAccGitlabProjectConfig,
|
||||
Check: resource.ComposeTestCheckFunc(
|
||||
testAccCheckGitlabProjectExists("gitlab_project.foo", &project),
|
||||
testAccCheckGitlabProjectAttributes(&project, &testAccGitlabProjectExpectedAttributes{
|
||||
Name: "foo",
|
||||
Description: "Terraform acceptance tests",
|
||||
IssuesEnabled: true,
|
||||
MergeRequestsEnabled: true,
|
||||
WikiEnabled: true,
|
||||
SnippetsEnabled: true,
|
||||
VisibilityLevel: 20,
|
||||
}),
|
||||
),
|
||||
},
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func testAccCheckGitlabProjectExists(n string, project *gitlab.Project) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
rs, ok := s.RootModule().Resources[n]
|
||||
if !ok {
|
||||
return fmt.Errorf("Not Found: %s", n)
|
||||
}
|
||||
|
||||
repoName := rs.Primary.ID
|
||||
if repoName == "" {
|
||||
return fmt.Errorf("No project ID is set")
|
||||
}
|
||||
conn := testAccProvider.Meta().(*gitlab.Client)
|
||||
|
||||
gotProject, _, err := conn.Projects.GetProject(repoName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*project = *gotProject
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
type testAccGitlabProjectExpectedAttributes struct {
|
||||
Name string
|
||||
Description string
|
||||
DefaultBranch string
|
||||
IssuesEnabled bool
|
||||
MergeRequestsEnabled bool
|
||||
WikiEnabled bool
|
||||
SnippetsEnabled bool
|
||||
VisibilityLevel gitlab.VisibilityLevelValue
|
||||
}
|
||||
|
||||
func testAccCheckGitlabProjectAttributes(project *gitlab.Project, want *testAccGitlabProjectExpectedAttributes) resource.TestCheckFunc {
|
||||
return func(s *terraform.State) error {
|
||||
if project.Name != want.Name {
|
||||
return fmt.Errorf("got repo %q; want %q", project.Name, want.Name)
|
||||
}
|
||||
if project.Description != want.Description {
|
||||
return fmt.Errorf("got description %q; want %q", project.Description, want.Description)
|
||||
}
|
||||
|
||||
if project.DefaultBranch != want.DefaultBranch {
|
||||
return fmt.Errorf("got default_branch %q; want %q", project.DefaultBranch, want.DefaultBranch)
|
||||
}
|
||||
|
||||
if project.IssuesEnabled != want.IssuesEnabled {
|
||||
return fmt.Errorf("got issues_enabled %t; want %t", project.IssuesEnabled, want.IssuesEnabled)
|
||||
}
|
||||
|
||||
if project.MergeRequestsEnabled != want.MergeRequestsEnabled {
|
||||
return fmt.Errorf("got merge_requests_enabled %t; want %t", project.MergeRequestsEnabled, want.MergeRequestsEnabled)
|
||||
}
|
||||
|
||||
if project.WikiEnabled != want.WikiEnabled {
|
||||
return fmt.Errorf("got wiki_enabled %t; want %t", project.WikiEnabled, want.WikiEnabled)
|
||||
}
|
||||
|
||||
if project.SnippetsEnabled != want.SnippetsEnabled {
|
||||
return fmt.Errorf("got snippets_enabled %t; want %t", project.SnippetsEnabled, want.SnippetsEnabled)
|
||||
}
|
||||
|
||||
if project.VisibilityLevel != want.VisibilityLevel {
|
||||
return fmt.Errorf("got default branch %q; want %q", project.VisibilityLevel, want.VisibilityLevel)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func testAccCheckGitlabProjectDestroy(s *terraform.State) error {
|
||||
conn := testAccProvider.Meta().(*gitlab.Client)
|
||||
|
||||
for _, rs := range s.RootModule().Resources {
|
||||
if rs.Type != "gitlab_project" {
|
||||
continue
|
||||
}
|
||||
|
||||
gotRepo, resp, err := conn.Projects.GetProject(rs.Primary.ID)
|
||||
if err == nil {
|
||||
if gotRepo != nil && fmt.Sprintf("%d", gotRepo.ID) == rs.Primary.ID {
|
||||
return fmt.Errorf("Repository still exists")
|
||||
}
|
||||
}
|
||||
if resp.StatusCode != 404 {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
const testAccGitlabProjectConfig = `
|
||||
resource "gitlab_project" "foo" {
|
||||
name = "foo"
|
||||
description = "Terraform acceptance tests"
|
||||
|
||||
# So that acceptance tests can be run in a gitlab organization
|
||||
# with no billing
|
||||
visibility_level = "public"
|
||||
}
|
||||
`
|
||||
|
||||
const testAccGitlabProjectUpdateConfig = `
|
||||
resource "gitlab_project" "foo" {
|
||||
name = "foo"
|
||||
description = "Terraform acceptance tests!"
|
||||
|
||||
# So that acceptance tests can be run in a gitlab organization
|
||||
# with no billing
|
||||
visibility_level = "public"
|
||||
|
||||
issues_enabled = false
|
||||
merge_requests_enabled = false
|
||||
wiki_enabled = false
|
||||
snippets_enabled = false
|
||||
}
|
||||
`
|
|
@ -0,0 +1,54 @@
|
|||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform/helper/schema"
|
||||
gitlab "github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
// copied from ../github/util.go
|
||||
func validateValueFunc(values []string) schema.SchemaValidateFunc {
|
||||
return func(v interface{}, k string) (we []string, errors []error) {
|
||||
value := v.(string)
|
||||
valid := false
|
||||
for _, role := range values {
|
||||
if value == role {
|
||||
valid = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !valid {
|
||||
errors = append(errors, fmt.Errorf("%s is an invalid value for argument %s", value, k))
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func stringToVisibilityLevel(s string) *gitlab.VisibilityLevelValue {
|
||||
lookup := map[string]gitlab.VisibilityLevelValue{
|
||||
"private": gitlab.PrivateVisibility,
|
||||
"internal": gitlab.InternalVisibility,
|
||||
"public": gitlab.PublicVisibility,
|
||||
}
|
||||
|
||||
value, ok := lookup[s]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return &value
|
||||
}
|
||||
|
||||
func visibilityLevelToString(v gitlab.VisibilityLevelValue) *string {
|
||||
lookup := map[gitlab.VisibilityLevelValue]string{
|
||||
gitlab.PrivateVisibility: "private",
|
||||
gitlab.InternalVisibility: "internal",
|
||||
gitlab.PublicVisibility: "public",
|
||||
}
|
||||
value, ok := lookup[v]
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return &value
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
package gitlab
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
func TestGitlab_validation(t *testing.T) {
|
||||
cases := []struct {
|
||||
Value string
|
||||
ErrCount int
|
||||
}{
|
||||
{
|
||||
Value: "invalid",
|
||||
ErrCount: 1,
|
||||
},
|
||||
{
|
||||
Value: "valid_one",
|
||||
ErrCount: 0,
|
||||
},
|
||||
{
|
||||
Value: "valid_two",
|
||||
ErrCount: 0,
|
||||
},
|
||||
}
|
||||
|
||||
validationFunc := validateValueFunc([]string{"valid_one", "valid_two"})
|
||||
|
||||
for _, tc := range cases {
|
||||
_, errors := validationFunc(tc.Value, "test_arg")
|
||||
|
||||
if len(errors) != tc.ErrCount {
|
||||
t.Fatalf("Expected 1 validation error")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGitlab_visbilityHelpers(t *testing.T) {
|
||||
cases := []struct {
|
||||
String string
|
||||
Level gitlab.VisibilityLevelValue
|
||||
}{
|
||||
{
|
||||
String: "private",
|
||||
Level: gitlab.PrivateVisibility,
|
||||
},
|
||||
{
|
||||
String: "public",
|
||||
Level: gitlab.PublicVisibility,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
level := stringToVisibilityLevel(tc.String)
|
||||
if level == nil || *level != tc.Level {
|
||||
t.Fatalf("got %v expected %v", level, tc.Level)
|
||||
}
|
||||
|
||||
sv := visibilityLevelToString(tc.Level)
|
||||
if sv == nil || *sv != tc.String {
|
||||
t.Fatalf("got %v expected %v", sv, tc.String)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -31,6 +31,7 @@ import (
|
|||
externalprovider "github.com/hashicorp/terraform/builtin/providers/external"
|
||||
fastlyprovider "github.com/hashicorp/terraform/builtin/providers/fastly"
|
||||
githubprovider "github.com/hashicorp/terraform/builtin/providers/github"
|
||||
gitlabprovider "github.com/hashicorp/terraform/builtin/providers/gitlab"
|
||||
googleprovider "github.com/hashicorp/terraform/builtin/providers/google"
|
||||
grafanaprovider "github.com/hashicorp/terraform/builtin/providers/grafana"
|
||||
herokuprovider "github.com/hashicorp/terraform/builtin/providers/heroku"
|
||||
|
@ -110,6 +111,7 @@ var InternalProviders = map[string]plugin.ProviderFunc{
|
|||
"external": externalprovider.Provider,
|
||||
"fastly": fastlyprovider.Provider,
|
||||
"github": githubprovider.Provider,
|
||||
"gitlab": gitlabprovider.Provider,
|
||||
"google": googleprovider.Provider,
|
||||
"grafana": grafanaprovider.Provider,
|
||||
"heroku": herokuprovider.Provider,
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
go-github CHANGELOG
|
||||
===================
|
||||
|
||||
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.
|
|
@ -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.
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
# go-gitlab
|
||||
|
||||
A GitLab API client enabling Go programs to interact with GitLab in a simple and uniform way
|
||||
|
||||
**Documentation:** [![GoDoc](https://godoc.org/github.com/xanzy/go-gitlab?status.svg)](https://godoc.org/github.com/xanzy/go-gitlab)
|
||||
**Build Status:** [![Build Status](https://travis-ci.org/xanzy/go-gitlab.svg?branch=master)](https://travis-ci.org/xanzy/go-gitlab)
|
||||
|
||||
## NOTE
|
||||
|
||||
Release v0.5.0 (released on 22-03-2017) no longer supports Go versions older
|
||||
then 1.7.x If you want (or need) to use an older Go version please use v0.4.1
|
||||
|
||||
## Coverage
|
||||
|
||||
This API client package covers **100%** of the existing GitLab API calls! So this
|
||||
includes all calls to the following services:
|
||||
|
||||
- [x] Users
|
||||
- [x] Session
|
||||
- [x] Projects (including setting Webhooks)
|
||||
- [x] Project Snippets
|
||||
- [x] Services
|
||||
- [x] Repositories
|
||||
- [x] Repository Files
|
||||
- [x] Commits
|
||||
- [x] Branches
|
||||
- [x] Merge Requests
|
||||
- [x] Issues
|
||||
- [x] Labels
|
||||
- [x] Milestones
|
||||
- [x] Notes (comments)
|
||||
- [x] Deploy Keys
|
||||
- [x] System Hooks
|
||||
- [x] Groups
|
||||
- [x] Namespaces
|
||||
- [x] Settings
|
||||
- [x] Pipelines
|
||||
|
||||
## 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/v3")
|
||||
users, _, err := git.Users.ListUsers()
|
||||
```
|
||||
|
||||
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),
|
||||
VisibilityLevel: gitlab.VisibilityLevel(gitlab.PublicVisibility),
|
||||
}
|
||||
project, _, err := git.Projects.CreateProject(p)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Add a new snippet
|
||||
s := &gitlab.CreateSnippetOptions{
|
||||
Title: gitlab.String("Dummy Snippet"),
|
||||
FileName: gitlab.String("snippet.go"),
|
||||
Code: gitlab.String("package main...."),
|
||||
VisibilityLevel: gitlab.VisibilityLevel(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>
|
|
@ -0,0 +1,201 @@
|
|||
//
|
||||
// Copyright 2015, 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"`
|
||||
}
|
||||
|
||||
func (b Branch) String() string {
|
||||
return Stringify(b)
|
||||
}
|
||||
|
||||
// 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{}, options ...OptionFunc) ([]*Branch, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/branches", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, 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", url.QueryEscape(project), 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
|
||||
}
|
||||
|
||||
// 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, 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", url.QueryEscape(project), 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
|
||||
}
|
||||
|
||||
// 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", url.QueryEscape(project), 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 {
|
||||
BranchName *string `url:"branch_name,omitempty" json:"branch_name,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", url.QueryEscape(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", url.QueryEscape(project), branch)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
|
@ -0,0 +1,146 @@
|
|||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// BuildVariablesService handles communication with the project variables related methods
|
||||
// of the Gitlab API
|
||||
//
|
||||
// Gitlab API Docs : https://docs.gitlab.com/ce/api/build_variables.html
|
||||
type BuildVariablesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// BuildVariable represents a variable available for each build of the given project
|
||||
//
|
||||
// Gitlab API Docs : https://docs.gitlab.com/ce/api/build_variables.html
|
||||
type BuildVariable struct {
|
||||
Key string `json:"key"`
|
||||
Value string `json:"value"`
|
||||
}
|
||||
|
||||
func (v BuildVariable) String() string {
|
||||
return Stringify(v)
|
||||
}
|
||||
|
||||
// ListBuildVariables gets the a list of project variables in a project
|
||||
//
|
||||
// Gitlab API Docs:
|
||||
// https://docs.gitlab.com/ce/api/build_variables.html#list-project-variables
|
||||
func (s *BuildVariablesService) ListBuildVariables(pid interface{}, options ...OptionFunc) ([]*BuildVariable, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/variables", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var v []*BuildVariable
|
||||
resp, err := s.client.Do(req, &v)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return v, resp, err
|
||||
}
|
||||
|
||||
// GetBuildVariable gets a single project variable of a project
|
||||
//
|
||||
// Gitlab API Docs:
|
||||
// https://docs.gitlab.com/ce/api/build_variables.html#show-variable-details
|
||||
func (s *BuildVariablesService) GetBuildVariable(pid interface{}, key string, options ...OptionFunc) (*BuildVariable, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/variables/%s", url.QueryEscape(project), key)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
v := new(BuildVariable)
|
||||
resp, err := s.client.Do(req, v)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return v, resp, err
|
||||
}
|
||||
|
||||
// CreateBuildVariable creates a variable for a given project
|
||||
//
|
||||
// Gitlab API Docs:
|
||||
// https://docs.gitlab.com/ce/api/build_variables.html#create-variable
|
||||
func (s *BuildVariablesService) CreateBuildVariable(pid interface{}, key, value string, options ...OptionFunc) (*BuildVariable, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/variables", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, BuildVariable{key, value}, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
v := new(BuildVariable)
|
||||
resp, err := s.client.Do(req, v)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return v, resp, err
|
||||
}
|
||||
|
||||
// UpdateBuildVariable updates an existing project variable
|
||||
// The variable key must exist
|
||||
//
|
||||
// Gitlab API Docs:
|
||||
// https://docs.gitlab.com/ce/api/build_variables.html#update-variable
|
||||
func (s *BuildVariablesService) UpdateBuildVariable(pid interface{}, key, value string, options ...OptionFunc) (*BuildVariable, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/variables/%s", url.QueryEscape(project), key)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, BuildVariable{key, value}, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
v := new(BuildVariable)
|
||||
resp, err := s.client.Do(req, v)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return v, resp, err
|
||||
}
|
||||
|
||||
// RemoveBuildVariable removes a project variable of a given project identified by its key
|
||||
//
|
||||
// Gitlab API Docs:
|
||||
// https://docs.gitlab.com/ce/api/build_variables.html#remove-variable
|
||||
func (s *BuildVariablesService) RemoveBuildVariable(pid interface{}, key string, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/variables/%s", url.QueryEscape(project), key)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
|
@ -0,0 +1,349 @@
|
|||
//
|
||||
// Copyright 2016, Arkbriar
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ListBuildsOptions are options for two list apis
|
||||
type ListBuildsOptions struct {
|
||||
ListOptions
|
||||
Scope []BuildState `url:"scope,omitempty" json:"scope,omitempty"`
|
||||
}
|
||||
|
||||
// BuildsService handles communication with the ci builds related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/builds.html
|
||||
type BuildsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Build represents a ci build.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/builds.html
|
||||
type Build struct {
|
||||
Commit *Commit `json:"commit"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
ArtifactsFile struct {
|
||||
Filename string `json:"filename"`
|
||||
Size int `json:"size"`
|
||||
} `json:"artifacts_file"`
|
||||
FinishedAt *time.Time `json:"finished_at"`
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Ref string `json:"ref"`
|
||||
Runner struct {
|
||||
ID int `json:"id"`
|
||||
Description string `json:"description"`
|
||||
Active bool `json:"active"`
|
||||
IsShared bool `json:"is_shared"`
|
||||
Name string `json:"name"`
|
||||
} `json:"runner"`
|
||||
Stage string `json:"stage"`
|
||||
StartedAt *time.Time `json:"started_at"`
|
||||
Status string `json:"status"`
|
||||
Tag bool `json:"tag"`
|
||||
User *User `json:"user"`
|
||||
}
|
||||
|
||||
// ListProjectBuilds gets a list of builds in a project.
|
||||
//
|
||||
// The scope of builds to show, one or array of: pending, running,
|
||||
// failed, success, canceled; showing all builds if none provided.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/builds.html#list-project-builds
|
||||
func (s *BuildsService) ListProjectBuilds(pid interface{}, opts *ListBuildsOptions, options ...OptionFunc) ([]Build, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/builds", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opts, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var builds []Build
|
||||
resp, err := s.client.Do(req, &builds)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return builds, resp, err
|
||||
}
|
||||
|
||||
// ListCommitBuilds gets a list of builds for specific commit in a
|
||||
// project. If the commit SHA is not found, it will respond with 404.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/builds.html#list-commit-builds
|
||||
func (s *BuildsService) ListCommitBuilds(pid interface{}, sha string, opts *ListBuildsOptions, options ...OptionFunc) ([]Build, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/builds", project, sha)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opts, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var builds []Build
|
||||
resp, err := s.client.Do(req, &builds)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return builds, resp, err
|
||||
}
|
||||
|
||||
// GetBuild gets a single build of a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/builds.html#get-a-single-build
|
||||
func (s *BuildsService) GetBuild(pid interface{}, buildID int, options ...OptionFunc) (*Build, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/builds/%d", project, buildID)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
build := new(Build)
|
||||
resp, err := s.client.Do(req, build)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return build, resp, err
|
||||
}
|
||||
|
||||
// GetBuildArtifacts get builds artifacts of a project
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/builds.html#get-build-artifacts
|
||||
func (s *BuildsService) GetBuildArtifacts(pid interface{}, buildID int, options ...OptionFunc) (io.Reader, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/builds/%d/artifacts", project, buildID)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
artifactsBuf := new(bytes.Buffer)
|
||||
resp, err := s.client.Do(req, artifactsBuf)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return artifactsBuf, resp, err
|
||||
}
|
||||
|
||||
// DownloadArtifactsFile download the artifacts file from the given
|
||||
// reference name and job provided the build finished successfully.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/builds.html#download-the-artifacts-file
|
||||
func (s *BuildsService) DownloadArtifactsFile(pid interface{}, refName string, job string, options ...OptionFunc) (io.Reader, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/builds/artifacts/%s/download?job=%s", project, refName, job)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
artifactsBuf := new(bytes.Buffer)
|
||||
resp, err := s.client.Do(req, artifactsBuf)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return artifactsBuf, resp, err
|
||||
}
|
||||
|
||||
// GetTraceFile gets a trace of a specific build of a project
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/builds.html#get-a-trace-file
|
||||
func (s *BuildsService) GetTraceFile(pid interface{}, buildID int, options ...OptionFunc) (io.Reader, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/builds/%d/trace", project, buildID)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
traceBuf := new(bytes.Buffer)
|
||||
resp, err := s.client.Do(req, traceBuf)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return traceBuf, resp, err
|
||||
}
|
||||
|
||||
// CancelBuild cancels a single build of a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/builds.html#cancel-a-build
|
||||
func (s *BuildsService) CancelBuild(pid interface{}, buildID int, options ...OptionFunc) (*Build, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/builds/%d/cancel", project, buildID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
build := new(Build)
|
||||
resp, err := s.client.Do(req, build)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return build, resp, err
|
||||
}
|
||||
|
||||
// RetryBuild retries a single build of a project
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/builds.html#retry-a-build
|
||||
func (s *BuildsService) RetryBuild(pid interface{}, buildID int, options ...OptionFunc) (*Build, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/builds/%d/retry", project, buildID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
build := new(Build)
|
||||
resp, err := s.client.Do(req, build)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return build, resp, err
|
||||
}
|
||||
|
||||
// EraseBuild erases a single build of a project, removes a build
|
||||
// artifacts and a build trace.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/builds.html#erase-a-build
|
||||
func (s *BuildsService) EraseBuild(pid interface{}, buildID int, options ...OptionFunc) (*Build, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/builds/%d/erase", project, buildID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
build := new(Build)
|
||||
resp, err := s.client.Do(req, build)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return build, resp, err
|
||||
}
|
||||
|
||||
// KeepArtifacts prevents artifacts from being deleted when
|
||||
// expiration is set.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/builds.html#keep-artifacts
|
||||
func (s *BuildsService) KeepArtifacts(pid interface{}, buildID int, options ...OptionFunc) (*Build, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/builds/%d/artifacts/keep", project, buildID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
build := new(Build)
|
||||
resp, err := s.client.Do(req, build)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return build, resp, err
|
||||
}
|
||||
|
||||
// PlayBuild triggers a nanual action to start a build.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/builds.html#play-a-build
|
||||
func (s *BuildsService) PlayBuild(pid interface{}, buildID int, options ...OptionFunc) (*Build, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/builds/%d/play", project, buildID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
build := new(Build)
|
||||
resp, err := s.client.Do(req, build)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return build, resp, err
|
||||
}
|
|
@ -0,0 +1,444 @@
|
|||
//
|
||||
// Copyright 2015, 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"
|
||||
"time"
|
||||
)
|
||||
|
||||
// CommitsService handles communication with the commit related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html
|
||||
type CommitsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Commit represents a GitLab commit.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html
|
||||
type Commit struct {
|
||||
ID string `json:"id"`
|
||||
ShortID string `json:"short_id"`
|
||||
Title string `json:"title"`
|
||||
AuthorName string `json:"author_name"`
|
||||
AuthorEmail string `json:"author_email"`
|
||||
AuthoredDate *time.Time `json:"authored_date"`
|
||||
CommitterName string `json:"committer_name"`
|
||||
CommitterEmail string `json:"committer_email"`
|
||||
CommittedDate *time.Time `json:"committed_date"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
Message string `json:"message"`
|
||||
ParentIDs []string `json:"parent_ids"`
|
||||
Stats *CommitStats `json:"stats"`
|
||||
Status *BuildState `json:"status"`
|
||||
}
|
||||
|
||||
// CommitStats represents the number of added and deleted files in a commit.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html
|
||||
type CommitStats struct {
|
||||
Additions int `json:"additions"`
|
||||
Deletions int `json:"deletions"`
|
||||
Total int `json:"total"`
|
||||
}
|
||||
|
||||
func (c Commit) String() string {
|
||||
return Stringify(c)
|
||||
}
|
||||
|
||||
// ListCommitsOptions represents the available ListCommits() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#list-repository-commits
|
||||
type ListCommitsOptions struct {
|
||||
ListOptions
|
||||
RefName *string `url:"ref_name,omitempty" json:"ref_name,omitempty"`
|
||||
Since time.Time `url:"since,omitempty" json:"since,omitempty"`
|
||||
Until time.Time `url:"until,omitempty" json:"until,omitempty"`
|
||||
}
|
||||
|
||||
// ListCommits gets a list of repository commits in a project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#list-commits
|
||||
func (s *CommitsService) ListCommits(pid interface{}, opt *ListCommitsOptions, options ...OptionFunc) ([]*Commit, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var c []*Commit
|
||||
resp, err := s.client.Do(req, &c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// FileAction represents the available actions that can be performed on a file.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions
|
||||
type FileAction string
|
||||
|
||||
// The available file actions.
|
||||
const (
|
||||
FileCreate FileAction = "create"
|
||||
FileDelete FileAction = "delete"
|
||||
FileMove FileAction = "move"
|
||||
FileUpdate FileAction = "update"
|
||||
)
|
||||
|
||||
// CommitAction represents a single file action within a commit.
|
||||
type CommitAction struct {
|
||||
Action FileAction `url:"action" json:"action,omitempty"`
|
||||
FilePath string `url:"file_path" json:"file_path,omitempty"`
|
||||
PreviousPath string `url:"previous_path,omitempty" json:"previous_path,omitempty"`
|
||||
Content string `url:"content,omitempty" json:"content,omitempty"`
|
||||
Encoding string `url:"encoding,omitempty" json:"encoding,omitempty"`
|
||||
}
|
||||
|
||||
// CreateCommitOptions represents the available options for a new commit.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions
|
||||
type CreateCommitOptions struct {
|
||||
BranchName *string `url:"branch_name" json:"branch_name,omitempty"`
|
||||
CommitMessage *string `url:"commit_message" json:"commit_message,omitempty"`
|
||||
Actions []*CommitAction `url:"actions" json:"actions,omitempty"`
|
||||
AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"`
|
||||
AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"`
|
||||
}
|
||||
|
||||
// CreateCommit creates a commit with multiple files and actions.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#create-a-commit-with-multiple-files-and-actions
|
||||
func (s *CommitsService) CreateCommit(pid interface{}, opt *CreateCommitOptions, options ...OptionFunc) (*Commit, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var c *Commit
|
||||
resp, err := s.client.Do(req, &c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// GetCommit gets a specific commit identified by the commit hash or name of a
|
||||
// branch or tag.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-a-single-commit
|
||||
func (s *CommitsService) GetCommit(pid interface{}, sha string, options ...OptionFunc) (*Commit, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s", url.QueryEscape(project), sha)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
c := new(Commit)
|
||||
resp, err := s.client.Do(req, c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// Diff represents a GitLab diff.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html
|
||||
type Diff struct {
|
||||
Diff string `json:"diff"`
|
||||
NewPath string `json:"new_path"`
|
||||
OldPath string `json:"old_path"`
|
||||
AMode string `json:"a_mode"`
|
||||
BMode string `json:"b_mode"`
|
||||
NewFile bool `json:"new_file"`
|
||||
RenamedFile bool `json:"renamed_file"`
|
||||
DeletedFile bool `json:"deleted_file"`
|
||||
}
|
||||
|
||||
func (d Diff) String() string {
|
||||
return Stringify(d)
|
||||
}
|
||||
|
||||
// GetCommitDiff gets the diff of a commit in a project..
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#get-the-diff-of-a-commit
|
||||
func (s *CommitsService) GetCommitDiff(pid interface{}, sha string, options ...OptionFunc) ([]*Diff, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/diff", url.QueryEscape(project), sha)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var d []*Diff
|
||||
resp, err := s.client.Do(req, &d)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return d, resp, err
|
||||
}
|
||||
|
||||
// CommitComment represents a GitLab commit comment.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html
|
||||
type CommitComment struct {
|
||||
Note string `json:"note"`
|
||||
Path string `json:"path"`
|
||||
Line int `json:"line"`
|
||||
LineType string `json:"line_type"`
|
||||
Author Author `json:"author"`
|
||||
}
|
||||
|
||||
// Author represents a GitLab commit author
|
||||
type Author struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
Blocked bool `json:"blocked"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func (c CommitComment) String() string {
|
||||
return Stringify(c)
|
||||
}
|
||||
|
||||
// GetCommitComments gets the comments of a commit in a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#get-the-comments-of-a-commit
|
||||
func (s *CommitsService) GetCommitComments(pid interface{}, sha string, options ...OptionFunc) ([]*CommitComment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/comments", url.QueryEscape(project), sha)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var c []*CommitComment
|
||||
resp, err := s.client.Do(req, &c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// PostCommitCommentOptions represents the available PostCommitComment()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#post-comment-to-commit
|
||||
type PostCommitCommentOptions struct {
|
||||
Note *string `url:"note,omitempty" json:"note,omitempty"`
|
||||
Path *string `url:"path" json:"path"`
|
||||
Line *int `url:"line" json:"line"`
|
||||
LineType *string `url:"line_type" json:"line_type"`
|
||||
}
|
||||
|
||||
// PostCommitComment adds a comment to a commit. Optionally you can post
|
||||
// comments on a specific line of a commit. Therefor both path, line_new and
|
||||
// line_old are required.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/commits.html#post-comment-to-commit
|
||||
func (s *CommitsService) PostCommitComment(pid interface{}, sha string, opt *PostCommitCommentOptions, options ...OptionFunc) (*CommitComment, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/comments", url.QueryEscape(project), sha)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
c := new(CommitComment)
|
||||
resp, err := s.client.Do(req, c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// GetCommitStatusesOptions represents the available GetCommitStatuses() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-the-status-of-a-commit
|
||||
type GetCommitStatusesOptions struct {
|
||||
Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
|
||||
Stage *string `url:"stage,omitempty" json:"stage,omitempty"`
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
All *bool `url:"all,omitempty" json:"all,omitempty"`
|
||||
}
|
||||
|
||||
// CommitStatus represents a GitLab commit status.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-the-status-of-a-commit
|
||||
type CommitStatus struct {
|
||||
ID int `json:"id"`
|
||||
SHA string `json:"sha"`
|
||||
Ref string `json:"ref"`
|
||||
Status string `json:"status"`
|
||||
Name string `json:"name"`
|
||||
TargetURL string `json:"target_url"`
|
||||
Description string `json:"description"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
StartedAt *time.Time `json:"started_at"`
|
||||
FinishedAt *time.Time `json:"finished_at"`
|
||||
Author Author `json:"author"`
|
||||
}
|
||||
|
||||
// GetCommitStatuses gets the statuses of a commit in a project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#get-the-status-of-a-commit
|
||||
func (s *CommitsService) GetCommitStatuses(pid interface{}, sha string, opt *GetCommitStatusesOptions, options ...OptionFunc) ([]*CommitStatus, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/statuses", url.QueryEscape(project), sha)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var cs []*CommitStatus
|
||||
resp, err := s.client.Do(req, &cs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return cs, resp, err
|
||||
}
|
||||
|
||||
// SetCommitStatusOptions represents the available SetCommitStatus() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#post-the-status-to-commit
|
||||
type SetCommitStatusOptions struct {
|
||||
State BuildState `url:"state" json:"state"`
|
||||
Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Context *string `url:"context,omitempty" json:"context,omitempty"`
|
||||
TargetURL *string `url:"target_url,omitempty" json:"target_url,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// BuildState represents a GitLab build state.
|
||||
type BuildState string
|
||||
|
||||
// These constants represent all valid build states.
|
||||
const (
|
||||
Pending BuildState = "pending"
|
||||
Running BuildState = "running"
|
||||
Success BuildState = "success"
|
||||
Failed BuildState = "failed"
|
||||
Canceled BuildState = "canceled"
|
||||
)
|
||||
|
||||
// SetCommitStatus sets the status of a commit in a project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#post-the-status-to-commit
|
||||
func (s *CommitsService) SetCommitStatus(pid interface{}, sha string, opt *SetCommitStatusOptions, options ...OptionFunc) (*CommitStatus, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/statuses/%s", url.QueryEscape(project), sha)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var cs *CommitStatus
|
||||
resp, err := s.client.Do(req, &cs)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return cs, resp, err
|
||||
}
|
||||
|
||||
// CherryPickCommitOptions represents the available options for cherry-picking a commit.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#cherry-pick-a-commit
|
||||
type CherryPickCommitOptions struct {
|
||||
TargetBranch *string `url:"branch" json:"branch,omitempty"`
|
||||
}
|
||||
|
||||
// CherryPickCommit sherry picks a commit to a given branch.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/commits.html#cherry-pick-a-commit
|
||||
func (s *CommitsService) CherryPickCommit(pid interface{}, sha string, opt *CherryPickCommitOptions, options ...OptionFunc) (*Commit, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/commits/%s/cherry_pick",
|
||||
url.QueryEscape(project), url.QueryEscape(sha))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var c *Commit
|
||||
resp, err := s.client.Do(req, &c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
|
@ -0,0 +1,150 @@
|
|||
//
|
||||
// Copyright 2015, 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"
|
||||
"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)
|
||||
}
|
||||
|
||||
// ListDeployKeys gets a list of a project's deploy keys
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/deploy_keys.html#list-deploy-keys
|
||||
func (s *DeployKeysService) ListDeployKeys(pid interface{}, options ...OptionFunc) ([]*DeployKey, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/keys", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var k []*DeployKey
|
||||
resp, err := s.client.Do(req, &k)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return k, 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/keys/%d", url.QueryEscape(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/keys", url.QueryEscape(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/keys/%d", url.QueryEscape(project), deployKey)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
|
@ -0,0 +1,557 @@
|
|||
//
|
||||
// Copyright 2015, 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 "time"
|
||||
|
||||
// PushEvent represents a push event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#push-events
|
||||
type PushEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
Before string `json:"before"`
|
||||
After string `json:"after"`
|
||||
Ref string `json:"ref"`
|
||||
CheckoutSha string `json:"checkout_sha"`
|
||||
UserID int `json:"user_id"`
|
||||
UserName string `json:"user_name"`
|
||||
UserEmail string `json:"user_email"`
|
||||
UserAvatar string `json:"user_avatar"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
VisibilityLevel VisibilityLevelValue `json:"visibility_level"`
|
||||
} `json:"project"`
|
||||
Repository *Repository `json:"repository"`
|
||||
Commits []*Commit `json:"commits"`
|
||||
TotalCommitsCount int `json:"total_commits_count"`
|
||||
}
|
||||
|
||||
// TagEvent represents a tag event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#tag-events
|
||||
type TagEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
Before string `json:"before"`
|
||||
After string `json:"after"`
|
||||
Ref string `json:"ref"`
|
||||
CheckoutSha string `json:"checkout_sha"`
|
||||
UserID int `json:"user_id"`
|
||||
UserName string `json:"user_name"`
|
||||
UserAvatar string `json:"user_avatar"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
VisibilityLevel VisibilityLevelValue `json:"visibility_level"`
|
||||
} `json:"project"`
|
||||
Repository *Repository `json:"repository"`
|
||||
Commits []*Commit `json:"commits"`
|
||||
TotalCommitsCount int `json:"total_commits_count"`
|
||||
}
|
||||
|
||||
// IssueEvent represents a issue event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#issues-events
|
||||
type IssueEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
User *User `json:"user"`
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
VisibilityLevel VisibilityLevelValue `json:"visibility_level"`
|
||||
} `json:"project"`
|
||||
Repository *Repository `json:"repository"`
|
||||
ObjectAttributes struct {
|
||||
ID int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
AssigneeID int `json:"assignee_id"`
|
||||
AuthorID int `json:"author_id"`
|
||||
ProjectID int `json:"project_id"`
|
||||
CreatedAt string `json:"created_at"` // Should be *time.Time (see Gitlab issue #21468)
|
||||
UpdatedAt string `json:"updated_at"` // Should be *time.Time (see Gitlab issue #21468)
|
||||
Position int `json:"position"`
|
||||
BranchName string `json:"branch_name"`
|
||||
Description string `json:"description"`
|
||||
MilestoneID int `json:"milestone_id"`
|
||||
State string `json:"state"`
|
||||
Iid int `json:"iid"`
|
||||
URL string `json:"url"`
|
||||
Action string `json:"action"`
|
||||
} `json:"object_attributes"`
|
||||
Assignee struct {
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
} `json:"assignee"`
|
||||
}
|
||||
|
||||
// CommitCommentEvent represents a comment on a commit event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#comment-on-commit
|
||||
type CommitCommentEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
User *User `json:"user"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
VisibilityLevel VisibilityLevelValue `json:"visibility_level"`
|
||||
} `json:"project"`
|
||||
Repository *Repository `json:"repository"`
|
||||
ObjectAttributes struct {
|
||||
ID int `json:"id"`
|
||||
Note string `json:"note"`
|
||||
NoteableType string `json:"noteable_type"`
|
||||
AuthorID int `json:"author_id"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Attachment string `json:"attachment"`
|
||||
LineCode string `json:"line_code"`
|
||||
CommitID string `json:"commit_id"`
|
||||
NoteableID int `json:"noteable_id"`
|
||||
System bool `json:"system"`
|
||||
StDiff struct {
|
||||
Diff string `json:"diff"`
|
||||
NewPath string `json:"new_path"`
|
||||
OldPath string `json:"old_path"`
|
||||
AMode string `json:"a_mode"`
|
||||
BMode string `json:"b_mode"`
|
||||
NewFile bool `json:"new_file"`
|
||||
RenamedFile bool `json:"renamed_file"`
|
||||
DeletedFile bool `json:"deleted_file"`
|
||||
} `json:"st_diff"`
|
||||
} `json:"object_attributes"`
|
||||
Commit *Commit `json:"commit"`
|
||||
}
|
||||
|
||||
// MergeCommentEvent represents a comment on a merge event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#comment-on-merge-request
|
||||
type MergeCommentEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
User *User `json:"user"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
VisibilityLevel VisibilityLevelValue `json:"visibility_level"`
|
||||
} `json:"project"`
|
||||
Repository *Repository `json:"repository"`
|
||||
ObjectAttributes struct {
|
||||
ID int `json:"id"`
|
||||
Note string `json:"note"`
|
||||
NoteableType string `json:"noteable_type"`
|
||||
AuthorID int `json:"author_id"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Attachment string `json:"attachment"`
|
||||
LineCode string `json:"line_code"`
|
||||
CommitID string `json:"commit_id"`
|
||||
NoteableID int `json:"noteable_id"`
|
||||
System bool `json:"system"`
|
||||
StDiff *Diff `json:"st_diff"`
|
||||
URL string `json:"url"`
|
||||
} `json:"object_attributes"`
|
||||
MergeRequest *MergeRequest `json:"merge_request"`
|
||||
}
|
||||
|
||||
// IssueCommentEvent represents a comment on an issue event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#comment-on-issue
|
||||
type IssueCommentEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
User *User `json:"user"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
VisibilityLevel VisibilityLevelValue `json:"visibility_level"`
|
||||
} `json:"project"`
|
||||
Repository *Repository `json:"repository"`
|
||||
ObjectAttributes struct {
|
||||
ID int `json:"id"`
|
||||
Note string `json:"note"`
|
||||
NoteableType string `json:"noteable_type"`
|
||||
AuthorID int `json:"author_id"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Attachment string `json:"attachment"`
|
||||
LineCode string `json:"line_code"`
|
||||
CommitID string `json:"commit_id"`
|
||||
NoteableID int `json:"noteable_id"`
|
||||
System bool `json:"system"`
|
||||
StDiff []*Diff `json:"st_diff"`
|
||||
URL string `json:"url"`
|
||||
} `json:"object_attributes"`
|
||||
Issue *Issue `json:"issue"`
|
||||
}
|
||||
|
||||
// SnippetCommentEvent represents a comment on a snippet event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#comment-on-code-snippet
|
||||
type SnippetCommentEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
User *User `json:"user"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
VisibilityLevel VisibilityLevelValue `json:"visibility_level"`
|
||||
} `json:"project"`
|
||||
Repository *Repository `json:"repository"`
|
||||
ObjectAttributes struct {
|
||||
ID int `json:"id"`
|
||||
Note string `json:"note"`
|
||||
NoteableType string `json:"noteable_type"`
|
||||
AuthorID int `json:"author_id"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
UpdatedAt string `json:"updated_at"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Attachment string `json:"attachment"`
|
||||
LineCode string `json:"line_code"`
|
||||
CommitID string `json:"commit_id"`
|
||||
NoteableID int `json:"noteable_id"`
|
||||
System bool `json:"system"`
|
||||
StDiff *Diff `json:"st_diff"`
|
||||
URL string `json:"url"`
|
||||
} `json:"object_attributes"`
|
||||
Snippet *Snippet `json:"snippet"`
|
||||
}
|
||||
|
||||
// MergeEvent represents a merge event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#merge-request-events
|
||||
type MergeEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
User *User `json:"user"`
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
VisibilityLevel VisibilityLevelValue `json:"visibility_level"`
|
||||
} `json:"project"`
|
||||
ObjectAttributes struct {
|
||||
ID int `json:"id"`
|
||||
TargetBranch string `json:"target_branch"`
|
||||
SourceBranch string `json:"source_branch"`
|
||||
SourceProjectID int `json:"source_project_id"`
|
||||
AuthorID int `json:"author_id"`
|
||||
AssigneeID int `json:"assignee_id"`
|
||||
Title string `json:"title"`
|
||||
CreatedAt string `json:"created_at"` // Should be *time.Time (see Gitlab issue #21468)
|
||||
UpdatedAt string `json:"updated_at"` // Should be *time.Time (see Gitlab issue #21468)
|
||||
StCommits []*Commit `json:"st_commits"`
|
||||
StDiffs []*Diff `json:"st_diffs"`
|
||||
MilestoneID int `json:"milestone_id"`
|
||||
State string `json:"state"`
|
||||
MergeStatus string `json:"merge_status"`
|
||||
TargetProjectID int `json:"target_project_id"`
|
||||
Iid int `json:"iid"`
|
||||
Description string `json:"description"`
|
||||
Position int `json:"position"`
|
||||
LockedAt string `json:"locked_at"`
|
||||
UpdatedByID int `json:"updated_by_id"`
|
||||
MergeError string `json:"merge_error"`
|
||||
MergeParams struct {
|
||||
ForceRemoveSourceBranch string `json:"force_remove_source_branch"`
|
||||
} `json:"merge_params"`
|
||||
MergeWhenBuildSucceeds bool `json:"merge_when_build_succeeds"`
|
||||
MergeUserID int `json:"merge_user_id"`
|
||||
MergeCommitSha string `json:"merge_commit_sha"`
|
||||
DeletedAt string `json:"deleted_at"`
|
||||
ApprovalsBeforeMerge string `json:"approvals_before_merge"`
|
||||
RebaseCommitSha string `json:"rebase_commit_sha"`
|
||||
InProgressMergeCommitSha string `json:"in_progress_merge_commit_sha"`
|
||||
LockVersion int `json:"lock_version"`
|
||||
TimeEstimate int `json:"time_estimate"`
|
||||
Source *Repository `json:"source"`
|
||||
Target *Repository `json:"target"`
|
||||
LastCommit struct {
|
||||
ID string `json:"id"`
|
||||
Message string `json:"message"`
|
||||
Timestamp *time.Time `json:"timestamp"`
|
||||
URL string `json:"url"`
|
||||
Author *Author `json:"author"`
|
||||
} `json:"last_commit"`
|
||||
WorkInProgress bool `json:"work_in_progress"`
|
||||
URL string `json:"url"`
|
||||
Action string `json:"action"`
|
||||
Assignee struct {
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
} `json:"assignee"`
|
||||
} `json:"object_attributes"`
|
||||
Repository *Repository `json:"repository"`
|
||||
Assignee struct {
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
} `json:"assignee"`
|
||||
}
|
||||
|
||||
// WikiPageEvent represents a wiki page event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#wiki-page-events
|
||||
type WikiPageEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
User *User `json:"user"`
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
VisibilityLevel VisibilityLevelValue `json:"visibility_level"`
|
||||
} `json:"project"`
|
||||
Wiki struct {
|
||||
WebURL string `json:"web_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
} `json:"wiki"`
|
||||
ObjectAttributes struct {
|
||||
Title string `json:"title"`
|
||||
Content string `json:"content"`
|
||||
Format string `json:"format"`
|
||||
Message string `json:"message"`
|
||||
Slug string `json:"slug"`
|
||||
URL string `json:"url"`
|
||||
Action string `json:"action"`
|
||||
} `json:"object_attributes"`
|
||||
}
|
||||
|
||||
// PipelineEvent represents a pipeline event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#pipeline-events
|
||||
type PipelineEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
ObjectAttributes struct {
|
||||
ID int `json:"id"`
|
||||
Ref string `json:"ref"`
|
||||
Tag bool `json:"tag"`
|
||||
Sha string `json:"sha"`
|
||||
BeforeSha string `json:"before_sha"`
|
||||
Status string `json:"status"`
|
||||
Stages []string `json:"stages"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
FinishedAt string `json:"finished_at"`
|
||||
Duration int `json:"duration"`
|
||||
} `json:"object_attributes"`
|
||||
User struct {
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
} `json:"user"`
|
||||
Project struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
VisibilityLevel VisibilityLevelValue `json:"visibility_level"`
|
||||
} `json:"project"`
|
||||
Commit struct {
|
||||
ID string `json:"id"`
|
||||
Message string `json:"message"`
|
||||
Timestamp time.Time `json:"timestamp"`
|
||||
URL string `json:"url"`
|
||||
Author struct {
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
} `json:"author"`
|
||||
} `json:"commit"`
|
||||
Builds []struct {
|
||||
ID int `json:"id"`
|
||||
Stage string `json:"stage"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
CreatedAt string `json:"created_at"`
|
||||
StartedAt string `json:"started_at"`
|
||||
FinishedAt string `json:"finished_at"`
|
||||
When string `json:"when"`
|
||||
Manual bool `json:"manual"`
|
||||
User struct {
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
} `json:"user"`
|
||||
Runner string `json:"runner"`
|
||||
ArtifactsFile struct {
|
||||
Filename string `json:"filename"`
|
||||
Size string `json:"size"`
|
||||
} `json:"artifacts_file"`
|
||||
} `json:"builds"`
|
||||
}
|
||||
|
||||
//BuildEvent represents a build event
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/web_hooks/web_hooks.html#build-events
|
||||
type BuildEvent struct {
|
||||
ObjectKind string `json:"object_kind"`
|
||||
Ref string `json:"ref"`
|
||||
Tag bool `json:"tag"`
|
||||
BeforeSha string `json:"before_sha"`
|
||||
Sha string `json:"sha"`
|
||||
BuildID int `json:"build_id"`
|
||||
BuildName string `json:"build_name"`
|
||||
BuildStage string `json:"build_stage"`
|
||||
BuildStatus string `json:"build_status"`
|
||||
BuildStartedAt string `json:"build_started_at"`
|
||||
BuildFinishedAt string `json:"build_finished_at"`
|
||||
BuildDuration string `json:"build_duration"`
|
||||
BuildAllowFailure bool `json:"build_allow_failure"`
|
||||
ProjectID int `json:"project_id"`
|
||||
ProjectName string `json:"project_name"`
|
||||
User struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Email string `json:"email"`
|
||||
} `json:"user"`
|
||||
Commit struct {
|
||||
ID int `json:"id"`
|
||||
Sha string `json:"sha"`
|
||||
Message string `json:"message"`
|
||||
AuthorName string `json:"author_name"`
|
||||
AuthorEmail string `json:"author_email"`
|
||||
Status string `json:"status"`
|
||||
Duration string `json:"duration"`
|
||||
StartedAt string `json:"started_at"`
|
||||
FinishedAt string `json:"finished_at"`
|
||||
} `json:"commit"`
|
||||
Repository *Repository `json:"repository"`
|
||||
}
|
|
@ -0,0 +1,605 @@
|
|||
//
|
||||
// Copyright 2015, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/google/go-querystring/query"
|
||||
)
|
||||
|
||||
const (
|
||||
libraryVersion = "0.1.1"
|
||||
defaultBaseURL = "https://gitlab.com/api/v3/"
|
||||
userAgent = "go-gitlab/" + libraryVersion
|
||||
)
|
||||
|
||||
// tokenType represents a token type within GitLab.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/
|
||||
type tokenType int
|
||||
|
||||
// List of available token type
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/
|
||||
const (
|
||||
privateToken tokenType = iota
|
||||
oAuthToken
|
||||
)
|
||||
|
||||
// AccessLevelValue represents a permission level within GitLab.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/permissions/permissions.html
|
||||
type AccessLevelValue int
|
||||
|
||||
// List of available access levels
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/permissions/permissions.html
|
||||
const (
|
||||
GuestPermissions AccessLevelValue = 10
|
||||
ReporterPermissions AccessLevelValue = 20
|
||||
DeveloperPermissions AccessLevelValue = 30
|
||||
MasterPermissions AccessLevelValue = 40
|
||||
OwnerPermission AccessLevelValue = 50
|
||||
)
|
||||
|
||||
// NotificationLevelValue represents a notification level.
|
||||
type NotificationLevelValue int
|
||||
|
||||
// String implements the fmt.Stringer interface.
|
||||
func (l NotificationLevelValue) String() string {
|
||||
return notificationLevelNames[l]
|
||||
}
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (l NotificationLevelValue) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(l.String())
|
||||
}
|
||||
|
||||
// UnmarshalJSON implements the json.Unmarshaler interface.
|
||||
func (l *NotificationLevelValue) UnmarshalJSON(data []byte) error {
|
||||
var raw interface{}
|
||||
if err := json.Unmarshal(data, &raw); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch raw := raw.(type) {
|
||||
case float64:
|
||||
*l = NotificationLevelValue(raw)
|
||||
case string:
|
||||
*l = notificationLevelTypes[raw]
|
||||
default:
|
||||
return fmt.Errorf("json: cannot unmarshal %T into Go value of type %T", raw, *l)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// List of valid notification levels.
|
||||
const (
|
||||
DisabledNotificationLevel NotificationLevelValue = iota
|
||||
ParticipatingNotificationLevel
|
||||
WatchNotificationLevel
|
||||
GlobalNotificationLevel
|
||||
MentionNotificationLevel
|
||||
CustomNotificationLevel
|
||||
)
|
||||
|
||||
var notificationLevelNames = [...]string{
|
||||
"disabled",
|
||||
"participating",
|
||||
"watch",
|
||||
"global",
|
||||
"mention",
|
||||
"custom",
|
||||
}
|
||||
|
||||
var notificationLevelTypes = map[string]NotificationLevelValue{
|
||||
"disabled": DisabledNotificationLevel,
|
||||
"participating": ParticipatingNotificationLevel,
|
||||
"watch": WatchNotificationLevel,
|
||||
"global": GlobalNotificationLevel,
|
||||
"mention": MentionNotificationLevel,
|
||||
"custom": CustomNotificationLevel,
|
||||
}
|
||||
|
||||
// VisibilityLevelValue represents a visibility level within GitLab.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/
|
||||
type VisibilityLevelValue int
|
||||
|
||||
// List of available visibility levels
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/
|
||||
const (
|
||||
PrivateVisibility VisibilityLevelValue = 0
|
||||
InternalVisibility VisibilityLevelValue = 10
|
||||
PublicVisibility VisibilityLevelValue = 20
|
||||
)
|
||||
|
||||
// A Client manages communication with the GitLab API.
|
||||
type Client struct {
|
||||
// HTTP client used to communicate with the API.
|
||||
client *http.Client
|
||||
|
||||
// Base URL for API requests. Defaults to the public GitLab API, but can be
|
||||
// set to a domain endpoint to use with aself hosted GitLab server. baseURL
|
||||
// should always be specified with a trailing slash.
|
||||
baseURL *url.URL
|
||||
|
||||
// token type used to make authenticated API calls.
|
||||
tokenType tokenType
|
||||
|
||||
// token used to make authenticated API calls.
|
||||
token string
|
||||
|
||||
// User agent used when communicating with the GitLab API.
|
||||
UserAgent string
|
||||
|
||||
// Services used for talking to different parts of the GitLab API.
|
||||
Branches *BranchesService
|
||||
BuildVariables *BuildVariablesService
|
||||
Builds *BuildsService
|
||||
Commits *CommitsService
|
||||
DeployKeys *DeployKeysService
|
||||
Groups *GroupsService
|
||||
Issues *IssuesService
|
||||
Labels *LabelsService
|
||||
MergeRequests *MergeRequestsService
|
||||
Milestones *MilestonesService
|
||||
Namespaces *NamespacesService
|
||||
Notes *NotesService
|
||||
NotificationSettings *NotificationSettingsService
|
||||
Projects *ProjectsService
|
||||
ProjectSnippets *ProjectSnippetsService
|
||||
Pipelines *PipelinesService
|
||||
Repositories *RepositoriesService
|
||||
RepositoryFiles *RepositoryFilesService
|
||||
Services *ServicesService
|
||||
Session *SessionService
|
||||
Settings *SettingsService
|
||||
SystemHooks *SystemHooksService
|
||||
Tags *TagsService
|
||||
TimeStats *TimeStatsService
|
||||
Users *UsersService
|
||||
}
|
||||
|
||||
// ListOptions specifies the optional parameters to various List methods that
|
||||
// support pagination.
|
||||
type ListOptions struct {
|
||||
// For paginated result sets, page of results to retrieve.
|
||||
Page int `url:"page,omitempty" json:"page,omitempty"`
|
||||
|
||||
// For paginated result sets, the number of results to include per page.
|
||||
PerPage int `url:"per_page,omitempty" json:"per_page,omitempty"`
|
||||
}
|
||||
|
||||
// NewClient returns a new GitLab API client. If a nil httpClient is
|
||||
// provided, http.DefaultClient will be used. To use API methods which require
|
||||
// authentication, provide a valid private token.
|
||||
func NewClient(httpClient *http.Client, token string) *Client {
|
||||
return newClient(httpClient, privateToken, token)
|
||||
}
|
||||
|
||||
// NewOAuthClient returns a new GitLab API client. If a nil httpClient is
|
||||
// provided, http.DefaultClient will be used. To use API methods which require
|
||||
// authentication, provide a valid oauth token.
|
||||
func NewOAuthClient(httpClient *http.Client, token string) *Client {
|
||||
return newClient(httpClient, oAuthToken, token)
|
||||
}
|
||||
|
||||
func newClient(httpClient *http.Client, tokenType tokenType, token string) *Client {
|
||||
if httpClient == nil {
|
||||
httpClient = http.DefaultClient
|
||||
}
|
||||
|
||||
c := &Client{client: httpClient, tokenType: tokenType, token: token, UserAgent: userAgent}
|
||||
if err := c.SetBaseURL(defaultBaseURL); err != nil {
|
||||
// should never happen since defaultBaseURL is our constant
|
||||
panic(err)
|
||||
}
|
||||
|
||||
c.Branches = &BranchesService{client: c}
|
||||
c.BuildVariables = &BuildVariablesService{client: c}
|
||||
c.Builds = &BuildsService{client: c}
|
||||
c.Commits = &CommitsService{client: c}
|
||||
c.DeployKeys = &DeployKeysService{client: c}
|
||||
c.Groups = &GroupsService{client: c}
|
||||
c.Issues = &IssuesService{client: c}
|
||||
c.Labels = &LabelsService{client: c}
|
||||
c.MergeRequests = &MergeRequestsService{client: c}
|
||||
c.Milestones = &MilestonesService{client: c}
|
||||
c.Namespaces = &NamespacesService{client: c}
|
||||
c.Notes = &NotesService{client: c}
|
||||
c.NotificationSettings = &NotificationSettingsService{client: c}
|
||||
c.Projects = &ProjectsService{client: c}
|
||||
c.ProjectSnippets = &ProjectSnippetsService{client: c}
|
||||
c.Pipelines = &PipelinesService{client: c}
|
||||
c.Repositories = &RepositoriesService{client: c}
|
||||
c.RepositoryFiles = &RepositoryFilesService{client: c}
|
||||
c.Services = &ServicesService{client: c}
|
||||
c.Session = &SessionService{client: c}
|
||||
c.Settings = &SettingsService{client: c}
|
||||
c.SystemHooks = &SystemHooksService{client: c}
|
||||
c.Tags = &TagsService{client: c}
|
||||
c.TimeStats = &TimeStatsService{client: c}
|
||||
c.Users = &UsersService{client: c}
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
// BaseURL return a copy of the baseURL.
|
||||
func (c *Client) BaseURL() *url.URL {
|
||||
u := *c.baseURL
|
||||
return &u
|
||||
}
|
||||
|
||||
// SetBaseURL sets the base URL for API requests to a custom endpoint. urlStr
|
||||
// should always be specified with a trailing slash.
|
||||
func (c *Client) SetBaseURL(urlStr string) error {
|
||||
// Make sure the given URL end with a slash
|
||||
if !strings.HasSuffix(urlStr, "/") {
|
||||
urlStr += "/"
|
||||
}
|
||||
|
||||
var err error
|
||||
c.baseURL, err = url.Parse(urlStr)
|
||||
return err
|
||||
}
|
||||
|
||||
// NewRequest creates an API request. A relative URL path can be provided in
|
||||
// urlStr, in which case it is resolved relative to the base URL of the Client.
|
||||
// Relative URL paths should always be specified without a preceding slash. If
|
||||
// specified, the value pointed to by body is JSON encoded and included as the
|
||||
// request body.
|
||||
func (c *Client) NewRequest(method, path string, opt interface{}, options []OptionFunc) (*http.Request, error) {
|
||||
u := *c.baseURL
|
||||
// Set the encoded opaque data
|
||||
u.Opaque = c.baseURL.Path + path
|
||||
|
||||
if opt != nil {
|
||||
q, err := query.Values(opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u.RawQuery = q.Encode()
|
||||
}
|
||||
|
||||
req := &http.Request{
|
||||
Method: method,
|
||||
URL: &u,
|
||||
Proto: "HTTP/1.1",
|
||||
ProtoMajor: 1,
|
||||
ProtoMinor: 1,
|
||||
Header: make(http.Header),
|
||||
Host: u.Host,
|
||||
}
|
||||
|
||||
for _, fn := range options {
|
||||
if err := fn(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
if method == "POST" || method == "PUT" {
|
||||
bodyBytes, err := json.Marshal(opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
bodyReader := bytes.NewReader(bodyBytes)
|
||||
|
||||
u.RawQuery = ""
|
||||
req.Body = ioutil.NopCloser(bodyReader)
|
||||
req.ContentLength = int64(bodyReader.Len())
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
switch c.tokenType {
|
||||
case privateToken:
|
||||
req.Header.Set("PRIVATE-TOKEN", c.token)
|
||||
case oAuthToken:
|
||||
req.Header.Set("Authorization", "Bearer "+c.token)
|
||||
}
|
||||
|
||||
if c.UserAgent != "" {
|
||||
req.Header.Set("User-Agent", c.UserAgent)
|
||||
}
|
||||
|
||||
return req, nil
|
||||
}
|
||||
|
||||
// Response is a GitLab API response. This wraps the standard http.Response
|
||||
// returned from GitLab and provides convenient access to things like
|
||||
// pagination links.
|
||||
type Response struct {
|
||||
*http.Response
|
||||
|
||||
// These fields provide the page values for paginating through a set of
|
||||
// results. Any or all of these may be set to the zero value for
|
||||
// responses that are not part of a paginated set, or for which there
|
||||
// are no additional pages.
|
||||
|
||||
NextPage int
|
||||
PrevPage int
|
||||
FirstPage int
|
||||
LastPage int
|
||||
}
|
||||
|
||||
// newResponse creats a new Response for the provided http.Response.
|
||||
func newResponse(r *http.Response) *Response {
|
||||
response := &Response{Response: r}
|
||||
response.populatePageValues()
|
||||
return response
|
||||
}
|
||||
|
||||
// populatePageValues parses the HTTP Link response headers and populates the
|
||||
// various pagination link values in the Reponse.
|
||||
func (r *Response) populatePageValues() {
|
||||
if links, ok := r.Response.Header["Link"]; ok && len(links) > 0 {
|
||||
for _, link := range strings.Split(links[0], ",") {
|
||||
segments := strings.Split(strings.TrimSpace(link), ";")
|
||||
|
||||
// link must at least have href and rel
|
||||
if len(segments) < 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
// ensure href is properly formatted
|
||||
if !strings.HasPrefix(segments[0], "<") || !strings.HasSuffix(segments[0], ">") {
|
||||
continue
|
||||
}
|
||||
|
||||
// try to pull out page parameter
|
||||
url, err := url.Parse(segments[0][1 : len(segments[0])-1])
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
page := url.Query().Get("page")
|
||||
if page == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, segment := range segments[1:] {
|
||||
switch strings.TrimSpace(segment) {
|
||||
case `rel="next"`:
|
||||
r.NextPage, _ = strconv.Atoi(page)
|
||||
case `rel="prev"`:
|
||||
r.PrevPage, _ = strconv.Atoi(page)
|
||||
case `rel="first"`:
|
||||
r.FirstPage, _ = strconv.Atoi(page)
|
||||
case `rel="last"`:
|
||||
r.LastPage, _ = strconv.Atoi(page)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do sends an API request and returns the API response. The API response is
|
||||
// JSON decoded and stored in the value pointed to by v, or returned as an
|
||||
// error if an API error has occurred. If v implements the io.Writer
|
||||
// interface, the raw response body will be written to v, without attempting to
|
||||
// first decode it.
|
||||
func (c *Client) Do(req *http.Request, v interface{}) (*Response, error) {
|
||||
resp, err := c.client.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
response := newResponse(resp)
|
||||
|
||||
err = CheckResponse(resp)
|
||||
if err != nil {
|
||||
// even though there was an error, we still return the response
|
||||
// in case the caller wants to inspect it further
|
||||
return response, err
|
||||
}
|
||||
|
||||
if v != nil {
|
||||
if w, ok := v.(io.Writer); ok {
|
||||
_, err = io.Copy(w, resp.Body)
|
||||
} else {
|
||||
err = json.NewDecoder(resp.Body).Decode(v)
|
||||
}
|
||||
}
|
||||
return response, err
|
||||
}
|
||||
|
||||
// Helper function to accept and format both the project ID or name as project
|
||||
// identifier for all API calls.
|
||||
func parseID(id interface{}) (string, error) {
|
||||
switch v := id.(type) {
|
||||
case int:
|
||||
return strconv.Itoa(v), nil
|
||||
case string:
|
||||
return v, nil
|
||||
default:
|
||||
return "", fmt.Errorf("invalid ID type %#v, the ID must be an int or a string", id)
|
||||
}
|
||||
}
|
||||
|
||||
// An ErrorResponse reports one or more errors caused by an API request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/README.html#data-validation-and-error-reporting
|
||||
type ErrorResponse struct {
|
||||
Response *http.Response
|
||||
Message string
|
||||
}
|
||||
|
||||
func (e *ErrorResponse) Error() string {
|
||||
path, _ := url.QueryUnescape(e.Response.Request.URL.Opaque)
|
||||
u := fmt.Sprintf("%s://%s%s", e.Response.Request.URL.Scheme, e.Response.Request.URL.Host, path)
|
||||
return fmt.Sprintf("%s %s: %d %s", e.Response.Request.Method, u, e.Response.StatusCode, e.Message)
|
||||
}
|
||||
|
||||
// CheckResponse checks the API response for errors, and returns them if present.
|
||||
func CheckResponse(r *http.Response) error {
|
||||
switch r.StatusCode {
|
||||
case 200, 201, 304:
|
||||
return nil
|
||||
}
|
||||
|
||||
errorResponse := &ErrorResponse{Response: r}
|
||||
data, err := ioutil.ReadAll(r.Body)
|
||||
if err == nil && data != nil {
|
||||
var raw interface{}
|
||||
if err := json.Unmarshal(data, &raw); err != nil {
|
||||
errorResponse.Message = "failed to parse unknown error format"
|
||||
}
|
||||
|
||||
errorResponse.Message = parseError(raw)
|
||||
}
|
||||
|
||||
return errorResponse
|
||||
}
|
||||
|
||||
// Format:
|
||||
// {
|
||||
// "message": {
|
||||
// "<property-name>": [
|
||||
// "<error-message>",
|
||||
// "<error-message>",
|
||||
// ...
|
||||
// ],
|
||||
// "<embed-entity>": {
|
||||
// "<property-name>": [
|
||||
// "<error-message>",
|
||||
// "<error-message>",
|
||||
// ...
|
||||
// ],
|
||||
// }
|
||||
// },
|
||||
// "error": "<error-message>"
|
||||
// }
|
||||
func parseError(raw interface{}) string {
|
||||
switch raw := raw.(type) {
|
||||
case string:
|
||||
return raw
|
||||
|
||||
case []interface{}:
|
||||
var errs []string
|
||||
for _, v := range raw {
|
||||
errs = append(errs, parseError(v))
|
||||
}
|
||||
return fmt.Sprintf("[%s]", strings.Join(errs, ", "))
|
||||
|
||||
case map[string]interface{}:
|
||||
var errs []string
|
||||
for k, v := range raw {
|
||||
errs = append(errs, fmt.Sprintf("{%s: %s}", k, parseError(v)))
|
||||
}
|
||||
sort.Strings(errs)
|
||||
return fmt.Sprintf("%s", strings.Join(errs, ", "))
|
||||
|
||||
default:
|
||||
return fmt.Sprintf("failed to parse unexpected error type: %T", raw)
|
||||
}
|
||||
}
|
||||
|
||||
// OptionFunc can be passed to all API requests to make the API call as if you were
|
||||
// another user, provided your private token is from an administrator account.
|
||||
//
|
||||
// GitLab docs: https://docs.gitlab.com/ce/api/README.html#sudo
|
||||
type OptionFunc func(*http.Request) error
|
||||
|
||||
// WithSudo takes either a username or user ID and sets the SUDO request header
|
||||
func WithSudo(uid interface{}) OptionFunc {
|
||||
return func(req *http.Request) error {
|
||||
switch uid := uid.(type) {
|
||||
case int:
|
||||
req.Header.Set("SUDO", strconv.Itoa(uid))
|
||||
return nil
|
||||
case string:
|
||||
req.Header.Set("SUDO", uid)
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("uid must be either a username or user ID")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// WithContext runs the request with the provided context
|
||||
func WithContext(ctx context.Context) OptionFunc {
|
||||
return func(req *http.Request) error {
|
||||
*req = *req.WithContext(ctx)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Bool is a helper routine that allocates a new bool value
|
||||
// to store v and returns a pointer to it.
|
||||
func Bool(v bool) *bool {
|
||||
p := new(bool)
|
||||
*p = v
|
||||
return p
|
||||
}
|
||||
|
||||
// Int is a helper routine that allocates a new int32 value
|
||||
// to store v and returns a pointer to it, but unlike Int32
|
||||
// its argument value is an int.
|
||||
func Int(v int) *int {
|
||||
p := new(int)
|
||||
*p = v
|
||||
return p
|
||||
}
|
||||
|
||||
// String is a helper routine that allocates a new string value
|
||||
// to store v and returns a pointer to it.
|
||||
func String(v string) *string {
|
||||
p := new(string)
|
||||
*p = v
|
||||
return p
|
||||
}
|
||||
|
||||
// AccessLevel is a helper routine that allocates a new AccessLevelValue
|
||||
// to store v and returns a pointer to it.
|
||||
func AccessLevel(v AccessLevelValue) *AccessLevelValue {
|
||||
p := new(AccessLevelValue)
|
||||
*p = v
|
||||
return p
|
||||
}
|
||||
|
||||
// NotificationLevel is a helper routine that allocates a new NotificationLevelValue
|
||||
// to store v and returns a pointer to it.
|
||||
func NotificationLevel(v NotificationLevelValue) *NotificationLevelValue {
|
||||
p := new(NotificationLevelValue)
|
||||
*p = v
|
||||
return p
|
||||
}
|
||||
|
||||
// VisibilityLevel is a helper routine that allocates a new VisibilityLevelValue
|
||||
// to store v and returns a pointer to it.
|
||||
func VisibilityLevel(v VisibilityLevelValue) *VisibilityLevelValue {
|
||||
p := new(VisibilityLevelValue)
|
||||
*p = v
|
||||
return p
|
||||
}
|
|
@ -0,0 +1,358 @@
|
|||
//
|
||||
// Copyright 2015, 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"
|
||||
)
|
||||
|
||||
// GroupsService handles communication with the group related methods of
|
||||
// the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html
|
||||
type GroupsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Group represents a GitLab group.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html
|
||||
type Group struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
Description string `json:"description"`
|
||||
Projects []*Project `json:"projects"`
|
||||
Statistics *StorageStatistics `json:"statistics"`
|
||||
}
|
||||
|
||||
// ListGroupsOptions represents the available ListGroups() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#list-project-groups
|
||||
type ListGroupsOptions struct {
|
||||
ListOptions
|
||||
Search *string `url:"search,omitempty" json:"search,omitempty"`
|
||||
Statistics *bool `url:"statistics,omitempty" json:"statistics,omitempty"`
|
||||
}
|
||||
|
||||
// ListGroups gets a list of groups. (As user: my groups, as admin: all groups)
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-project-groups
|
||||
func (s *GroupsService) ListGroups(opt *ListGroupsOptions, options ...OptionFunc) ([]*Group, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "groups", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var g []*Group
|
||||
resp, err := s.client.Do(req, &g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// GetGroup gets all details of a group.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#details-of-a-group
|
||||
func (s *GroupsService) GetGroup(gid interface{}, options ...OptionFunc) (*Group, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s", group)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(Group)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// CreateGroupOptions represents the available CreateGroup() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#new-group
|
||||
type CreateGroupOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Path *string `url:"path,omitempty" json:"path,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
VisibilityLevel *VisibilityLevelValue `url:"visibility_level" json:"visibility_level,omitempty"`
|
||||
}
|
||||
|
||||
// CreateGroup creates a new project group. Available only for users who can
|
||||
// create groups.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#new-group
|
||||
func (s *GroupsService) CreateGroup(opt *CreateGroupOptions, options ...OptionFunc) (*Group, *Response, error) {
|
||||
req, err := s.client.NewRequest("POST", "groups", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(Group)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// TransferGroup transfers a project to the Group namespace. Available only
|
||||
// for admin.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#transfer-project-to-group
|
||||
func (s *GroupsService) TransferGroup(gid interface{}, project int, options ...OptionFunc) (*Group, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/projects/%d", group, project)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(Group)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// DeleteGroup removes group with all projects inside.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#remove-group
|
||||
func (s *GroupsService) DeleteGroup(gid interface{}, options ...OptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s", group)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// SearchGroup get all groups that match your string in their name or path.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#search-for-group
|
||||
func (s *GroupsService) SearchGroup(query string, options ...OptionFunc) ([]*Group, *Response, error) {
|
||||
var q struct {
|
||||
Search string `url:"search,omitempty" json:"search,omitempty"`
|
||||
}
|
||||
q.Search = query
|
||||
|
||||
req, err := s.client.NewRequest("GET", "groups", &q, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var g []*Group
|
||||
resp, err := s.client.Do(req, &g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// GroupMember represents a GitLab group member.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html
|
||||
type GroupMember struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
AccessLevel AccessLevelValue `json:"access_level"`
|
||||
}
|
||||
|
||||
// ListGroupMembersOptions represents the available ListGroupMembers()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-group-members
|
||||
type ListGroupMembersOptions struct {
|
||||
ListOptions
|
||||
}
|
||||
|
||||
// ListGroupMembers get a list of group members viewable by the authenticated
|
||||
// user.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-group-members
|
||||
func (s *GroupsService) ListGroupMembers(gid interface{}, opt *ListGroupMembersOptions, options ...OptionFunc) ([]*GroupMember, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/members", group)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var g []*GroupMember
|
||||
resp, err := s.client.Do(req, &g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// ListGroupProjectsOptions represents the available ListGroupProjects()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-a-group-s-projects
|
||||
type ListGroupProjectsOptions struct {
|
||||
ListOptions
|
||||
}
|
||||
|
||||
// ListGroupProjects get a list of group projects
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-a-group-s-projects
|
||||
func (s *GroupsService) ListGroupProjects(gid interface{}, opt *ListGroupProjectsOptions, options ...OptionFunc) ([]*Project, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/projects", group)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var p []*Project
|
||||
resp, err := s.client.Do(req, &p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// AddGroupMemberOptions represents the available AddGroupMember() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#add-group-member
|
||||
type AddGroupMemberOptions struct {
|
||||
UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"`
|
||||
AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"`
|
||||
}
|
||||
|
||||
// AddGroupMember adds a user to the list of group members.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-group-members
|
||||
func (s *GroupsService) AddGroupMember(gid interface{}, opt *AddGroupMemberOptions, options ...OptionFunc) (*GroupMember, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/members", group)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(GroupMember)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// UpdateGroupMemberOptions represents the available UpdateGroupMember()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#edit-group-team-member
|
||||
type UpdateGroupMemberOptions struct {
|
||||
AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateGroupMember updates a group team member to a specified access level.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#list-group-members
|
||||
func (s *GroupsService) UpdateGroupMember(gid interface{}, user int, opt *UpdateGroupMemberOptions, options ...OptionFunc) (*GroupMember, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/members/%d", group, user)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
g := new(GroupMember)
|
||||
resp, err := s.client.Do(req, g)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return g, resp, err
|
||||
}
|
||||
|
||||
// RemoveGroupMember removes user from user team.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/groups.html#remove-user-from-user-team
|
||||
func (s *GroupsService) RemoveGroupMember(gid interface{}, user int, options ...OptionFunc) (*Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/members/%d", group, user)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
|
@ -0,0 +1,264 @@
|
|||
//
|
||||
// Copyright 2015, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
// IssuesService handles communication with the issue related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html
|
||||
type IssuesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Issue represents a GitLab issue.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html
|
||||
type Issue struct {
|
||||
ID int `json:"id"`
|
||||
IID int `json:"iid"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Labels []string `json:"labels"`
|
||||
Milestone *Milestone `json:"milestone"`
|
||||
Assignee struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
} `json:"assignee"`
|
||||
Author struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
} `json:"author"`
|
||||
State string `json:"state"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
Subscribed bool `json:"subscribed"`
|
||||
UserNotesCount int `json:"user_notes_count"`
|
||||
Confidential bool `json:"confidential"`
|
||||
DueDate string `json:"due_date"`
|
||||
WebURL string `json:"web_url"`
|
||||
}
|
||||
|
||||
func (i Issue) String() string {
|
||||
return Stringify(i)
|
||||
}
|
||||
|
||||
// Labels is a custom type with specific marshaling characteristics.
|
||||
type Labels []string
|
||||
|
||||
// MarshalJSON implements the json.Marshaler interface.
|
||||
func (l *Labels) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(strings.Join(*l, ","))
|
||||
}
|
||||
|
||||
// ListIssuesOptions represents the available ListIssues() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-issues
|
||||
type ListIssuesOptions struct {
|
||||
ListOptions
|
||||
State *string `url:"state,omitempty" json:"state,omitempty"`
|
||||
Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
|
||||
OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
|
||||
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
|
||||
}
|
||||
|
||||
// ListIssues gets all issues created by authenticated user. This function
|
||||
// takes pagination parameters page and per_page to restrict the list of issues.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-issues
|
||||
func (s *IssuesService) ListIssues(opt *ListIssuesOptions, options ...OptionFunc) ([]*Issue, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "issues", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var i []*Issue
|
||||
resp, err := s.client.Do(req, &i)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return i, resp, err
|
||||
}
|
||||
|
||||
// ListProjectIssuesOptions represents the available ListProjectIssues() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-issues
|
||||
type ListProjectIssuesOptions struct {
|
||||
ListOptions
|
||||
IID *int `url:"iid,omitempty" json:"iid,omitempty"`
|
||||
State *string `url:"state,omitempty" json:"state,omitempty"`
|
||||
Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
|
||||
Milestone *string `url:"milestone,omitempty" json:"milestone,omitempty"`
|
||||
OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
|
||||
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
|
||||
}
|
||||
|
||||
// ListProjectIssues gets a list of project issues. This function accepts
|
||||
// pagination parameters page and per_page to return the list of project issues.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#list-project-issues
|
||||
func (s *IssuesService) ListProjectIssues(pid interface{}, opt *ListProjectIssuesOptions, options ...OptionFunc) ([]*Issue, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var i []*Issue
|
||||
resp, err := s.client.Do(req, &i)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return i, resp, err
|
||||
}
|
||||
|
||||
// GetIssue gets a single project issue.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#single-issues
|
||||
func (s *IssuesService) GetIssue(pid interface{}, issue int, options ...OptionFunc) (*Issue, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d", url.QueryEscape(project), issue)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
i := new(Issue)
|
||||
resp, err := s.client.Do(req, i)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return i, resp, err
|
||||
}
|
||||
|
||||
// CreateIssueOptions represents the available CreateIssue() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#new-issues
|
||||
type CreateIssueOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
|
||||
MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"`
|
||||
Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
|
||||
}
|
||||
|
||||
// CreateIssue creates a new project issue.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#new-issues
|
||||
func (s *IssuesService) CreateIssue(pid interface{}, opt *CreateIssueOptions, options ...OptionFunc) (*Issue, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
i := new(Issue)
|
||||
resp, err := s.client.Do(req, i)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return i, resp, err
|
||||
}
|
||||
|
||||
// UpdateIssueOptions represents the available UpdateIssue() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#edit-issues
|
||||
type UpdateIssueOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
|
||||
MilestoneID *int `url:"milestone_id,omitempty" json:"milestone_id,omitempty"`
|
||||
Labels Labels `url:"labels,comma,omitempty" json:"labels,omitempty"`
|
||||
StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateIssue updates an existing project issue. This function is also used
|
||||
// to mark an issue as closed.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#edit-issues
|
||||
func (s *IssuesService) UpdateIssue(pid interface{}, issue int, opt *UpdateIssueOptions, options ...OptionFunc) (*Issue, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d", url.QueryEscape(project), issue)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
i := new(Issue)
|
||||
resp, err := s.client.Do(req, i)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return i, resp, err
|
||||
}
|
||||
|
||||
// DeleteIssue deletes a single project issue.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html#delete-an-issue
|
||||
func (s *IssuesService) DeleteIssue(pid interface{}, issue int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d", url.QueryEscape(project), issue)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
|
@ -0,0 +1,164 @@
|
|||
//
|
||||
// Copyright 2015, 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"
|
||||
)
|
||||
|
||||
// LabelsService handles communication with the label related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html
|
||||
type LabelsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Label represents a GitLab label.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html
|
||||
type Label struct {
|
||||
Name string `json:"name"`
|
||||
Color string `json:"color"`
|
||||
Description string `json:"description"`
|
||||
OpenIssuesCount int `json:"open_issues_count"`
|
||||
ClosedIssuesCount int `json:"closed_issues_count"`
|
||||
OpenMergeRequestsCount int `json:"open_merge_requests_count"`
|
||||
}
|
||||
|
||||
func (l Label) String() string {
|
||||
return Stringify(l)
|
||||
}
|
||||
|
||||
// ListLabels gets all labels for given project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#list-labels
|
||||
func (s *LabelsService) ListLabels(pid interface{}, options ...OptionFunc) ([]*Label, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/labels", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var l []*Label
|
||||
resp, err := s.client.Do(req, &l)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return l, resp, err
|
||||
}
|
||||
|
||||
// CreateLabelOptions represents the available CreateLabel() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#create-a-new-label
|
||||
type CreateLabelOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Color *string `url:"color,omitempty" json:"color,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// CreateLabel creates a new label for given repository with given name and
|
||||
// color.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#create-a-new-label
|
||||
func (s *LabelsService) CreateLabel(pid interface{}, opt *CreateLabelOptions, options ...OptionFunc) (*Label, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/labels", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
l := new(Label)
|
||||
resp, err := s.client.Do(req, l)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return l, resp, err
|
||||
}
|
||||
|
||||
// DeleteLabelOptions represents the available DeleteLabel() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#delete-a-label
|
||||
type DeleteLabelOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
}
|
||||
|
||||
// DeleteLabel deletes a label given by its name.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#delete-a-label
|
||||
func (s *LabelsService) DeleteLabel(pid interface{}, opt *DeleteLabelOptions, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/labels", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// UpdateLabelOptions represents the available UpdateLabel() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#delete-a-label
|
||||
type UpdateLabelOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
NewName *string `url:"new_name,omitempty" json:"new_name,omitempty"`
|
||||
Color *string `url:"color,omitempty" json:"color,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateLabel updates an existing label with new name or now color. At least
|
||||
// one parameter is required, to update the label.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/labels.html#edit-an-existing-label
|
||||
func (s *LabelsService) UpdateLabel(pid interface{}, opt *UpdateLabelOptions, options ...OptionFunc) (*Label, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/labels", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
l := new(Label)
|
||||
resp, err := s.client.Do(req, l)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return l, resp, err
|
||||
}
|
|
@ -0,0 +1,333 @@
|
|||
//
|
||||
// Copyright 2015, 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"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MergeRequestsService handles communication with the merge requests related
|
||||
// methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/merge_requests.html
|
||||
type MergeRequestsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// MergeRequest represents a GitLab merge request.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/merge_requests.html
|
||||
type MergeRequest struct {
|
||||
ID int `json:"id"`
|
||||
IID int `json:"iid"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
WorkInProgress bool `json:"work_in_progress"`
|
||||
State string `json:"state"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
TargetBranch string `json:"target_branch"`
|
||||
SourceBranch string `json:"source_branch"`
|
||||
Upvotes int `json:"upvotes"`
|
||||
Downvotes int `json:"downvotes"`
|
||||
Author struct {
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
ID int `json:"id"`
|
||||
State string `json:"state"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
} `json:"author"`
|
||||
Assignee struct {
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
ID int `json:"id"`
|
||||
State string `json:"state"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
} `json:"assignee"`
|
||||
SourceProjectID int `json:"source_project_id"`
|
||||
TargetProjectID int `json:"target_project_id"`
|
||||
Labels []string `json:"labels"`
|
||||
Milestone struct {
|
||||
ID int `json:"id"`
|
||||
Iid int `json:"iid"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
State string `json:"state"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
DueDate string `json:"due_date"`
|
||||
} `json:"milestone"`
|
||||
MergeWhenBuildSucceeds bool `json:"merge_when_build_succeeds"`
|
||||
MergeStatus string `json:"merge_status"`
|
||||
Subscribed bool `json:"subscribed"`
|
||||
UserNotesCount int `json:"user_notes_count"`
|
||||
SouldRemoveSourceBranch bool `json:"should_remove_source_branch"`
|
||||
ForceRemoveSourceBranch bool `json:"force_remove_source_branch"`
|
||||
Changes []struct {
|
||||
OldPath string `json:"old_path"`
|
||||
NewPath string `json:"new_path"`
|
||||
AMode string `json:"a_mode"`
|
||||
BMode string `json:"b_mode"`
|
||||
Diff string `json:"diff"`
|
||||
NewFile bool `json:"new_file"`
|
||||
RenamedFile bool `json:"renamed_file"`
|
||||
DeletedFile bool `json:"deleted_file"`
|
||||
} `json:"changes"`
|
||||
WebURL string `json:"web_url"`
|
||||
}
|
||||
|
||||
func (m MergeRequest) String() string {
|
||||
return Stringify(m)
|
||||
}
|
||||
|
||||
// ListMergeRequestsOptions represents the available ListMergeRequests()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/merge_requests.html#list-merge-requests
|
||||
type ListMergeRequestsOptions struct {
|
||||
ListOptions
|
||||
IID *int `url:"iid,omitempty" json:"iid,omitempty"`
|
||||
State *string `url:"state,omitempty" json:"state,omitempty"`
|
||||
OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
|
||||
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
|
||||
}
|
||||
|
||||
// ListMergeRequests gets all merge requests for this project. The state
|
||||
// parameter can be used to get only merge requests with a given state (opened,
|
||||
// closed, or merged) or all of them (all). The pagination parameters page and
|
||||
// per_page can be used to restrict the list of merge requests.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/merge_requests.html#list-merge-requests
|
||||
func (s *MergeRequestsService) ListMergeRequests(pid interface{}, opt *ListMergeRequestsOptions, options ...OptionFunc) ([]*MergeRequest, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/merge_requests", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var m []*MergeRequest
|
||||
resp, err := s.client.Do(req, &m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// GetMergeRequest shows information about a single merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/merge_requests.html#get-single-mr
|
||||
func (s *MergeRequestsService) GetMergeRequest(pid interface{}, mergeRequest int, options ...OptionFunc) (*MergeRequest, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/merge_requests/%d", url.QueryEscape(project), mergeRequest)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(MergeRequest)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// GetMergeRequestCommits gets a list of merge request commits.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/merge_requests.html#get-single-mr-commits
|
||||
func (s *MergeRequestsService) GetMergeRequestCommits(pid interface{}, mergeRequest int, options ...OptionFunc) ([]*Commit, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/merge_requests/%d/commits", url.QueryEscape(project), mergeRequest)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var c []*Commit
|
||||
resp, err := s.client.Do(req, &c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// GetMergeRequestChanges shows information about the merge request including
|
||||
// its files and changes.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/merge_requests.html#get-single-mr-changes
|
||||
func (s *MergeRequestsService) GetMergeRequestChanges(pid interface{}, mergeRequest int, options ...OptionFunc) (*MergeRequest, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/merge_requests/%d/changes", url.QueryEscape(project), mergeRequest)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(MergeRequest)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// CreateMergeRequestOptions represents the available CreateMergeRequest()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/merge_requests.html#create-mr
|
||||
type CreateMergeRequestOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
SourceBranch *string `url:"source_branch,omitemtpy" json:"source_branch,omitemtpy"`
|
||||
TargetBranch *string `url:"target_branch,omitemtpy" json:"target_branch,omitemtpy"`
|
||||
AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
|
||||
TargetProjectID *int `url:"target_project_id,omitempty" json:"target_project_id,omitempty"`
|
||||
}
|
||||
|
||||
// CreateMergeRequest creates a new merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/merge_requests.html#create-mr
|
||||
func (s *MergeRequestsService) CreateMergeRequest(pid interface{}, opt *CreateMergeRequestOptions, options ...OptionFunc) (*MergeRequest, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/merge_requests", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(MergeRequest)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// UpdateMergeRequestOptions represents the available UpdateMergeRequest()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/merge_requests.html#update-mr
|
||||
type UpdateMergeRequestOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
TargetBranch *string `url:"target_branch,omitemtpy" json:"target_branch,omitemtpy"`
|
||||
AssigneeID *int `url:"assignee_id,omitempty" json:"assignee_id,omitempty"`
|
||||
StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateMergeRequest updates an existing project milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/merge_requests.html#update-mr
|
||||
func (s *MergeRequestsService) UpdateMergeRequest(pid interface{}, mergeRequest int, opt *UpdateMergeRequestOptions, options ...OptionFunc) (*MergeRequest, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/merge_requests/%d", url.QueryEscape(project), mergeRequest)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(MergeRequest)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// AcceptMergeRequestOptions represents the available AcceptMergeRequest()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/merge_requests.html#accept-mr
|
||||
type AcceptMergeRequestOptions struct {
|
||||
MergeCommitMessage *string `url:"merge_commit_message,omitempty" json:"merge_commit_message,omitempty"`
|
||||
ShouldRemoveSourceBranch *bool `url:"should_remove_source_branch,omitempty" json:"should_remove_source_branch,omitempty"`
|
||||
MergeWhenBuildSucceeds *bool `url:"merge_when_build_succeeds,omitempty" json:"merge_when_build_succeeds,omitempty"`
|
||||
Sha *string `url:"sha,omitempty" json:"sha,omitempty"`
|
||||
}
|
||||
|
||||
// AcceptMergeRequest merges changes submitted with MR using this API. If merge
|
||||
// success you get 200 OK. If it has some conflicts and can not be merged - you
|
||||
// get 405 and error message 'Branch cannot be merged'. If merge request is
|
||||
// already merged or closed - you get 405 and error message 'Method Not Allowed'
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/merge_requests.html#accept-mr
|
||||
func (s *MergeRequestsService) AcceptMergeRequest(pid interface{}, mergeRequest int, opt *AcceptMergeRequestOptions, options ...OptionFunc) (*MergeRequest, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/merge_requests/%d/merge", url.QueryEscape(project), mergeRequest)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(MergeRequest)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
|
@ -0,0 +1,216 @@
|
|||
//
|
||||
// Copyright 2015, 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"
|
||||
"time"
|
||||
)
|
||||
|
||||
// MilestonesService handles communication with the milestone related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/milestones.html
|
||||
type MilestonesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Milestone represents a GitLab milestone.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/milestones.html
|
||||
type Milestone struct {
|
||||
ID int `json:"id"`
|
||||
Iid int `json:"iid"`
|
||||
ProjectID int `json:"project_id"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
StartDate string `json:"start_date"`
|
||||
DueDate string `json:"due_date"`
|
||||
State string `json:"state"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func (m Milestone) String() string {
|
||||
return Stringify(m)
|
||||
}
|
||||
|
||||
// ListMilestonesOptions represents the available ListMilestones() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#list-project-milestones
|
||||
type ListMilestonesOptions struct {
|
||||
ListOptions
|
||||
IID *int `url:"iid,omitempty" json:"iid,omitempty"`
|
||||
}
|
||||
|
||||
// ListMilestones returns a list of project milestones.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#list-project-milestones
|
||||
func (s *MilestonesService) ListMilestones(pid interface{}, opt *ListMilestonesOptions, options ...OptionFunc) ([]*Milestone, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/milestones", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var m []*Milestone
|
||||
resp, err := s.client.Do(req, &m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// GetMilestone gets a single project milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#get-single-milestone
|
||||
func (s *MilestonesService) GetMilestone(pid interface{}, milestone int, options ...OptionFunc) (*Milestone, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/milestones/%d", url.QueryEscape(project), milestone)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(Milestone)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// CreateMilestoneOptions represents the available CreateMilestone() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#create-new-milestone
|
||||
type CreateMilestoneOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
StartDate *string `url:"start_date,omitempty" json:"start_date,omitempty"`
|
||||
DueDate *string `url:"due_date,omitempty" json:"due_date,omitempty"`
|
||||
}
|
||||
|
||||
// CreateMilestone creates a new project milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#create-new-milestone
|
||||
func (s *MilestonesService) CreateMilestone(pid interface{}, opt *CreateMilestoneOptions, options ...OptionFunc) (*Milestone, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/milestones", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(Milestone)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// UpdateMilestoneOptions represents the available UpdateMilestone() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#edit-milestone
|
||||
type UpdateMilestoneOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
StartDate *string `url:"start_date,omitempty" json:"start_date,omitempty"`
|
||||
DueDate *string `url:"due_date,omitempty" json:"due_date,omitempty"`
|
||||
StateEvent *string `url:"state_event,omitempty" json:"state_event,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateMilestone updates an existing project milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#edit-milestone
|
||||
func (s *MilestonesService) UpdateMilestone(pid interface{}, milestone int, opt *UpdateMilestoneOptions, options ...OptionFunc) (*Milestone, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/milestones/%d", url.QueryEscape(project), milestone)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
m := new(Milestone)
|
||||
resp, err := s.client.Do(req, m)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return m, resp, err
|
||||
}
|
||||
|
||||
// GetMilestoneIssuesOptions represents the available GetMilestoneIssues() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#get-all-issues-assigned-to-a-single-milestone
|
||||
type GetMilestoneIssuesOptions struct {
|
||||
ListOptions
|
||||
}
|
||||
|
||||
// GetMilestoneIssues gets all issues assigned to a single project milestone.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/milestones.html#get-all-issues-assigned-to-a-single-milestone
|
||||
func (s *MilestonesService) GetMilestoneIssues(pid interface{}, milestone int, opt *GetMilestoneIssuesOptions, options ...OptionFunc) ([]*Issue, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/milestones/%d/issues", url.QueryEscape(project), milestone)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var i []*Issue
|
||||
resp, err := s.client.Do(req, &i)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return i, resp, err
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
//
|
||||
// Copyright 2015, 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
|
||||
|
||||
// NamespacesService handles communication with the namespace related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/namespaces.html
|
||||
type NamespacesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Namespace represents a GitLab namespace.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/namespaces.html
|
||||
type Namespace struct {
|
||||
ID int `json:"id"`
|
||||
Path string `json:"path"`
|
||||
Kind string `json:"kind"`
|
||||
}
|
||||
|
||||
func (n Namespace) String() string {
|
||||
return Stringify(n)
|
||||
}
|
||||
|
||||
// ListNamespacesOptions represents the available ListNamespaces() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/namespaces.html#list-namespaces
|
||||
type ListNamespacesOptions struct {
|
||||
ListOptions
|
||||
Search *string `url:"search,omitempty" json:"search,omitempty"`
|
||||
}
|
||||
|
||||
// ListNamespaces gets a list of projects accessible by the authenticated user.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/namespaces.html#list-namespaces
|
||||
func (s *NamespacesService) ListNamespaces(opt *ListNamespacesOptions, options ...OptionFunc) ([]*Namespace, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "namespaces", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var n []*Namespace
|
||||
resp, err := s.client.Do(req, &n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// SearchNamespace gets all namespaces that match your string in their name
|
||||
// or path.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/namespaces.html#search-for-namespace
|
||||
func (s *NamespacesService) SearchNamespace(query string, options ...OptionFunc) ([]*Namespace, *Response, error) {
|
||||
var q struct {
|
||||
Search string `url:"search,omitempty" json:"search,omitempty"`
|
||||
}
|
||||
q.Search = query
|
||||
|
||||
req, err := s.client.NewRequest("GET", "namespaces", &q, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var n []*Namespace
|
||||
resp, err := s.client.Do(req, &n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
|
@ -0,0 +1,418 @@
|
|||
//
|
||||
// Copyright 2015, 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"
|
||||
"time"
|
||||
)
|
||||
|
||||
// NotesService handles communication with the notes related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/notes.html
|
||||
type NotesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Note represents a GitLab note.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/notes.html
|
||||
type Note struct {
|
||||
ID int `json:"id"`
|
||||
Body string `json:"body"`
|
||||
Attachment string `json:"attachment"`
|
||||
Title string `json:"title"`
|
||||
FileName string `json:"file_name"`
|
||||
Author struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
} `json:"author"`
|
||||
ExpiresAt *time.Time `json:"expires_at"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func (n Note) String() string {
|
||||
return Stringify(n)
|
||||
}
|
||||
|
||||
// ListIssueNotesOptions represents the available ListIssueNotes() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#list-project-issue-notes
|
||||
type ListIssueNotesOptions struct {
|
||||
ListOptions
|
||||
}
|
||||
|
||||
// ListIssueNotes gets a list of all notes for a single issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#list-project-issue-notes
|
||||
func (s *NotesService) ListIssueNotes(pid interface{}, issue int, opt *ListIssueNotesOptions, options ...OptionFunc) ([]*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d/notes", url.QueryEscape(project), issue)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var n []*Note
|
||||
resp, err := s.client.Do(req, &n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// GetIssueNote returns a single note for a specific project issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#get-single-issue-note
|
||||
func (s *NotesService) GetIssueNote(pid interface{}, issue int, note int, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d/notes/%d", url.QueryEscape(project), issue, note)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// CreateIssueNoteOptions represents the available CreateIssueNote()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#create-new-issue-note
|
||||
type CreateIssueNoteOptions struct {
|
||||
Body *string `url:"body,omitempty" json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// CreateIssueNote creates a new note to a single project issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#create-new-issue-note
|
||||
func (s *NotesService) CreateIssueNote(pid interface{}, issue int, opt *CreateIssueNoteOptions, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d/notes", url.QueryEscape(project), issue)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// UpdateIssueNoteOptions represents the available UpdateIssueNote()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#modify-existing-issue-note
|
||||
type UpdateIssueNoteOptions struct {
|
||||
Body *string `url:"body,omitempty" json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateIssueNote modifies existing note of an issue.
|
||||
//
|
||||
// https://docs.gitlab.com/ce/api/notes.html#modify-existing-issue-note
|
||||
func (s *NotesService) UpdateIssueNote(pid interface{}, issue int, note int, opt *UpdateIssueNoteOptions, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d/notes/%d", url.QueryEscape(project), issue, note)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// ListSnippetNotes gets a list of all notes for a single snippet. Snippet
|
||||
// notes are comments users can post to a snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#list-all-snippet-notes
|
||||
func (s *NotesService) ListSnippetNotes(pid interface{}, snippet int, options ...OptionFunc) ([]*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets/%d/notes", url.QueryEscape(project), snippet)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var n []*Note
|
||||
resp, err := s.client.Do(req, &n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// GetSnippetNote returns a single note for a given snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#get-single-snippet-note
|
||||
func (s *NotesService) GetSnippetNote(pid interface{}, snippet int, note int, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets/%d/notes/%d", url.QueryEscape(project), snippet, note)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// CreateSnippetNoteOptions represents the available CreateSnippetNote()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#create-new-snippet-note
|
||||
type CreateSnippetNoteOptions struct {
|
||||
Body *string `url:"body,omitempty" json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// CreateSnippetNote creates a new note for a single snippet. Snippet notes are
|
||||
// comments users can post to a snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#create-new-snippet-note
|
||||
func (s *NotesService) CreateSnippetNote(pid interface{}, snippet int, opt *CreateSnippetNoteOptions, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets/%d/notes", url.QueryEscape(project), snippet)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// UpdateSnippetNoteOptions represents the available UpdateSnippetNote()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#modify-existing-snippet-note
|
||||
type UpdateSnippetNoteOptions struct {
|
||||
Body *string `url:"body,omitempty" json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateSnippetNote modifies existing note of a snippet.
|
||||
//
|
||||
// https://docs.gitlab.com/ce/api/notes.html#modify-existing-snippet-note
|
||||
func (s *NotesService) UpdateSnippetNote(pid interface{}, snippet int, note int, opt *UpdateSnippetNoteOptions, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets/%d/notes/%d", url.QueryEscape(project), snippet, note)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// ListMergeRequestNotes gets a list of all notes for a single merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#list-all-merge-request-notes
|
||||
func (s *NotesService) ListMergeRequestNotes(pid interface{}, mergeRequest int, options ...OptionFunc) ([]*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/merge_requests/%d/notes", url.QueryEscape(project), mergeRequest)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var n []*Note
|
||||
resp, err := s.client.Do(req, &n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// GetMergeRequestNote returns a single note for a given merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#get-single-merge-request-note
|
||||
func (s *NotesService) GetMergeRequestNote(pid interface{}, mergeRequest int, note int, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/merge_requests/%d/notes/%d", url.QueryEscape(project), mergeRequest, note)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// CreateMergeRequestNoteOptions represents the available
|
||||
// CreateMergeRequestNote() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#create-new-merge-request-note
|
||||
type CreateMergeRequestNoteOptions struct {
|
||||
Body *string `url:"body,omitempty" json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// CreateMergeRequestNote creates a new note for a single merge request.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#create-new-merge-request-note
|
||||
func (s *NotesService) CreateMergeRequestNote(pid interface{}, mergeRequest int, opt *CreateMergeRequestNoteOptions, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/merge_requests/%d/notes", url.QueryEscape(project), mergeRequest)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
||||
|
||||
// UpdateMergeRequestNoteOptions represents the available
|
||||
// UpdateMergeRequestNote() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notes.html#modify-existing-merge-request-note
|
||||
type UpdateMergeRequestNoteOptions struct {
|
||||
Body *string `url:"body,omitempty" json:"body,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateMergeRequestNote modifies existing note of a merge request.
|
||||
//
|
||||
// https://docs.gitlab.com/ce/api/notes.html#modify-existing-merge-request-note
|
||||
func (s *NotesService) UpdateMergeRequestNote(pid interface{}, mergeRequest int, note int, opt *UpdateMergeRequestNoteOptions, options ...OptionFunc) (*Note, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf(
|
||||
"projects/%s/merge_requests/%d/notes/%d", url.QueryEscape(project), mergeRequest, note)
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
n := new(Note)
|
||||
resp, err := s.client.Do(req, n)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return n, resp, err
|
||||
}
|
|
@ -0,0 +1,214 @@
|
|||
package gitlab
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// NotificationSettingsService handles communication with the notification settings
|
||||
// related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/notification_settings.html
|
||||
type NotificationSettingsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// NotificationSettings represents the Gitlab notification setting.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notification_settings.html#notification-settings
|
||||
type NotificationSettings struct {
|
||||
Level NotificationLevelValue `json:"level"`
|
||||
NotificationEmail string `json:"notification_email"`
|
||||
Events *NotificationEvents `json:"events"`
|
||||
}
|
||||
|
||||
// NotificationEvents represents the avialable notification setting events.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notification_settings.html#notification-settings
|
||||
type NotificationEvents struct {
|
||||
CloseIssue bool `json:"close_issue"`
|
||||
CloseMergeRequest bool `json:"close_merge_request"`
|
||||
FailedPipeline bool `json:"failed_pipeline"`
|
||||
MergeMergeRequest bool `json:"merge_merge_request"`
|
||||
NewIssue bool `json:"new_issue"`
|
||||
NewMergeRequest bool `json:"new_merge_request"`
|
||||
NewNote bool `json:"new_note"`
|
||||
ReassignIssue bool `json:"reassign_issue"`
|
||||
ReassignMergeRequest bool `json:"reassign_merge_request"`
|
||||
ReopenIssue bool `json:"reopen_issue"`
|
||||
ReopenMergeRequest bool `json:"reopen_merge_request"`
|
||||
SuccessPipeline bool `json:"success_pipeline"`
|
||||
}
|
||||
|
||||
func (ns NotificationSettings) String() string {
|
||||
return Stringify(ns)
|
||||
}
|
||||
|
||||
// GetGlobalSettings returns current notification settings and email address.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notification_settings.html#global-notification-settings
|
||||
func (s *NotificationSettingsService) GetGlobalSettings(options ...OptionFunc) (*NotificationSettings, *Response, error) {
|
||||
u := "notification_settings"
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ns := new(NotificationSettings)
|
||||
resp, err := s.client.Do(req, ns)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ns, resp, err
|
||||
}
|
||||
|
||||
// NotificationSettingsOptions represents the available options that can be passed
|
||||
// to the API when updating the notification settings.
|
||||
type NotificationSettingsOptions struct {
|
||||
Level *NotificationLevelValue `url:"level,omitempty" json:"level,omitempty"`
|
||||
NotificationEmail *string `url:"notification_email,omitempty" json:"notification_email,omitempty"`
|
||||
CloseIssue *bool `url:"close_issue,omitempty" json:"close_issue,omitempty"`
|
||||
CloseMergeRequest *bool `url:"close_merge_request,omitempty" json:"close_merge_request,omitempty"`
|
||||
FailedPipeline *bool `url:"failed_pipeline,omitempty" json:"failed_pipeline,omitempty"`
|
||||
MergeMergeRequest *bool `url:"merge_merge_request,omitempty" json:"merge_merge_request,omitempty"`
|
||||
NewIssue *bool `url:"new_issue,omitempty" json:"new_issue,omitempty"`
|
||||
NewMergeRequest *bool `url:"new_merge_request,omitempty" json:"new_merge_request,omitempty"`
|
||||
NewNote *bool `url:"new_note,omitempty" json:"new_note,omitempty"`
|
||||
ReassignIssue *bool `url:"reassign_issue,omitempty" json:"reassign_issue,omitempty"`
|
||||
ReassignMergeRequest *bool `url:"reassign_merge_request,omitempty" json:"reassign_merge_request,omitempty"`
|
||||
ReopenIssue *bool `url:"reopen_issue,omitempty" json:"reopen_issue,omitempty"`
|
||||
ReopenMergeRequest *bool `url:"reopen_merge_request,omitempty" json:"reopen_merge_request,omitempty"`
|
||||
SuccessPipeline *bool `url:"success_pipeline,omitempty" json:"success_pipeline,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateGlobalSettings updates current notification settings and email address.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notification_settings.html#update-global-notification-settings
|
||||
func (s *NotificationSettingsService) UpdateGlobalSettings(opt *NotificationSettingsOptions, options ...OptionFunc) (*NotificationSettings, *Response, error) {
|
||||
if opt.Level != nil && *opt.Level == GlobalNotificationLevel {
|
||||
return nil, nil, errors.New(
|
||||
"notification level 'global' is not valid for global notification settings")
|
||||
}
|
||||
|
||||
u := "notification_settings"
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ns := new(NotificationSettings)
|
||||
resp, err := s.client.Do(req, ns)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ns, resp, err
|
||||
}
|
||||
|
||||
// GetSettingsForGroup returns current group notification settings.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notification_settings.html#group-project-level-notification-settings
|
||||
func (s *NotificationSettingsService) GetSettingsForGroup(gid interface{}, options ...OptionFunc) (*NotificationSettings, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/notification_settings", url.QueryEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ns := new(NotificationSettings)
|
||||
resp, err := s.client.Do(req, ns)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ns, resp, err
|
||||
}
|
||||
|
||||
// GetSettingsForProject returns current project notification settings.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notification_settings.html#group-project-level-notification-settings
|
||||
func (s *NotificationSettingsService) GetSettingsForProject(pid interface{}, options ...OptionFunc) (*NotificationSettings, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/notification_settings", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ns := new(NotificationSettings)
|
||||
resp, err := s.client.Do(req, ns)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ns, resp, err
|
||||
}
|
||||
|
||||
// UpdateSettingsForGroup updates current group notification settings.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notification_settings.html#update-group-project-level-notification-settings
|
||||
func (s *NotificationSettingsService) UpdateSettingsForGroup(gid interface{}, opt *NotificationSettingsOptions, options ...OptionFunc) (*NotificationSettings, *Response, error) {
|
||||
group, err := parseID(gid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("groups/%s/notification_settings", url.QueryEscape(group))
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ns := new(NotificationSettings)
|
||||
resp, err := s.client.Do(req, ns)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ns, resp, err
|
||||
}
|
||||
|
||||
// UpdateSettingsForProject updates current project notification settings.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/notification_settings.html#update-group-project-level-notification-settings
|
||||
func (s *NotificationSettingsService) UpdateSettingsForProject(pid interface{}, opt *NotificationSettingsOptions, options ...OptionFunc) (*NotificationSettings, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/notification_settings", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ns := new(NotificationSettings)
|
||||
resp, err := s.client.Do(req, ns)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ns, resp, err
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
//
|
||||
// Copyright 2017, Igor Varavko
|
||||
//
|
||||
// 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"
|
||||
"time"
|
||||
)
|
||||
|
||||
// PipelinesService handles communication with the repositories related
|
||||
// methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html
|
||||
type PipelinesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Pipeline represents a GitLab pipeline.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html
|
||||
type Pipeline struct {
|
||||
ID int `json:"id"`
|
||||
Status string `json:"status"`
|
||||
Ref string `json:"ref"`
|
||||
Sha string `json:"sha"`
|
||||
BeforeSha string `json:"before_sha"`
|
||||
Tag bool `json:"tag"`
|
||||
YamlErrors string `json:"yaml_errors"`
|
||||
User struct {
|
||||
Name string `json:"name"`
|
||||
Username string `json:"username"`
|
||||
ID int `json:"id"`
|
||||
State string `json:"state"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
WebURL string `json:"web_url"`
|
||||
}
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
StartedAt *time.Time `json:"started_at"`
|
||||
FinishedAt *time.Time `json:"finished_at"`
|
||||
CommittedAt *time.Time `json:"committed_at"`
|
||||
Duration int `json:"duration"`
|
||||
Coverage string `json:"coverage"`
|
||||
}
|
||||
|
||||
func (i Pipeline) String() string {
|
||||
return Stringify(i)
|
||||
}
|
||||
|
||||
// ListProjectPipelines gets a list of project piplines.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#list-project-pipelines
|
||||
func (s *PipelinesService) ListProjectPipelines(pid interface{}, options ...OptionFunc) ([]*Pipeline, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipelines", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var p []*Pipeline
|
||||
resp, err := s.client.Do(req, &p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// GetPipeline gets a single project pipeline.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#get-a-single-pipeline
|
||||
func (s *PipelinesService) GetPipeline(pid interface{}, pipeline int, options ...OptionFunc) (*Pipeline, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipelines/%d", url.QueryEscape(project), pipeline)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(Pipeline)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// CreatePipelineOptions represents the available CreatePipeline() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#create-a-new-pipeline
|
||||
type CreatePipelineOptions struct {
|
||||
Ref *string `url:"ref,omitempty" json:"ref"`
|
||||
}
|
||||
|
||||
// CreatePipeline creates a new project pipeline.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/pipelines.html#create-a-new-pipeline
|
||||
func (s *PipelinesService) CreatePipeline(pid interface{}, opt *CreatePipelineOptions, options ...OptionFunc) (*Pipeline, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipeline", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(Pipeline)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// RetryPipelineBuild retries failed builds in a pipeline
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/pipelines.html#retry-failed-builds-in-a-pipeline
|
||||
func (s *PipelinesService) RetryPipelineBuild(pid interface{}, pipelineID int, options ...OptionFunc) (*Pipeline, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipelines/%d/retry", project, pipelineID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(Pipeline)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// CancelPipelineBuild cancels a pipeline builds
|
||||
//
|
||||
// GitLab API docs:
|
||||
//https://docs.gitlab.com/ce/api/pipelines.html#cancel-a-pipelines-builds
|
||||
func (s *PipelinesService) CancelPipelineBuild(pid interface{}, pipelineID int, options ...OptionFunc) (*Pipeline, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/pipelines/%d/cancel", project, pipelineID)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(Pipeline)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
|
@ -0,0 +1,232 @@
|
|||
//
|
||||
// Copyright 2015, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ProjectSnippetsService handles communication with the project snippets
|
||||
// related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/project_snippets.html
|
||||
type ProjectSnippetsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Snippet represents a GitLab project snippet.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/project_snippets.html
|
||||
type Snippet struct {
|
||||
ID int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
FileName string `json:"file_name"`
|
||||
Author struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
} `json:"author"`
|
||||
ExpiresAt *time.Time `json:"expires_at"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func (s Snippet) String() string {
|
||||
return Stringify(s)
|
||||
}
|
||||
|
||||
// ListSnippetsOptions represents the available ListSnippets() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/project_snippets.html#list-snippets
|
||||
type ListSnippetsOptions struct {
|
||||
ListOptions
|
||||
}
|
||||
|
||||
// ListSnippets gets a list of project snippets.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/project_snippets.html#list-snippets
|
||||
func (s *ProjectSnippetsService) ListSnippets(pid interface{}, opt *ListSnippetsOptions, options ...OptionFunc) ([]*Snippet, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ps []*Snippet
|
||||
resp, err := s.client.Do(req, &ps)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ps, resp, err
|
||||
}
|
||||
|
||||
// GetSnippet gets a single project snippet
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/project_snippets.html#single-snippet
|
||||
func (s *ProjectSnippetsService) GetSnippet(pid interface{}, snippet int, options ...OptionFunc) (*Snippet, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets/%d", url.QueryEscape(project), snippet)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ps := new(Snippet)
|
||||
resp, err := s.client.Do(req, ps)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ps, resp, err
|
||||
}
|
||||
|
||||
// CreateSnippetOptions represents the available CreateSnippet() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/project_snippets.html#create-new-snippet
|
||||
type CreateSnippetOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
FileName *string `url:"file_name,omitempty" json:"file_name,omitempty"`
|
||||
Code *string `url:"code,omitempty" json:"code,omitempty"`
|
||||
VisibilityLevel *VisibilityLevelValue `url:"visibility_level,omitempty" json:"visibility_level,omitempty"`
|
||||
}
|
||||
|
||||
// CreateSnippet creates a new project snippet. The user must have permission
|
||||
// to create new snippets.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/project_snippets.html#create-new-snippet
|
||||
func (s *ProjectSnippetsService) CreateSnippet(pid interface{}, opt *CreateSnippetOptions, options ...OptionFunc) (*Snippet, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ps := new(Snippet)
|
||||
resp, err := s.client.Do(req, ps)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ps, resp, err
|
||||
}
|
||||
|
||||
// UpdateSnippetOptions represents the available UpdateSnippet() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/project_snippets.html#update-snippet
|
||||
type UpdateSnippetOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
FileName *string `url:"file_name,omitempty" json:"file_name,omitempty"`
|
||||
Code *string `url:"code,omitempty" json:"code,omitempty"`
|
||||
VisibilityLevel *VisibilityLevelValue `url:"visibility_level,omitempty" json:"visibility_level,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateSnippet updates an existing project snippet. The user must have
|
||||
// permission to change an existing snippet.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/project_snippets.html#update-snippet
|
||||
func (s *ProjectSnippetsService) UpdateSnippet(pid interface{}, snippet int, opt *UpdateSnippetOptions, options ...OptionFunc) (*Snippet, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets/%d", url.QueryEscape(project), snippet)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ps := new(Snippet)
|
||||
resp, err := s.client.Do(req, ps)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ps, resp, err
|
||||
}
|
||||
|
||||
// DeleteSnippet deletes an existing project snippet. This is an idempotent
|
||||
// function and deleting a non-existent snippet still returns a 200 OK status
|
||||
// code.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/project_snippets.html#delete-snippet
|
||||
func (s *ProjectSnippetsService) DeleteSnippet(pid interface{}, snippet int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets/%d", url.QueryEscape(project), snippet)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// SnippetContent returns the raw project snippet as plain text.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/project_snippets.html#snippet-content
|
||||
func (s *ProjectSnippetsService) SnippetContent(pid interface{}, snippet int, options ...OptionFunc) ([]byte, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/snippets/%d/raw", url.QueryEscape(project), snippet)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var b bytes.Buffer
|
||||
resp, err := s.client.Do(req, &b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b.Bytes(), resp, err
|
||||
}
|
|
@ -0,0 +1,981 @@
|
|||
//
|
||||
// Copyright 2015, 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"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ProjectsService handles communication with the repositories related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html
|
||||
type ProjectsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Project represents a GitLab project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html
|
||||
type Project struct {
|
||||
ID int `json:"id"`
|
||||
Description string `json:"description"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Public bool `json:"public"`
|
||||
VisibilityLevel VisibilityLevelValue `json:"visibility_level"`
|
||||
SSHURLToRepo string `json:"ssh_url_to_repo"`
|
||||
HTTPURLToRepo string `json:"http_url_to_repo"`
|
||||
WebURL string `json:"web_url"`
|
||||
TagList []string `json:"tag_list"`
|
||||
Owner *User `json:"owner"`
|
||||
Name string `json:"name"`
|
||||
NameWithNamespace string `json:"name_with_namespace"`
|
||||
Path string `json:"path"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
IssuesEnabled bool `json:"issues_enabled"`
|
||||
OpenIssuesCount int `json:"open_issues_count"`
|
||||
MergeRequestsEnabled bool `json:"merge_requests_enabled"`
|
||||
ApprovalsBeforeMerge int `json:"approvals_before_merge"`
|
||||
BuildsEnabled bool `json:"builds_enabled"`
|
||||
WikiEnabled bool `json:"wiki_enabled"`
|
||||
SnippetsEnabled bool `json:"snippets_enabled"`
|
||||
ContainerRegistryEnabled bool `json:"container_registry_enabled"`
|
||||
CreatedAt *time.Time `json:"created_at,omitempty"`
|
||||
LastActivityAt *time.Time `json:"last_activity_at,omitempty"`
|
||||
CreatorID int `json:"creator_id"`
|
||||
Namespace *ProjectNamespace `json:"namespace"`
|
||||
Permissions *Permissions `json:"permissions"`
|
||||
Archived bool `json:"archived"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
SharedRunnersEnabled bool `json:"shared_runners_enabled"`
|
||||
ForksCount int `json:"forks_count"`
|
||||
StarCount int `json:"star_count"`
|
||||
RunnersToken string `json:"runners_token"`
|
||||
PublicBuilds bool `json:"public_builds"`
|
||||
OnlyAllowMergeIfBuildSucceeds bool `json:"only_allow_merge_if_build_succeeds"`
|
||||
OnlyAllowMergeIfAllDiscussionsAreResolved bool `json:"only_allow_merge_if_all_discussions_are_resolved"`
|
||||
LFSEnabled bool `json:"lfs_enabled"`
|
||||
RequestAccessEnabled bool `json:"request_access_enabled"`
|
||||
SharedWithGroups []struct {
|
||||
GroupID int `json:"group_id"`
|
||||
GroupName string `json:"group_name"`
|
||||
GroupAccessLevel int `json:"group_access_level"`
|
||||
} `json:"shared_with_groups"`
|
||||
Statistics *ProjectStatistics `json:"statistics"`
|
||||
}
|
||||
|
||||
// Repository represents a repository.
|
||||
type Repository struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
WebURL string `json:"web_url"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
GitSSHURL string `json:"git_ssh_url"`
|
||||
GitHTTPURL string `json:"git_http_url"`
|
||||
Namespace string `json:"namespace"`
|
||||
VisibilityLevel int `json:"visibility_level"`
|
||||
PathWithNamespace string `json:"path_with_namespace"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
Homepage string `json:"homepage"`
|
||||
URL string `json:"url"`
|
||||
SSHURL string `json:"ssh_url"`
|
||||
HTTPURL string `json:"http_url"`
|
||||
}
|
||||
|
||||
// ProjectNamespace represents a project namespace.
|
||||
type ProjectNamespace struct {
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
Description string `json:"description"`
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
OwnerID int `json:"owner_id"`
|
||||
Path string `json:"path"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// StorageStatistics represents a statistics record for a group or project.
|
||||
type StorageStatistics struct {
|
||||
StorageSize int64 `json:"storage_size"`
|
||||
RepositorySize int64 `json:"repository_size"`
|
||||
LfsObjectsSize int64 `json:"lfs_objects_size"`
|
||||
BuildArtifactsSize int64 `json:"build_artifacts_size"`
|
||||
}
|
||||
|
||||
// ProjectStatistics represents a statistics record for a project.
|
||||
type ProjectStatistics struct {
|
||||
StorageStatistics
|
||||
CommitCount int `json:"commit_count"`
|
||||
}
|
||||
|
||||
// Permissions represents premissions.
|
||||
type Permissions struct {
|
||||
ProjectAccess *ProjectAccess `json:"project_access"`
|
||||
GroupAccess *GroupAccess `json:"group_access"`
|
||||
}
|
||||
|
||||
// ProjectAccess represents project access.
|
||||
type ProjectAccess struct {
|
||||
AccessLevel AccessLevelValue `json:"access_level"`
|
||||
NotificationLevel NotificationLevelValue `json:"notification_level"`
|
||||
}
|
||||
|
||||
// GroupAccess represents group access.
|
||||
type GroupAccess struct {
|
||||
AccessLevel AccessLevelValue `json:"access_level"`
|
||||
NotificationLevel NotificationLevelValue `json:"notification_level"`
|
||||
}
|
||||
|
||||
func (s Project) String() string {
|
||||
return Stringify(s)
|
||||
}
|
||||
|
||||
// ListProjectsOptions represents the available ListProjects() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#list-projects
|
||||
type ListProjectsOptions struct {
|
||||
ListOptions
|
||||
Archived *bool `url:"archived,omitempty" json:"archived,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"`
|
||||
Simple *bool `url:"simple,omitempty" json:"simple,omitempty"`
|
||||
Visibility *string `url:"visibility,omitempty" json:"visibility,omitempty"`
|
||||
Statistics *bool `url:"statistics,omitempty" json:"statistics,omitempty"`
|
||||
}
|
||||
|
||||
// ListProjects gets a list of projects accessible by the authenticated user.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#list-projects
|
||||
func (s *ProjectsService) ListProjects(opt *ListProjectsOptions, options ...OptionFunc) ([]*Project, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "projects", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var p []*Project
|
||||
resp, err := s.client.Do(req, &p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// ListOwnedProjects gets a list of projects which are owned by the
|
||||
// authenticated user.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#list-owned-projects
|
||||
func (s *ProjectsService) ListOwnedProjects(opt *ListProjectsOptions, options ...OptionFunc) ([]*Project, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "projects/owned", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var p []*Project
|
||||
resp, err := s.client.Do(req, &p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// ListStarredProjects gets a list of projects which are starred by the
|
||||
// authenticated user.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#list-starred-projects
|
||||
func (s *ProjectsService) ListStarredProjects(opt *ListProjectsOptions, options ...OptionFunc) ([]*Project, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "projects/starred", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var p []*Project
|
||||
resp, err := s.client.Do(req, &p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// ListAllProjects gets a list of all GitLab projects (admin only).
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#list-all-projects
|
||||
func (s *ProjectsService) ListAllProjects(opt *ListProjectsOptions, options ...OptionFunc) ([]*Project, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "projects/all", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var p []*Project
|
||||
resp, err := s.client.Do(req, &p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// GetProject gets a specific project, identified by project ID or
|
||||
// NAMESPACE/PROJECT_NAME, which is owned by the authenticated user.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#get-single-project
|
||||
func (s *ProjectsService) GetProject(pid interface{}, options ...OptionFunc) (*Project, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(Project)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// SearchProjectsOptions represents the available SearchProjects() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#search-for-projects-by-name
|
||||
type SearchProjectsOptions struct {
|
||||
ListOptions
|
||||
OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
|
||||
Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
|
||||
}
|
||||
|
||||
// SearchProjects searches for projects by name which are accessible to the
|
||||
// authenticated user.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#search-for-projects-by-name
|
||||
func (s *ProjectsService) SearchProjects(query string, opt *SearchProjectsOptions, options ...OptionFunc) ([]*Project, *Response, error) {
|
||||
u := fmt.Sprintf("projects/search/%s", query)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var p []*Project
|
||||
resp, err := s.client.Do(req, &p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// ProjectEvent represents a GitLab project event.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#get-project-events
|
||||
type ProjectEvent struct {
|
||||
Title interface{} `json:"title"`
|
||||
ProjectID int `json:"project_id"`
|
||||
ActionName string `json:"action_name"`
|
||||
TargetID interface{} `json:"target_id"`
|
||||
TargetType interface{} `json:"target_type"`
|
||||
AuthorID int `json:"author_id"`
|
||||
AuthorUsername string `json:"author_username"`
|
||||
Data struct {
|
||||
Before string `json:"before"`
|
||||
After string `json:"after"`
|
||||
Ref string `json:"ref"`
|
||||
UserID int `json:"user_id"`
|
||||
UserName string `json:"user_name"`
|
||||
Repository *Repository `json:"repository"`
|
||||
Commits []*Commit `json:"commits"`
|
||||
TotalCommitsCount int `json:"total_commits_count"`
|
||||
} `json:"data"`
|
||||
TargetTitle interface{} `json:"target_title"`
|
||||
}
|
||||
|
||||
func (s ProjectEvent) String() string {
|
||||
return Stringify(s)
|
||||
}
|
||||
|
||||
// GetProjectEventsOptions represents the available GetProjectEvents() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#get-project-events
|
||||
type GetProjectEventsOptions struct {
|
||||
ListOptions
|
||||
}
|
||||
|
||||
// GetProjectEvents gets the events for the specified project. Sorted from
|
||||
// newest to latest.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#get-project-events
|
||||
func (s *ProjectsService) GetProjectEvents(pid interface{}, opt *GetProjectEventsOptions, options ...OptionFunc) ([]*ProjectEvent, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/events", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var p []*ProjectEvent
|
||||
resp, err := s.client.Do(req, &p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// CreateProjectOptions represents the available CreateProjects() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#create-project
|
||||
type CreateProjectOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Path *string `url:"path,omitempty" json:"path,omitempty"`
|
||||
NamespaceID *int `url:"namespace_id,omitempty" json:"namespace_id,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
IssuesEnabled *bool `url:"issues_enabled,omitempty" json:"issues_enabled,omitempty"`
|
||||
MergeRequestsEnabled *bool `url:"merge_requests_enabled,omitempty" json:"merge_requests_enabled,omitempty"`
|
||||
BuildsEnabled *bool `url:"builds_enabled,omitempty" json:"builds_enabled,omitempty"`
|
||||
WikiEnabled *bool `url:"wiki_enabled,omitempty" json:"wiki_enabled,omitempty"`
|
||||
SnippetsEnabled *bool `url:"snippets_enabled,omitempty" json:"snippets_enabled,omitempty"`
|
||||
ContainerRegistryEnabled *bool `url:"container_registry_enabled,omitempty" json:"container_registry_enabled,omitempty"`
|
||||
SharedRunnersEnabled *bool `url:"shared_runners_enabled,omitempty" json:"shared_runners_enabled,omitempty"`
|
||||
Public *bool `url:"public,omitempty" json:"public,omitempty"`
|
||||
VisibilityLevel *VisibilityLevelValue `url:"visibility_level,omitempty" json:"visibility_level,omitempty"`
|
||||
ImportURL *string `url:"import_url,omitempty" json:"import_url,omitempty"`
|
||||
PublicBuilds *bool `url:"public_builds,omitempty" json:"public_builds,omitempty"`
|
||||
OnlyAllowMergeIfBuildSucceeds *bool `url:"only_allow_merge_if_build_succeeds,omitempty" json:"only_allow_merge_if_build_succeeds,omitempty"`
|
||||
LFSEnabled *bool `url:"lfs_enabled,omitempty" json:"lfs_enabled,omitempty"`
|
||||
RequestAccessEnabled *bool `url:"request_access_enabled,omitempty" json:"request_access_enabled,omitempty"`
|
||||
}
|
||||
|
||||
// CreateProject creates a new project owned by the authenticated user.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#create-project
|
||||
func (s *ProjectsService) CreateProject(opt *CreateProjectOptions, options ...OptionFunc) (*Project, *Response, error) {
|
||||
req, err := s.client.NewRequest("POST", "projects", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(Project)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// CreateProjectForUserOptions represents the available CreateProjectForUser()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#create-project-for-user
|
||||
type CreateProjectForUserOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
DefaultBranch *string `url:"default_branch,omitempty" json:"default_branch,omitempty"`
|
||||
IssuesEnabled *bool `url:"issues_enabled,omitempty" json:"issues_enabled,omitempty"`
|
||||
MergeRequestsEnabled *bool `url:"merge_requests_enabled,omitempty" json:"merge_requests_enabled,omitempty"`
|
||||
WikiEnabled *bool `url:"wiki_enabled,omitempty" json:"wiki_enabled,omitempty"`
|
||||
SnippetsEnabled *bool `url:"snippets_enabled,omitempty" json:"snippets_enabled,omitempty"`
|
||||
Public *bool `url:"public,omitempty" json:"public,omitempty"`
|
||||
VisibilityLevel *VisibilityLevelValue `url:"visibility_level,omitempty" json:"visibility_level,omitempty"`
|
||||
ImportURL *string `url:"import_url,omitempty" json:"import_url,omitempty"`
|
||||
}
|
||||
|
||||
// CreateProjectForUser creates a new project owned by the specified user.
|
||||
// Available only for admins.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#create-project-for-user
|
||||
func (s *ProjectsService) CreateProjectForUser(user int, opt *CreateProjectForUserOptions, options ...OptionFunc) (*Project, *Response, error) {
|
||||
u := fmt.Sprintf("projects/user/%d", user)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(Project)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// EditProjectOptions represents the available EditProject() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#edit-project
|
||||
type EditProjectOptions struct {
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Path *string `url:"path,omitempty" json:"path,omitempty"`
|
||||
Description *string `url:"description,omitempty" json:"description,omitempty"`
|
||||
DefaultBranch *string `url:"default_branch,omitempty" json:"default_branch,omitempty"`
|
||||
IssuesEnabled *bool `url:"issues_enabled,omitempty" json:"issues_enabled,omitempty"`
|
||||
MergeRequestsEnabled *bool `url:"merge_requests_enabled,omitempty" json:"merge_requests_enabled,omitempty"`
|
||||
ApprovalsBeforeMerge *int `url:"approvals_before_merge,omitempty" json:"approvals_before_merge,omitempty"`
|
||||
BuildsEnabled *bool `url:"builds_enabled,omitempty" json:"builds_enabled,omitempty"`
|
||||
WikiEnabled *bool `url:"wiki_enabled,omitempty" json:"wiki_enabled,omitempty"`
|
||||
SnippetsEnabled *bool `url:"snippets_enabled,omitempty" json:"snippets_enabled,omitempty"`
|
||||
ContainerRegistryEnabled *bool `url:"container_registry_enabled,omitempty" json:"container_registry_enabled,omitempty"`
|
||||
SharedRunnersEnabled *bool `url:"shared_runners_enabled,omitempty" json:"shared_runners_enabled,omitempty"`
|
||||
Public *bool `url:"public,omitempty" json:"public,omitempty"`
|
||||
VisibilityLevel *VisibilityLevelValue `url:"visibility_level,omitempty" json:"visibility_level,omitempty"`
|
||||
ImportURL *bool `url:"import_url,omitempty" json:"import_url,omitempty"`
|
||||
PublicBuilds *bool `url:"public_builds,omitempty" json:"public_builds,omitempty"`
|
||||
OnlyAllowMergeIfBuildSucceeds *bool `url:"only_allow_merge_if_build_succeeds,omitempty" json:"only_allow_merge_if_build_succeeds,omitempty"`
|
||||
OnlyAllowMergeIfAllDiscussionsAreResolved *bool `url:"only_allow_merge_if_all_discussions_are_resolved,omitempty" json:"only_allow_merge_if_all_discussions_are_resolved,omitempty"`
|
||||
LFSEnabled *bool `url:"lfs_enabled,omitempty" json:"lfs_enabled,omitempty"`
|
||||
RequestAccessEnabled *bool `url:"request_access_enabled,omitempty" json:"request_access_enabled,omitempty"`
|
||||
}
|
||||
|
||||
// EditProject updates an existing project.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#edit-project
|
||||
func (s *ProjectsService) EditProject(pid interface{}, opt *EditProjectOptions, options ...OptionFunc) (*Project, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(Project)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// ForkProject forks a project into the user namespace of the authenticated
|
||||
// user.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#fork-project
|
||||
func (s *ProjectsService) ForkProject(pid interface{}, options ...OptionFunc) (*Project, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/fork/%s", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(Project)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// DeleteProject removes a project including all associated resources
|
||||
// (issues, merge requests etc.)
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#remove-project
|
||||
func (s *ProjectsService) DeleteProject(pid interface{}, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// ProjectMember represents a project member.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#list-project-team-members
|
||||
type ProjectMember struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
AccessLevel AccessLevelValue `json:"access_level"`
|
||||
}
|
||||
|
||||
// ListProjectMembersOptions represents the available ListProjectMembers()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#list-project-team-members
|
||||
type ListProjectMembersOptions struct {
|
||||
ListOptions
|
||||
Query *string `url:"query,omitempty" json:"query,omitempty"`
|
||||
}
|
||||
|
||||
// ListProjectMembers gets a list of a project's team members.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#list-project-team-members
|
||||
func (s *ProjectsService) ListProjectMembers(pid interface{}, opt *ListProjectMembersOptions, options ...OptionFunc) ([]*ProjectMember, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/members", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var pm []*ProjectMember
|
||||
resp, err := s.client.Do(req, &pm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pm, resp, err
|
||||
}
|
||||
|
||||
// GetProjectMember gets a project team member.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#get-project-team-member
|
||||
func (s *ProjectsService) GetProjectMember(pid interface{}, user int, options ...OptionFunc) (*ProjectMember, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/members/%d", url.QueryEscape(project), user)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pm := new(ProjectMember)
|
||||
resp, err := s.client.Do(req, pm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pm, resp, err
|
||||
}
|
||||
|
||||
// AddProjectMemberOptions represents the available AddProjectMember() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#add-project-team-member
|
||||
type AddProjectMemberOptions struct {
|
||||
UserID *int `url:"user_id,omitempty" json:"user_id,omitempty"`
|
||||
AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"`
|
||||
}
|
||||
|
||||
// AddProjectMember adds a user to a project team. This is an idempotent
|
||||
// method and can be called multiple times with the same parameters. Adding
|
||||
// team membership to a user that is already a member does not affect the
|
||||
// existing membership.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#add-project-team-member
|
||||
func (s *ProjectsService) AddProjectMember(pid interface{}, opt *AddProjectMemberOptions, options ...OptionFunc) (*ProjectMember, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/members", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pm := new(ProjectMember)
|
||||
resp, err := s.client.Do(req, pm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pm, resp, err
|
||||
}
|
||||
|
||||
// EditProjectMemberOptions represents the available EditProjectMember() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#edit-project-team-member
|
||||
type EditProjectMemberOptions struct {
|
||||
AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"`
|
||||
}
|
||||
|
||||
// EditProjectMember updates a project team member to a specified access level..
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#edit-project-team-member
|
||||
func (s *ProjectsService) EditProjectMember(pid interface{}, user int, opt *EditProjectMemberOptions, options ...OptionFunc) (*ProjectMember, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/members/%d", url.QueryEscape(project), user)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pm := new(ProjectMember)
|
||||
resp, err := s.client.Do(req, pm)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pm, resp, err
|
||||
}
|
||||
|
||||
// DeleteProjectMember removes a user from a project team.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#remove-project-team-member
|
||||
func (s *ProjectsService) DeleteProjectMember(pid interface{}, user int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/members/%d", url.QueryEscape(project), user)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// ProjectHook represents a project hook.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#list-project-hooks
|
||||
type ProjectHook struct {
|
||||
ID int `json:"id"`
|
||||
URL string `json:"url"`
|
||||
ProjectID int `json:"project_id"`
|
||||
PushEvents bool `json:"push_events"`
|
||||
IssuesEvents bool `json:"issues_events"`
|
||||
MergeRequestsEvents bool `json:"merge_requests_events"`
|
||||
TagPushEvents bool `json:"tag_push_events"`
|
||||
NoteEvents bool `json:"note_events"`
|
||||
BuildEvents bool `json:"build_events"`
|
||||
PipelineEvents bool `json:"pipeline_events"`
|
||||
WikiPageEvents bool `json:"wiki_page_events"`
|
||||
EnableSSLVerification bool `json:"enable_ssl_verification"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// ListProjectHooksOptions represents the available ListProjectHooks() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#list-project-hooks
|
||||
type ListProjectHooksOptions struct {
|
||||
ListOptions
|
||||
}
|
||||
|
||||
// ListProjectHooks gets a list of project hooks.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#list-project-hooks
|
||||
func (s *ProjectsService) ListProjectHooks(pid interface{}, opt *ListProjectHooksOptions, options ...OptionFunc) ([]*ProjectHook, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/hooks", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var ph []*ProjectHook
|
||||
resp, err := s.client.Do(req, &ph)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ph, resp, err
|
||||
}
|
||||
|
||||
// GetProjectHook gets a specific hook for a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#get-project-hook
|
||||
func (s *ProjectsService) GetProjectHook(pid interface{}, hook int, options ...OptionFunc) (*ProjectHook, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/hooks/%d", url.QueryEscape(project), hook)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ph := new(ProjectHook)
|
||||
resp, err := s.client.Do(req, ph)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ph, resp, err
|
||||
}
|
||||
|
||||
// AddProjectHookOptions represents the available AddProjectHook() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#add-project-hook
|
||||
type AddProjectHookOptions struct {
|
||||
URL *string `url:"url,omitempty" json:"url,omitempty"`
|
||||
PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"`
|
||||
IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"`
|
||||
MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"`
|
||||
TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"`
|
||||
NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"`
|
||||
BuildEvents *bool `url:"build_events,omitempty" json:"build_events,omitempty"`
|
||||
PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"`
|
||||
WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"`
|
||||
EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"`
|
||||
Token *string `url:"token,omitempty" json:"token,omitempty"`
|
||||
}
|
||||
|
||||
// AddProjectHook adds a hook to a specified project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#add-project-hook
|
||||
func (s *ProjectsService) AddProjectHook(pid interface{}, opt *AddProjectHookOptions, options ...OptionFunc) (*ProjectHook, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/hooks", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ph := new(ProjectHook)
|
||||
resp, err := s.client.Do(req, ph)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ph, resp, err
|
||||
}
|
||||
|
||||
// EditProjectHookOptions represents the available EditProjectHook() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#edit-project-hook
|
||||
type EditProjectHookOptions struct {
|
||||
URL *string `url:"url,omitempty" json:"url,omitempty"`
|
||||
PushEvents *bool `url:"push_events,omitempty" json:"push_events,omitempty"`
|
||||
IssuesEvents *bool `url:"issues_events,omitempty" json:"issues_events,omitempty"`
|
||||
MergeRequestsEvents *bool `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"`
|
||||
TagPushEvents *bool `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"`
|
||||
NoteEvents *bool `url:"note_events,omitempty" json:"note_events,omitempty"`
|
||||
BuildEvents *bool `url:"build_events,omitempty" json:"build_events,omitempty"`
|
||||
PipelineEvents *bool `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"`
|
||||
WikiPageEvents *bool `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"`
|
||||
EnableSSLVerification *bool `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"`
|
||||
Token *string `url:"token,omitempty" json:"token,omitempty"`
|
||||
}
|
||||
|
||||
// EditProjectHook edits a hook for a specified project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#edit-project-hook
|
||||
func (s *ProjectsService) EditProjectHook(pid interface{}, hook int, opt *EditProjectHookOptions, options ...OptionFunc) (*ProjectHook, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/hooks/%d", url.QueryEscape(project), hook)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
ph := new(ProjectHook)
|
||||
resp, err := s.client.Do(req, ph)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return ph, resp, err
|
||||
}
|
||||
|
||||
// DeleteProjectHook removes a hook from a project. This is an idempotent
|
||||
// method and can be called multiple times. Either the hook is available or not.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#delete-project-hook
|
||||
func (s *ProjectsService) DeleteProjectHook(pid interface{}, hook int, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/hooks/%d", url.QueryEscape(project), hook)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// ProjectForkRelation represents a project fork relationship.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#admin-fork-relation
|
||||
type ProjectForkRelation struct {
|
||||
ID int `json:"id"`
|
||||
ForkedToProjectID int `json:"forked_to_project_id"`
|
||||
ForkedFromProjectID int `json:"forked_from_project_id"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
// CreateProjectForkRelation creates a forked from/to relation between
|
||||
// existing projects.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#create-a-forked-fromto-relation-between-existing-projects.
|
||||
func (s *ProjectsService) CreateProjectForkRelation(pid int, fork int, options ...OptionFunc) (*ProjectForkRelation, *Response, error) {
|
||||
u := fmt.Sprintf("projects/%d/fork/%d", pid, fork)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
pfr := new(ProjectForkRelation)
|
||||
resp, err := s.client.Do(req, pfr)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return pfr, resp, err
|
||||
}
|
||||
|
||||
// DeleteProjectForkRelation deletes an existing forked from relationship.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#delete-an-existing-forked-from-relationship
|
||||
func (s *ProjectsService) DeleteProjectForkRelation(pid int, options ...OptionFunc) (*Response, error) {
|
||||
u := fmt.Sprintf("projects/%d/fork", pid)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// ArchiveProject archives the project if the user is either admin or the
|
||||
// project owner of this project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#archive-a-project
|
||||
func (s *ProjectsService) ArchiveProject(pid interface{}, options ...OptionFunc) (*Project, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/archive", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(Project)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
||||
|
||||
// UnarchiveProject unarchives the project if the user is either admin or
|
||||
// the project owner of this project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/projects.html#unarchive-a-project
|
||||
func (s *ProjectsService) UnarchiveProject(pid interface{}, options ...OptionFunc) (*Project, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/unarchive", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
p := new(Project)
|
||||
resp, err := s.client.Do(req, p)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return p, resp, err
|
||||
}
|
|
@ -0,0 +1,259 @@
|
|||
//
|
||||
// Copyright 2015, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// RepositoriesService handles communication with the repositories related
|
||||
// methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/repositories.html
|
||||
type RepositoriesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// TreeNode represents a GitLab repository file or directory.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/repositories.html
|
||||
type TreeNode struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
Mode string `json:"mode"`
|
||||
}
|
||||
|
||||
func (t TreeNode) String() string {
|
||||
return Stringify(t)
|
||||
}
|
||||
|
||||
// ListTreeOptions represents the available ListTree() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repositories.html#list-repository-tree
|
||||
type ListTreeOptions struct {
|
||||
Path *string `url:"path,omitempty" json:"path,omitempty"`
|
||||
RefName *string `url:"ref_name,omitempty" json:"ref_name,omitempty"`
|
||||
}
|
||||
|
||||
// ListTree gets a list of repository files and directories in a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repositories.html#list-repository-tree
|
||||
func (s *RepositoriesService) ListTree(pid interface{}, opt *ListTreeOptions, options ...OptionFunc) ([]*TreeNode, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/tree", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var t []*TreeNode
|
||||
resp, err := s.client.Do(req, &t)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return t, resp, err
|
||||
}
|
||||
|
||||
// RawFileContentOptions represents the available RawFileContent() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repositories.html#raw-file-content
|
||||
type RawFileContentOptions struct {
|
||||
FilePath *string `url:"filepath,omitempty" json:"filepath,omitempty"`
|
||||
}
|
||||
|
||||
// RawFileContent gets the raw file contents for a file by commit SHA and path
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repositories.html#raw-file-content
|
||||
func (s *RepositoriesService) RawFileContent(pid interface{}, sha string, opt *RawFileContentOptions, options ...OptionFunc) ([]byte, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/blobs/%s", url.QueryEscape(project), sha)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var b bytes.Buffer
|
||||
resp, err := s.client.Do(req, &b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b.Bytes(), resp, err
|
||||
}
|
||||
|
||||
// RawBlobContent gets the raw file contents for a blob by blob SHA.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repositories.html#raw-blob-content
|
||||
func (s *RepositoriesService) RawBlobContent(pid interface{}, sha string, options ...OptionFunc) ([]byte, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/raw_blobs/%s", url.QueryEscape(project), sha)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var b bytes.Buffer
|
||||
resp, err := s.client.Do(req, &b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b.Bytes(), resp, err
|
||||
}
|
||||
|
||||
// ArchiveOptions represents the available Archive() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repositories.html#get-file-archive
|
||||
type ArchiveOptions struct {
|
||||
SHA *string `url:"sha,omitempty" json:"sha,omitempty"`
|
||||
}
|
||||
|
||||
// Archive gets an archive of the repository.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repositories.html#get-file-archive
|
||||
func (s *RepositoriesService) Archive(pid interface{}, opt *ArchiveOptions, options ...OptionFunc) ([]byte, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/archive", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var b bytes.Buffer
|
||||
resp, err := s.client.Do(req, &b)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return b.Bytes(), resp, err
|
||||
}
|
||||
|
||||
// Compare represents the result of a comparison of branches, tags or commits.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repositories.html#compare-branches-tags-or-commits
|
||||
type Compare struct {
|
||||
Commit *Commit `json:"commit"`
|
||||
Commits []*Commit `json:"commits"`
|
||||
Diffs []*Diff `json:"diffs"`
|
||||
CompareTimeout bool `json:"compare_timeout"`
|
||||
CompareSameRef bool `json:"compare_same_ref"`
|
||||
}
|
||||
|
||||
func (c Compare) String() string {
|
||||
return Stringify(c)
|
||||
}
|
||||
|
||||
// CompareOptions represents the available Compare() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repositories.html#compare-branches-tags-or-commits
|
||||
type CompareOptions struct {
|
||||
From *string `url:"from,omitempty" json:"from,omitempty"`
|
||||
To *string `url:"to,omitempty" json:"to,omitempty"`
|
||||
}
|
||||
|
||||
// Compare compares branches, tags or commits.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repositories.html#compare-branches-tags-or-commits
|
||||
func (s *RepositoriesService) Compare(pid interface{}, opt *CompareOptions, options ...OptionFunc) (*Compare, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/compare", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
c := new(Compare)
|
||||
resp, err := s.client.Do(req, c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
||||
|
||||
// Contributor represents a GitLap contributor.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/repositories.html#contributer
|
||||
type Contributor struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Email string `json:"email,omitempty"`
|
||||
Commits int `json:"commits,omitempty"`
|
||||
Additions int `json:"additions,omitempty"`
|
||||
Deletions int `json:"deletions,omitempty"`
|
||||
}
|
||||
|
||||
func (c Contributor) String() string {
|
||||
return Stringify(c)
|
||||
}
|
||||
|
||||
// Contributors gets the repository contributors list.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/repositories.html#contributer
|
||||
func (s *RepositoriesService) Contributors(pid interface{}, options ...OptionFunc) ([]*Contributor, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/contributors", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var c []*Contributor
|
||||
resp, err := s.client.Do(req, &c)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return c, resp, err
|
||||
}
|
|
@ -0,0 +1,210 @@
|
|||
//
|
||||
// Copyright 2015, 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"
|
||||
)
|
||||
|
||||
// RepositoryFilesService handles communication with the repository files
|
||||
// related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/repository_files.html
|
||||
type RepositoryFilesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// File represents a GitLab repository file.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/repository_files.html
|
||||
type File struct {
|
||||
FileName string `json:"file_name"`
|
||||
FilePath string `json:"file_path"`
|
||||
Size int `json:"size"`
|
||||
Encoding string `json:"encoding"`
|
||||
Content string `json:"content"`
|
||||
Ref string `json:"ref"`
|
||||
BlobID string `json:"blob_id"`
|
||||
CommitID string `json:"commit_id"`
|
||||
}
|
||||
|
||||
func (r File) String() string {
|
||||
return Stringify(r)
|
||||
}
|
||||
|
||||
// GetFileOptions represents the available GetFile() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repository_files.html#get-file-from-respository
|
||||
type GetFileOptions struct {
|
||||
FilePath *string `url:"file_path,omitempty" json:"file_path,omitempty"`
|
||||
Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
|
||||
}
|
||||
|
||||
// GetFile allows you to receive information about a file in repository like
|
||||
// name, size, content. Note that file content is Base64 encoded.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repository_files.html#get-file-from-respository
|
||||
func (s *RepositoryFilesService) GetFile(pid interface{}, opt *GetFileOptions, options ...OptionFunc) (*File, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/files", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
f := new(File)
|
||||
resp, err := s.client.Do(req, f)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return f, resp, err
|
||||
}
|
||||
|
||||
// FileInfo represents file details of a GitLab repository file.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/repository_files.html
|
||||
type FileInfo struct {
|
||||
FilePath string `json:"file_path"`
|
||||
BranchName string `json:"branch_name"`
|
||||
}
|
||||
|
||||
func (r FileInfo) String() string {
|
||||
return Stringify(r)
|
||||
}
|
||||
|
||||
// CreateFileOptions represents the available CreateFile() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repository_files.html#create-new-file-in-repository
|
||||
type CreateFileOptions struct {
|
||||
FilePath *string `url:"file_path,omitempty" json:"file_path,omitempty"`
|
||||
BranchName *string `url:"branch_name,omitempty" json:"branch_name,omitempty"`
|
||||
Encoding *string `url:"encoding,omitempty" json:"encoding,omitempty"`
|
||||
AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"`
|
||||
AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"`
|
||||
Content *string `url:"content,omitempty" json:"content,omitempty"`
|
||||
CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"`
|
||||
}
|
||||
|
||||
// CreateFile creates a new file in a repository.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repository_files.html#create-new-file-in-repository
|
||||
func (s *RepositoryFilesService) CreateFile(pid interface{}, opt *CreateFileOptions, options ...OptionFunc) (*FileInfo, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/files", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
f := new(FileInfo)
|
||||
resp, err := s.client.Do(req, f)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return f, resp, err
|
||||
}
|
||||
|
||||
// UpdateFileOptions represents the available UpdateFile() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repository_files.html#update-existing-file-in-repository
|
||||
type UpdateFileOptions struct {
|
||||
FilePath *string `url:"file_path,omitempty" json:"file_path,omitempty"`
|
||||
BranchName *string `url:"branch_name,omitempty" json:"branch_name,omitempty"`
|
||||
Encoding *string `url:"encoding,omitempty" json:"encoding,omitempty"`
|
||||
AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"`
|
||||
AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"`
|
||||
Content *string `url:"content,omitempty" json:"content,omitempty"`
|
||||
CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateFile updates an existing file in a repository
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repository_files.html#update-existing-file-in-repository
|
||||
func (s *RepositoryFilesService) UpdateFile(pid interface{}, opt *UpdateFileOptions, options ...OptionFunc) (*FileInfo, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/files", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
f := new(FileInfo)
|
||||
resp, err := s.client.Do(req, f)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return f, resp, err
|
||||
}
|
||||
|
||||
// DeleteFileOptions represents the available DeleteFile() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repository_files.html#delete-existing-file-in-repository
|
||||
type DeleteFileOptions struct {
|
||||
FilePath *string `url:"file_path,omitempty" json:"file_path,omitempty"`
|
||||
BranchName *string `url:"branch_name,omitempty" json:"branch_name,omitempty"`
|
||||
AuthorEmail *string `url:"author_email,omitempty" json:"author_email,omitempty"`
|
||||
AuthorName *string `url:"author_name,omitempty" json:"author_name,omitempty"`
|
||||
CommitMessage *string `url:"commit_message,omitempty" json:"commit_message,omitempty"`
|
||||
}
|
||||
|
||||
// DeleteFile deletes an existing file in a repository
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/repository_files.html#delete-existing-file-in-repository
|
||||
func (s *RepositoryFilesService) DeleteFile(pid interface{}, opt *DeleteFileOptions, options ...OptionFunc) (*FileInfo, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/files", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
f := new(FileInfo)
|
||||
resp, err := s.client.Do(req, f)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return f, resp, err
|
||||
}
|
|
@ -0,0 +1,279 @@
|
|||
//
|
||||
// Copyright 2015, 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"
|
||||
"time"
|
||||
)
|
||||
|
||||
// ServicesService handles communication with the services related methods of
|
||||
// the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/services.html
|
||||
type ServicesService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Service represents a GitLab service.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/services.html
|
||||
type Service struct {
|
||||
ID *int `json:"id"`
|
||||
Title *string `json:"title"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
UpdatedAt *time.Time `json:"created_at"`
|
||||
Active *bool `json:"active"`
|
||||
PushEvents *bool `json:"push_events"`
|
||||
IssuesEvents *bool `json:"issues_events"`
|
||||
MergeRequestsEvents *bool `json:"merge_requests_events"`
|
||||
TagPushEvents *bool `json:"tag_push_events"`
|
||||
NoteEvents *bool `json:"note_events"`
|
||||
}
|
||||
|
||||
// SetGitLabCIServiceOptions represents the available SetGitLabCIService()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/services.html#edit-gitlab-ci-service
|
||||
type SetGitLabCIServiceOptions struct {
|
||||
Token *string `url:"token,omitempty" json:"token,omitempty"`
|
||||
ProjectURL *string `url:"project_url,omitempty" json:"project_url,omitempty"`
|
||||
}
|
||||
|
||||
// SetGitLabCIService sets GitLab CI service for a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/services.html#edit-gitlab-ci-service
|
||||
func (s *ServicesService) SetGitLabCIService(pid interface{}, opt *SetGitLabCIServiceOptions, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/services/gitlab-ci", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// DeleteGitLabCIService deletes GitLab CI service settings for a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/services.html#delete-gitlab-ci-service
|
||||
func (s *ServicesService) DeleteGitLabCIService(pid interface{}, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/services/gitlab-ci", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// SetHipChatServiceOptions represents the available SetHipChatService()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/services.html#edit-hipchat-service
|
||||
type SetHipChatServiceOptions struct {
|
||||
Token *string `url:"token,omitempty" json:"token,omitempty" `
|
||||
Room *string `url:"room,omitempty" json:"room,omitempty"`
|
||||
}
|
||||
|
||||
// SetHipChatService sets HipChat service for a project
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/services.html#edit-hipchat-service
|
||||
func (s *ServicesService) SetHipChatService(pid interface{}, opt *SetHipChatServiceOptions, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/services/hipchat", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// DeleteHipChatService deletes HipChat service for project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/services.html#delete-hipchat-service
|
||||
func (s *ServicesService) DeleteHipChatService(pid interface{}, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/services/hipchat", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// SetDroneCIServiceOptions represents the available SetDroneCIService()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/services.html#createedit-drone-ci-service
|
||||
type SetDroneCIServiceOptions struct {
|
||||
Token *string `url:"token" json:"token" `
|
||||
DroneURL *string `url:"drone_url" json:"drone_url"`
|
||||
EnableSSLVerification *string `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"`
|
||||
}
|
||||
|
||||
// SetDroneCIService sets Drone CI service for a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/services.html#createedit-drone-ci-service
|
||||
func (s *ServicesService) SetDroneCIService(pid interface{}, opt *SetDroneCIServiceOptions, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/services/drone-ci", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// DeleteDroneCIService deletes Drone CI service settings for a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/services.html#delete-drone-ci-service
|
||||
func (s *ServicesService) DeleteDroneCIService(pid interface{}, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/services/drone-ci", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// DroneCIServiceProperties represents Drone CI specific properties.
|
||||
type DroneCIServiceProperties struct {
|
||||
Token *string `url:"token" json:"token"`
|
||||
DroneURL *string `url:"drone_url" json:"drone_url"`
|
||||
EnableSSLVerification *string `url:"enable_ssl_verification" json:"enable_ssl_verification"`
|
||||
}
|
||||
|
||||
// DroneCIService represents Drone CI service settings.
|
||||
type DroneCIService struct {
|
||||
Service
|
||||
Properties *DroneCIServiceProperties `json:"properties"`
|
||||
}
|
||||
|
||||
// GetDroneCIService gets Drone CI service settings for a project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/services.html#get-drone-ci-service-settings
|
||||
func (s *ServicesService) GetDroneCIService(pid interface{}, options ...OptionFunc) (*DroneCIService, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/services/drone-ci", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
opt := new(DroneCIService)
|
||||
resp, err := s.client.Do(req, opt)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return opt, resp, err
|
||||
}
|
||||
|
||||
// SetSlackServiceOptions represents the available SetSlackService()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/services.html#edit-slack-service
|
||||
type SetSlackServiceOptions struct {
|
||||
WebHook *string `url:"webhook,omitempty" json:"webhook,omitempty" `
|
||||
Username *string `url:"username,omitempty" json:"username,omitempty" `
|
||||
Channel *string `url:"channel,omitempty" json:"channel,omitempty"`
|
||||
}
|
||||
|
||||
// SetSlackService sets Slack service for a project
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/services.html#edit-slack-service
|
||||
func (s *ServicesService) SetSlackService(pid interface{}, opt *SetSlackServiceOptions, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/services/slack", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// DeleteSlackService deletes Slack service for project.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/services.html#delete-slack-service
|
||||
func (s *ServicesService) DeleteSlackService(pid interface{}, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/services/slack", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
//
|
||||
// Copyright 2015, 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 "time"
|
||||
|
||||
// SessionService handles communication with the session related methods of
|
||||
// the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/session.html
|
||||
type SessionService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Session represents a GitLab session.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/session.html#session
|
||||
type Session struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
PrivateToken string `json:"private_token"`
|
||||
Blocked bool `json:"blocked"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
Bio interface{} `json:"bio"`
|
||||
Skype string `json:"skype"`
|
||||
Linkedin string `json:"linkedin"`
|
||||
Twitter string `json:"twitter"`
|
||||
WebsiteURL string `json:"website_url"`
|
||||
DarkScheme bool `json:"dark_scheme"`
|
||||
ThemeID int `json:"theme_id"`
|
||||
IsAdmin bool `json:"is_admin"`
|
||||
CanCreateGroup bool `json:"can_create_group"`
|
||||
CanCreateTeam bool `json:"can_create_team"`
|
||||
CanCreateProject bool `json:"can_create_project"`
|
||||
}
|
||||
|
||||
// GetSessionOptions represents the available Session() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/session.html#session
|
||||
type GetSessionOptions struct {
|
||||
Login *string `url:"login,omitempty" json:"login,omitempty"`
|
||||
Email *string `url:"email,omitempty" json:"email,omitempty"`
|
||||
Password *string `url:"password,omitempty" json:"password,omitempty"`
|
||||
}
|
||||
|
||||
// GetSession logs in to get private token.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/session.html#session
|
||||
func (s *SessionService) GetSession(opt *GetSessionOptions, options ...OptionFunc) (*Session, *Response, error) {
|
||||
req, err := s.client.NewRequest("POST", "session", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
session := new(Session)
|
||||
resp, err := s.client.Do(req, session)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return session, resp, err
|
||||
}
|
|
@ -0,0 +1,117 @@
|
|||
//
|
||||
// Copyright 2015, 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 "time"
|
||||
|
||||
// SettingsService handles communication with the application SettingsService
|
||||
// related methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/settings.html
|
||||
type SettingsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Settings represents the GitLab application settings.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/settings.html
|
||||
type Settings struct {
|
||||
ID int `json:"id"`
|
||||
DefaultProjectsLimit int `json:"default_projects_limit"`
|
||||
SignupEnabled bool `json:"signup_enabled"`
|
||||
SigninEnabled bool `json:"signin_enabled"`
|
||||
GravatarEnabled bool `json:"gravatar_enabled"`
|
||||
SignInText string `json:"sign_in_text"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
UpdatedAt *time.Time `json:"updated_at"`
|
||||
HomePageURL string `json:"home_page_url"`
|
||||
DefaultBranchProtection int `json:"default_branch_protection"`
|
||||
TwitterSharingEnabled bool `json:"twitter_sharing_enabled"`
|
||||
RestrictedVisibilityLevels []VisibilityLevelValue `json:"restricted_visibility_levels"`
|
||||
MaxAttachmentSize int `json:"max_attachment_size"`
|
||||
SessionExpireDelay int `json:"session_expire_delay"`
|
||||
DefaultProjectVisibility int `json:"default_project_visibility"`
|
||||
DefaultSnippetVisibility int `json:"default_snippet_visibility"`
|
||||
RestrictedSignupDomains []string `json:"restricted_signup_domains"`
|
||||
UserOauthApplications bool `json:"user_oauth_applications"`
|
||||
AfterSignOutPath string `json:"after_sign_out_path"`
|
||||
}
|
||||
|
||||
func (s Settings) String() string {
|
||||
return Stringify(s)
|
||||
}
|
||||
|
||||
// GetSettings gets the current application settings.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/settings.html#get-current-application.settings
|
||||
func (s *SettingsService) GetSettings(options ...OptionFunc) (*Settings, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "application/settings", nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
as := new(Settings)
|
||||
resp, err := s.client.Do(req, as)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return as, resp, err
|
||||
}
|
||||
|
||||
// UpdateSettingsOptions represents the available UpdateSettings() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/settings.html#change-application.settings
|
||||
type UpdateSettingsOptions struct {
|
||||
DefaultProjectsLimit *int `url:"default_projects_limit,omitempty" json:"default_projects_limit,omitempty"`
|
||||
SignupEnabled *bool `url:"signup_enabled,omitempty" json:"signup_enabled,omitempty"`
|
||||
SigninEnabled *bool `url:"signin_enabled,omitempty" json:"signin_enabled,omitempty"`
|
||||
GravatarEnabled *bool `url:"gravatar_enabled,omitempty" json:"gravatar_enabled,omitempty"`
|
||||
SignInText *string `url:"sign_in_text,omitempty" json:"sign_in_text,omitempty"`
|
||||
HomePageURL *string `url:"home_page_url,omitempty" json:"home_page_url,omitempty"`
|
||||
DefaultBranchProtection *int `url:"default_branch_protection,omitempty" json:"default_branch_protection,omitempty"`
|
||||
TwitterSharingEnabled *bool `url:"twitter_sharing_enabled,omitempty" json:"twitter_sharing_enabled,omitempty"`
|
||||
RestrictedVisibilityLevels []VisibilityLevelValue `url:"restricted_visibility_levels,omitempty" json:"restricted_visibility_levels,omitempty"`
|
||||
MaxAttachmentSize *int `url:"max_attachment_size,omitempty" json:"max_attachment_size,omitempty"`
|
||||
SessionExpireDelay *int `url:"session_expire_delay,omitempty" json:"session_expire_delay,omitempty"`
|
||||
DefaultProjectVisibility *int `url:"default_project_visibility,omitempty" json:"default_project_visibility,omitempty"`
|
||||
DefaultSnippetVisibility *int `url:"default_snippet_visibility,omitempty" json:"default_snippet_visibility,omitempty"`
|
||||
RestrictedSignupDomains []string `url:"restricted_signup_domains,omitempty" json:"restricted_signup_domains,omitempty"`
|
||||
UserOauthApplications *bool `url:"user_oauth_applications,omitempty" json:"user_oauth_applications,omitempty"`
|
||||
AfterSignOutPath *string `url:"after_sign_out_path,omitempty" json:"after_sign_out_path,omitempty"`
|
||||
}
|
||||
|
||||
// UpdateSettings updates the application settings.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/settings.html#change-application.settings
|
||||
func (s *SettingsService) UpdateSettings(opt *UpdateSettingsOptions, options ...OptionFunc) (*Settings, *Response, error) {
|
||||
req, err := s.client.NewRequest("PUT", "application/settings", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
as := new(Settings)
|
||||
resp, err := s.client.Do(req, as)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return as, resp, err
|
||||
}
|
|
@ -0,0 +1,94 @@
|
|||
//
|
||||
// Copyright 2015, Sander van Harmelen
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
|
||||
package gitlab
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Stringify attempts to create a reasonable string representation of types in
|
||||
// the GitHub library. It does things like resolve pointers to their values
|
||||
// and omits struct fields with nil values.
|
||||
func Stringify(message interface{}) string {
|
||||
var buf bytes.Buffer
|
||||
v := reflect.ValueOf(message)
|
||||
stringifyValue(&buf, v)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// stringifyValue was heavily inspired by the goprotobuf library.
|
||||
func stringifyValue(buf *bytes.Buffer, val reflect.Value) {
|
||||
if val.Kind() == reflect.Ptr && val.IsNil() {
|
||||
buf.WriteString("<nil>")
|
||||
return
|
||||
}
|
||||
|
||||
v := reflect.Indirect(val)
|
||||
|
||||
switch v.Kind() {
|
||||
case reflect.String:
|
||||
fmt.Fprintf(buf, `"%s"`, v)
|
||||
case reflect.Slice:
|
||||
buf.WriteByte('[')
|
||||
for i := 0; i < v.Len(); i++ {
|
||||
if i > 0 {
|
||||
buf.WriteByte(' ')
|
||||
}
|
||||
|
||||
stringifyValue(buf, v.Index(i))
|
||||
}
|
||||
|
||||
buf.WriteByte(']')
|
||||
return
|
||||
case reflect.Struct:
|
||||
if v.Type().Name() != "" {
|
||||
buf.WriteString(v.Type().String())
|
||||
}
|
||||
|
||||
buf.WriteByte('{')
|
||||
|
||||
var sep bool
|
||||
for i := 0; i < v.NumField(); i++ {
|
||||
fv := v.Field(i)
|
||||
if fv.Kind() == reflect.Ptr && fv.IsNil() {
|
||||
continue
|
||||
}
|
||||
if fv.Kind() == reflect.Slice && fv.IsNil() {
|
||||
continue
|
||||
}
|
||||
|
||||
if sep {
|
||||
buf.WriteString(", ")
|
||||
} else {
|
||||
sep = true
|
||||
}
|
||||
|
||||
buf.WriteString(v.Type().Field(i).Name)
|
||||
buf.WriteByte(':')
|
||||
stringifyValue(buf, fv)
|
||||
}
|
||||
|
||||
buf.WriteByte('}')
|
||||
default:
|
||||
if v.CanInterface() {
|
||||
fmt.Fprint(buf, v.Interface())
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
//
|
||||
// Copyright 2015, 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"
|
||||
)
|
||||
|
||||
// SystemHooksService handles communication with the system hooks related
|
||||
// methods of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/system_hooks.html
|
||||
type SystemHooksService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Hook represents a GitLap system hook.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/system_hooks.html
|
||||
type Hook struct {
|
||||
ID int `json:"id"`
|
||||
URL string `json:"url"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
func (h Hook) String() string {
|
||||
return Stringify(h)
|
||||
}
|
||||
|
||||
// ListHooks gets a list of system hooks.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/system_hooks.html#list-system-hooks
|
||||
func (s *SystemHooksService) ListHooks(options ...OptionFunc) ([]*Hook, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "hooks", nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var h []*Hook
|
||||
resp, err := s.client.Do(req, &h)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return h, resp, err
|
||||
}
|
||||
|
||||
// AddHookOptions represents the available AddHook() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/system_hooks.html#add-new-system-hook-hook
|
||||
type AddHookOptions struct {
|
||||
URL *string `url:"url,omitempty" json:"url,omitempty"`
|
||||
}
|
||||
|
||||
// AddHook adds a new system hook hook.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/system_hooks.html#add-new-system-hook-hook
|
||||
func (s *SystemHooksService) AddHook(opt *AddHookOptions, options ...OptionFunc) (*Hook, *Response, error) {
|
||||
req, err := s.client.NewRequest("POST", "hooks", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
h := new(Hook)
|
||||
resp, err := s.client.Do(req, h)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return h, resp, err
|
||||
}
|
||||
|
||||
// HookEvent represents an event triggert by a GitLab system hook.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/system_hooks.html
|
||||
type HookEvent struct {
|
||||
EventName string `json:"event_name"`
|
||||
Name string `json:"name"`
|
||||
Path string `json:"path"`
|
||||
ProjectID int `json:"project_id"`
|
||||
OwnerName string `json:"owner_name"`
|
||||
OwnerEmail string `json:"owner_email"`
|
||||
}
|
||||
|
||||
func (h HookEvent) String() string {
|
||||
return Stringify(h)
|
||||
}
|
||||
|
||||
// TestHook tests a system hook.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/system_hooks.html#test-system-hook
|
||||
func (s *SystemHooksService) TestHook(hook int, options ...OptionFunc) (*HookEvent, *Response, error) {
|
||||
u := fmt.Sprintf("hooks/%d", hook)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
h := new(HookEvent)
|
||||
resp, err := s.client.Do(req, h)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return h, resp, err
|
||||
}
|
||||
|
||||
// DeleteHook deletes a system hook. This is an idempotent API function and
|
||||
// returns 200 OK even if the hook is not available. If the hook is deleted it
|
||||
// is also returned as JSON.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/system_hooks.html#delete-system-hook
|
||||
func (s *SystemHooksService) DeleteHook(hook int, options ...OptionFunc) (*Response, error) {
|
||||
u := fmt.Sprintf("hooks/%d", hook)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
//
|
||||
// Copyright 2015, 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"
|
||||
)
|
||||
|
||||
// TagsService handles communication with the tags related methods
|
||||
// of the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/tags.html
|
||||
type TagsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// Tag represents a GitLab tag.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/tags.html
|
||||
type Tag struct {
|
||||
Commit *Commit `json:"commit"`
|
||||
Name string `json:"name"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func (r Tag) String() string {
|
||||
return Stringify(r)
|
||||
}
|
||||
|
||||
// ListTags gets a list of tags from a project, sorted by name in reverse
|
||||
// alphabetical order.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/tags.html#list-project-repository-tags
|
||||
func (s *TagsService) ListTags(pid interface{}, options ...OptionFunc) ([]*Tag, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/tags", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var t []*Tag
|
||||
resp, err := s.client.Do(req, &t)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return t, resp, err
|
||||
}
|
||||
|
||||
// GetTag a specific repository tag determined by its name. It returns 200 together
|
||||
// with the tag information if the tag exists. It returns 404 if the tag does not exist.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/tags.html#get-a-single-repository-tag
|
||||
func (s *TagsService) GetTag(pid interface{}, tag string, options ...OptionFunc) (*Tag, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/tags/%s", url.QueryEscape(project), tag)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var t *Tag
|
||||
resp, err := s.client.Do(req, &t)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return t, resp, err
|
||||
}
|
||||
|
||||
// CreateTagOptions represents the available CreateTag() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/tags.html#create-a-new-tag
|
||||
type CreateTagOptions struct {
|
||||
TagName *string `url:"tag_name,omitempty" json:"tag_name,omitempty"`
|
||||
Ref *string `url:"ref,omitempty" json:"ref,omitempty"`
|
||||
Message *string `url:"message,omitempty" json:"message,omitempty"`
|
||||
}
|
||||
|
||||
// CreateTag creates a new tag in the repository that points to the supplied ref.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/tags.html#create-a-new-tag
|
||||
func (s *TagsService) CreateTag(pid interface{}, opt *CreateTagOptions, options ...OptionFunc) (*Tag, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/tags", url.QueryEscape(project))
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
t := new(Tag)
|
||||
resp, err := s.client.Do(req, t)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return t, resp, err
|
||||
}
|
||||
|
||||
// DeleteTag deletes a tag of a repository with given name.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/tags.html#delete-a-tag
|
||||
func (s *TagsService) DeleteTag(pid interface{}, tag string, options ...OptionFunc) (*Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/repository/tags/%s", url.QueryEscape(project), tag)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
package gitlab
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// TimeStatsService handles communication with the time tracking related
|
||||
// methods of the GitLab API.
|
||||
//
|
||||
// GitLab docs: https://docs.gitlab.com/ce/workflow/time_tracking.html
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html
|
||||
type TimeStatsService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// TimeStats represents the time estimates and time spent for an issue.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/issues.html
|
||||
type TimeStats struct {
|
||||
HumanTimeEstimate string `json:"human_time_estimate"`
|
||||
HumanTotalTimeSpent string `json:"human_total_time_spent"`
|
||||
TimeEstimate int `json:"time_estimate"`
|
||||
TotalTimeSpent int `json:"total_time_spent"`
|
||||
}
|
||||
|
||||
func (t TimeStats) String() string {
|
||||
return Stringify(t)
|
||||
}
|
||||
|
||||
// SetTimeEstimateOptions represents the available SetTimeEstimate()
|
||||
// options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/issues.html#set-a-time-estimate-for-an-issue
|
||||
type SetTimeEstimateOptions struct {
|
||||
Duration *string `url:"duration,omitempty" json:"duration,omitempty"`
|
||||
}
|
||||
|
||||
// SetTimeEstimate sets the time estimate for a single project issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/issues.html#set-a-time-estimate-for-an-issue
|
||||
func (s *TimeStatsService) SetTimeEstimate(pid interface{}, issue int, opt *SetTimeEstimateOptions, options ...OptionFunc) (*TimeStats, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d/time_estimate", url.QueryEscape(project), issue)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
t := new(TimeStats)
|
||||
resp, err := s.client.Do(req, t)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return t, resp, err
|
||||
}
|
||||
|
||||
// ResetTimeEstimate resets the time estimate for a single project issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/issues.html#reset-the-time-estimate-for-an-issue
|
||||
func (s *TimeStatsService) ResetTimeEstimate(pid interface{}, issue int, options ...OptionFunc) (*TimeStats, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d/reset_time_estimate", url.QueryEscape(project), issue)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
t := new(TimeStats)
|
||||
resp, err := s.client.Do(req, t)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return t, resp, err
|
||||
}
|
||||
|
||||
// AddSpentTimeOptions represents the available AddSpentTime() options.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/issues.html#add-spent-time-for-an-issue
|
||||
type AddSpentTimeOptions struct {
|
||||
Duration *string `url:"duration,omitempty" json:"duration,omitempty"`
|
||||
}
|
||||
|
||||
// AddSpentTime adds spent time for a single project issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/issues.html#add-spent-time-for-an-issue
|
||||
func (s *TimeStatsService) AddSpentTime(pid interface{}, issue int, opt *AddSpentTimeOptions, options ...OptionFunc) (*TimeStats, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d/add_spent_time", url.QueryEscape(project), issue)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
t := new(TimeStats)
|
||||
resp, err := s.client.Do(req, t)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return t, resp, err
|
||||
}
|
||||
|
||||
// ResetSpentTime resets the spent time for a single project issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/issues.html#reset-spent-time-for-an-issue
|
||||
func (s *TimeStatsService) ResetSpentTime(pid interface{}, issue int, options ...OptionFunc) (*TimeStats, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d/reset_spent_time", url.QueryEscape(project), issue)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
t := new(TimeStats)
|
||||
resp, err := s.client.Do(req, t)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return t, resp, err
|
||||
}
|
||||
|
||||
// GetTimeSpent gets the spent time for a single project issue.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/issues.html#get-time-tracking-stats
|
||||
func (s *TimeStatsService) GetTimeSpent(pid interface{}, issue int, options ...OptionFunc) (*TimeStats, *Response, error) {
|
||||
project, err := parseID(pid)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
u := fmt.Sprintf("projects/%s/issues/%d/time_stats", url.QueryEscape(project), issue)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
t := new(TimeStats)
|
||||
resp, err := s.client.Do(req, t)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return t, resp, err
|
||||
}
|
|
@ -0,0 +1,584 @@
|
|||
//
|
||||
// Copyright 2015, 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 (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// UsersService handles communication with the user related methods of
|
||||
// the GitLab API.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html
|
||||
type UsersService struct {
|
||||
client *Client
|
||||
}
|
||||
|
||||
// User represents a GitLab user.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html
|
||||
type User struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Name string `json:"name"`
|
||||
State string `json:"state"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
Bio string `json:"bio"`
|
||||
Skype string `json:"skype"`
|
||||
Linkedin string `json:"linkedin"`
|
||||
Twitter string `json:"twitter"`
|
||||
WebsiteURL string `json:"website_url"`
|
||||
ExternUID string `json:"extern_uid"`
|
||||
Provider string `json:"provider"`
|
||||
ThemeID int `json:"theme_id"`
|
||||
ColorSchemeID int `json:"color_scheme_id"`
|
||||
IsAdmin bool `json:"is_admin"`
|
||||
AvatarURL string `json:"avatar_url"`
|
||||
CanCreateGroup bool `json:"can_create_group"`
|
||||
CanCreateProject bool `json:"can_create_project"`
|
||||
ProjectsLimit int `json:"projects_limit"`
|
||||
CurrentSignInAt *time.Time `json:"current_sign_in_at"`
|
||||
LastSignInAt *time.Time `json:"last_sign_in_at"`
|
||||
TwoFactorEnabled bool `json:"two_factor_enabled"`
|
||||
Identities []*UserIdentity `json:"identities"`
|
||||
}
|
||||
|
||||
// UserIdentity represents a user identity
|
||||
type UserIdentity struct {
|
||||
Provider string `json:"provider"`
|
||||
ExternUID string `json:"extern_uid"`
|
||||
}
|
||||
|
||||
// ListUsersOptions represents the available ListUsers() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#list-users
|
||||
type ListUsersOptions struct {
|
||||
ListOptions
|
||||
Active *bool `url:"active,omitempty" json:"active,omitempty"`
|
||||
Search *string `url:"search,omitempty" json:"search,omitempty"`
|
||||
Username *string `url:"username,omitempty" json:"username,omitempty"`
|
||||
}
|
||||
|
||||
// ListUsers gets a list of users.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#list-users
|
||||
func (s *UsersService) ListUsers(opt *ListUsersOptions, options ...OptionFunc) ([]*User, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "users", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var usr []*User
|
||||
resp, err := s.client.Do(req, &usr)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return usr, resp, err
|
||||
}
|
||||
|
||||
// GetUser gets a single user.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#single-user
|
||||
func (s *UsersService) GetUser(user int, options ...OptionFunc) (*User, *Response, error) {
|
||||
u := fmt.Sprintf("users/%d", user)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
usr := new(User)
|
||||
resp, err := s.client.Do(req, usr)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return usr, resp, err
|
||||
}
|
||||
|
||||
// CreateUserOptions represents the available CreateUser() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#user-creation
|
||||
type CreateUserOptions struct {
|
||||
Email *string `url:"email,omitempty" json:"email,omitempty"`
|
||||
Password *string `url:"password,omitempty" json:"password,omitempty"`
|
||||
Username *string `url:"username,omitempty" json:"username,omitempty"`
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Skype *string `url:"skype,omitempty" json:"skype,omitempty"`
|
||||
Linkedin *string `url:"linkedin,omitempty" json:"linkedin,omitempty"`
|
||||
Twitter *string `url:"twitter,omitempty" json:"twitter,omitempty"`
|
||||
WebsiteURL *string `url:"website_url,omitempty" json:"website_url,omitempty"`
|
||||
ProjectsLimit *int `url:"projects_limit,omitempty" json:"projects_limit,omitempty"`
|
||||
ExternUID *string `url:"extern_uid,omitempty" json:"extern_uid,omitempty"`
|
||||
Provider *string `url:"provider,omitempty" json:"provider,omitempty"`
|
||||
Bio *string `url:"bio,omitempty" json:"bio,omitempty"`
|
||||
Admin *bool `url:"admin,omitempty" json:"admin,omitempty"`
|
||||
CanCreateGroup *bool `url:"can_create_group,omitempty" json:"can_create_group,omitempty"`
|
||||
Confirm *bool `url:"confirm,omitempty" json:"confirm,omitempty"`
|
||||
}
|
||||
|
||||
// CreateUser creates a new user. Note only administrators can create new users.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#user-creation
|
||||
func (s *UsersService) CreateUser(opt *CreateUserOptions, options ...OptionFunc) (*User, *Response, error) {
|
||||
req, err := s.client.NewRequest("POST", "users", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
usr := new(User)
|
||||
resp, err := s.client.Do(req, usr)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return usr, resp, err
|
||||
}
|
||||
|
||||
// ModifyUserOptions represents the available ModifyUser() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#user-modification
|
||||
type ModifyUserOptions struct {
|
||||
Email *string `url:"email,omitempty" json:"email,omitempty"`
|
||||
Password *string `url:"password,omitempty" json:"password,omitempty"`
|
||||
Username *string `url:"username,omitempty" json:"username,omitempty"`
|
||||
Name *string `url:"name,omitempty" json:"name,omitempty"`
|
||||
Skype *string `url:"skype,omitempty" json:"skype,omitempty"`
|
||||
Linkedin *string `url:"linkedin,omitempty" json:"linkedin,omitempty"`
|
||||
Twitter *string `url:"twitter,omitempty" json:"twitter,omitempty"`
|
||||
WebsiteURL *string `url:"website_url,omitempty" json:"website_url,omitempty"`
|
||||
ProjectsLimit *int `url:"projects_limit,omitempty" json:"projects_limit,omitempty"`
|
||||
ExternUID *string `url:"extern_uid,omitempty" json:"extern_uid,omitempty"`
|
||||
Provider *string `url:"provider,omitempty" json:"provider,omitempty"`
|
||||
Bio *string `url:"bio,omitempty" json:"bio,omitempty"`
|
||||
Admin *bool `url:"admin,omitempty" json:"admin,omitempty"`
|
||||
CanCreateGroup *bool `url:"can_create_group,omitempty" json:"can_create_group,omitempty"`
|
||||
}
|
||||
|
||||
// ModifyUser modifies an existing user. Only administrators can change attributes
|
||||
// of a user.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#user-modification
|
||||
func (s *UsersService) ModifyUser(user int, opt *ModifyUserOptions, options ...OptionFunc) (*User, *Response, error) {
|
||||
u := fmt.Sprintf("users/%d", user)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
usr := new(User)
|
||||
resp, err := s.client.Do(req, usr)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return usr, resp, err
|
||||
}
|
||||
|
||||
// DeleteUser deletes a user. Available only for administrators. This is an
|
||||
// idempotent function, calling this function for a non-existent user id still
|
||||
// returns a status code 200 OK. The JSON response differs if the user was
|
||||
// actually deleted or not. In the former the user is returned and in the
|
||||
// latter not.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#user-deletion
|
||||
func (s *UsersService) DeleteUser(user int, options ...OptionFunc) (*Response, error) {
|
||||
u := fmt.Sprintf("users/%d", user)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// CurrentUser gets currently authenticated user.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#current-user
|
||||
func (s *UsersService) CurrentUser(options ...OptionFunc) (*User, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "user", nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
usr := new(User)
|
||||
resp, err := s.client.Do(req, usr)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return usr, resp, err
|
||||
}
|
||||
|
||||
// SSHKey represents a SSH key.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#list-ssh-keys
|
||||
type SSHKey struct {
|
||||
ID int `json:"id"`
|
||||
Title string `json:"title"`
|
||||
Key string `json:"key"`
|
||||
CreatedAt *time.Time `json:"created_at"`
|
||||
}
|
||||
|
||||
// ListSSHKeys gets a list of currently authenticated user's SSH keys.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#list-ssh-keys
|
||||
func (s *UsersService) ListSSHKeys(options ...OptionFunc) ([]*SSHKey, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "user/keys", nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var k []*SSHKey
|
||||
resp, err := s.client.Do(req, &k)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return k, resp, err
|
||||
}
|
||||
|
||||
// ListSSHKeysForUser gets a list of a specified user's SSH keys. Available
|
||||
// only for admin
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/users.html#list-ssh-keys-for-user
|
||||
func (s *UsersService) ListSSHKeysForUser(user int, options ...OptionFunc) ([]*SSHKey, *Response, error) {
|
||||
u := fmt.Sprintf("users/%d/keys", user)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var k []*SSHKey
|
||||
resp, err := s.client.Do(req, &k)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return k, resp, err
|
||||
}
|
||||
|
||||
// GetSSHKey gets a single key.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#single-ssh-key
|
||||
func (s *UsersService) GetSSHKey(kid int, options ...OptionFunc) (*SSHKey, *Response, error) {
|
||||
u := fmt.Sprintf("user/keys/%d", kid)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
k := new(SSHKey)
|
||||
resp, err := s.client.Do(req, k)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return k, resp, err
|
||||
}
|
||||
|
||||
// AddSSHKeyOptions represents the available AddSSHKey() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#add-ssh-key
|
||||
type AddSSHKeyOptions struct {
|
||||
Title *string `url:"title,omitempty" json:"title,omitempty"`
|
||||
Key *string `url:"key,omitempty" json:"key,omitempty"`
|
||||
}
|
||||
|
||||
// AddSSHKey creates a new key owned by the currently authenticated user.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#add-ssh-key
|
||||
func (s *UsersService) AddSSHKey(opt *AddSSHKeyOptions, options ...OptionFunc) (*SSHKey, *Response, error) {
|
||||
req, err := s.client.NewRequest("POST", "user/keys", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
k := new(SSHKey)
|
||||
resp, err := s.client.Do(req, k)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return k, resp, err
|
||||
}
|
||||
|
||||
// AddSSHKeyForUser creates new key owned by specified user. Available only for
|
||||
// admin.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#add-ssh-key-for-user
|
||||
func (s *UsersService) AddSSHKeyForUser(user int, opt *AddSSHKeyOptions, options ...OptionFunc) (*SSHKey, *Response, error) {
|
||||
u := fmt.Sprintf("users/%d/keys", user)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
k := new(SSHKey)
|
||||
resp, err := s.client.Do(req, k)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return k, resp, err
|
||||
}
|
||||
|
||||
// DeleteSSHKey deletes key owned by currently authenticated user. This is an
|
||||
// idempotent function and calling it on a key that is already deleted or not
|
||||
// available results in 200 OK.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/users.html#delete-ssh-key-for-current-owner
|
||||
func (s *UsersService) DeleteSSHKey(kid int, options ...OptionFunc) (*Response, error) {
|
||||
u := fmt.Sprintf("user/keys/%d", kid)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// DeleteSSHKeyForUser deletes key owned by a specified user. Available only
|
||||
// for admin.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/users.html#delete-ssh-key-for-given-user
|
||||
func (s *UsersService) DeleteSSHKeyForUser(user int, kid int, options ...OptionFunc) (*Response, error) {
|
||||
u := fmt.Sprintf("users/%d/keys/%d", user, kid)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// BlockUser blocks the specified user. Available only for admin.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#block-user
|
||||
func (s *UsersService) BlockUser(user int, options ...OptionFunc) error {
|
||||
u := fmt.Sprintf("users/%d/block", user)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, nil, options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch resp.StatusCode {
|
||||
case 200:
|
||||
return nil
|
||||
case 403:
|
||||
return errors.New("Cannot block a user that is already blocked by LDAP synchronization")
|
||||
case 404:
|
||||
return errors.New("User does not exists")
|
||||
default:
|
||||
return fmt.Errorf("Received unexpected result code: %d", resp.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
// UnblockUser unblocks the specified user. Available only for admin.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#unblock-user
|
||||
func (s *UsersService) UnblockUser(user int, options ...OptionFunc) error {
|
||||
u := fmt.Sprintf("users/%d/unblock", user)
|
||||
|
||||
req, err := s.client.NewRequest("PUT", u, nil, options)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resp, err := s.client.Do(req, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch resp.StatusCode {
|
||||
case 200:
|
||||
return nil
|
||||
case 403:
|
||||
return errors.New("Cannot unblock a user that is blocked by LDAP synchronization")
|
||||
case 404:
|
||||
return errors.New("User does not exists")
|
||||
default:
|
||||
return fmt.Errorf("Received unexpected result code: %d", resp.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
// Email represents an Email.
|
||||
//
|
||||
// GitLab API docs: https://doc.gitlab.com/ce/api/users.html#list-emails
|
||||
type Email struct {
|
||||
ID int `json:"id"`
|
||||
Email string `json:"email"`
|
||||
}
|
||||
|
||||
// ListEmails gets a list of currently authenticated user's Emails.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#list-emails
|
||||
func (s *UsersService) ListEmails(options ...OptionFunc) ([]*Email, *Response, error) {
|
||||
req, err := s.client.NewRequest("GET", "user/emails", nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var e []*Email
|
||||
resp, err := s.client.Do(req, &e)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return e, resp, err
|
||||
}
|
||||
|
||||
// ListEmailsForUser gets a list of a specified user's Emails. Available
|
||||
// only for admin
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/users.html#list-emails-for-user
|
||||
func (s *UsersService) ListEmailsForUser(uid int, options ...OptionFunc) ([]*Email, *Response, error) {
|
||||
u := fmt.Sprintf("users/%d/emails", uid)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
var e []*Email
|
||||
resp, err := s.client.Do(req, &e)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return e, resp, err
|
||||
}
|
||||
|
||||
// GetEmail gets a single email.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#single-email
|
||||
func (s *UsersService) GetEmail(eid int, options ...OptionFunc) (*Email, *Response, error) {
|
||||
u := fmt.Sprintf("user/emails/%d", eid)
|
||||
|
||||
req, err := s.client.NewRequest("GET", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
e := new(Email)
|
||||
resp, err := s.client.Do(req, e)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return e, resp, err
|
||||
}
|
||||
|
||||
// AddEmailOptions represents the available AddEmail() options.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/projects.html#add-email
|
||||
type AddEmailOptions struct {
|
||||
Email *string `url:"email,omitempty" json:"email,omitempty"`
|
||||
}
|
||||
|
||||
// AddEmail creates a new email owned by the currently authenticated user.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#add-email
|
||||
func (s *UsersService) AddEmail(opt *AddEmailOptions, options ...OptionFunc) (*Email, *Response, error) {
|
||||
req, err := s.client.NewRequest("POST", "user/emails", opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
e := new(Email)
|
||||
resp, err := s.client.Do(req, e)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return e, resp, err
|
||||
}
|
||||
|
||||
// AddEmailForUser creates new email owned by specified user. Available only for
|
||||
// admin.
|
||||
//
|
||||
// GitLab API docs: https://docs.gitlab.com/ce/api/users.html#add-email-for-user
|
||||
func (s *UsersService) AddEmailForUser(uid int, opt *AddEmailOptions, options ...OptionFunc) (*Email, *Response, error) {
|
||||
u := fmt.Sprintf("users/%d/emails", uid)
|
||||
|
||||
req, err := s.client.NewRequest("POST", u, opt, options)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
e := new(Email)
|
||||
resp, err := s.client.Do(req, e)
|
||||
if err != nil {
|
||||
return nil, resp, err
|
||||
}
|
||||
|
||||
return e, resp, err
|
||||
}
|
||||
|
||||
// DeleteEmail deletes email owned by currently authenticated user. This is an
|
||||
// idempotent function and calling it on a key that is already deleted or not
|
||||
// available results in 200 OK.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/users.html#delete-email-for-current-owner
|
||||
func (s *UsersService) DeleteEmail(eid int, options ...OptionFunc) (*Response, error) {
|
||||
u := fmt.Sprintf("user/emails/%d", eid)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
||||
|
||||
// DeleteEmailForUser deletes email owned by a specified user. Available only
|
||||
// for admin.
|
||||
//
|
||||
// GitLab API docs:
|
||||
// https://docs.gitlab.com/ce/api/users.html#delete-email-for-given-user
|
||||
func (s *UsersService) DeleteEmailForUser(uid int, eid int, options ...OptionFunc) (*Response, error) {
|
||||
u := fmt.Sprintf("users/%d/emails/%d", uid, eid)
|
||||
|
||||
req, err := s.client.NewRequest("DELETE", u, nil, options)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return s.client.Do(req, nil)
|
||||
}
|
|
@ -3075,6 +3075,12 @@
|
|||
"revision": "deca6e17c056012b540aa2d2eae3ea1e63203b85",
|
||||
"revisionTime": "2016-10-26T18:16:49Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "1mR4/KWIQEL8rzyDlCR4CRrTqGQ=",
|
||||
"path": "github.com/xanzy/go-gitlab",
|
||||
"revision": "5b756e2fdc9f21fd4791fa1453b8fe01af0f82e2",
|
||||
"revisionTime": "2017-03-22T12:21:15Z"
|
||||
},
|
||||
{
|
||||
"checksumSHA1": "iHiMTBffQvWYlOLu3130JXuQpgQ=",
|
||||
"path": "github.com/xanzy/ssh-agent",
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
---
|
||||
layout: "gitlab"
|
||||
page_title: "Provider: GitLab"
|
||||
sidebar_current: "docs-gitlab-index"
|
||||
description: |-
|
||||
The GitLab provider is used to interact with GitLab organization resources.
|
||||
---
|
||||
|
||||
# GitLab Provider
|
||||
|
||||
The GitLab provider is used to interact with GitLab organization resources.
|
||||
|
||||
The provider allows you to manage your GitLab organization's members and teams easily.
|
||||
It needs to be configured with the proper credentials before it can be used.
|
||||
|
||||
Use the navigation to the left to read about the available resources.
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
# Configure the GitLab Provider
|
||||
provider "gitlab" {
|
||||
token = "${var.github_token}"
|
||||
}
|
||||
|
||||
# Add a project to the organization
|
||||
resource "gitlab_project" "sample_project" {
|
||||
...
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported in the `provider` block:
|
||||
|
||||
* `token` - (Optional) This is the GitLab personal access token. It must be provided, but
|
||||
it can also be sourced from the `GITLAB_TOKEN` environment variable.
|
||||
|
||||
* `base_url` - (Optional) This is the target GitLab base API endpoint. Providing a value is a
|
||||
requirement when working with GitLab CE or GitLab Enterprise. It is optional to provide this value and
|
||||
it can also be sourced from the `GITLAB_BASE_URL` environment variable. The value must end with a slash.
|
|
@ -0,0 +1,58 @@
|
|||
---
|
||||
layout: "gitlab"
|
||||
page_title: "GitLab: gitlab_project"
|
||||
sidebar_current: "docs-gitlab-resource-project"
|
||||
description: |-
|
||||
Creates and manages projects within Github organizations
|
||||
---
|
||||
|
||||
# gitlab\_project
|
||||
|
||||
This resource allows you to create and manage projects within your
|
||||
GitLab organization.
|
||||
|
||||
|
||||
## Example Usage
|
||||
|
||||
```
|
||||
resource "gitlab_repository" "example" {
|
||||
name = "example"
|
||||
description = "My awesome codebase"
|
||||
|
||||
visbility_level = "public"
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `name` - (Required) The name of the project.
|
||||
|
||||
* `description` - (Optional) A description of the project.
|
||||
|
||||
* `default_branch` - (Optional) The default branch for the project.
|
||||
|
||||
* `issues_enabled` - (Optional) Enable issue tracking for the project.
|
||||
|
||||
* `merge_requests_enabled` - (Optional) Enable merge requests for the project.
|
||||
|
||||
* `wiki_enabled` - (Optional) Enable wiki for the project.
|
||||
|
||||
* `snippets_enabled` - (Optional) Enable snippets for the project.
|
||||
|
||||
* `visbility_level` - (Optional) Set to `public` to create a public project.
|
||||
Valid values are `private`, `internal`, `public`.
|
||||
Repositories are created as private by default.
|
||||
|
||||
## Attributes Reference
|
||||
|
||||
The following additional attributes are exported:
|
||||
|
||||
* `ssh_url_to_repo` - URL that can be provided to `git clone` to clone the
|
||||
repository via SSH.
|
||||
|
||||
* `http_url_to_repo` - URL that can be provided to `git clone` to clone the
|
||||
repository via HTTP.
|
||||
|
||||
* `web_url` - URL that can be used to find the project in a browser.
|
Loading…
Reference in New Issue