From ef7c88ab25ec352cb3202e181aee401460cd5046 Mon Sep 17 00:00:00 2001 From: Martin Fernandez Date: Fri, 14 Dec 2018 00:40:50 -0300 Subject: [PATCH] Add new options to project resource New options: - merge_method - only_allow_merge_if_pipeline_succeeds - only_allow_merge_if_all_discussions_are_resolved --- gitlab/resource_gitlab_project.go | 48 ++++++-- gitlab/resource_gitlab_project_test.go | 155 ++++++++++++++++--------- gitlab/util.go | 19 ++- website/docs/r/project.html.markdown | 8 ++ 4 files changed, 165 insertions(+), 65 deletions(-) diff --git a/gitlab/resource_gitlab_project.go b/gitlab/resource_gitlab_project.go index 141558e29..6bccf02e3 100644 --- a/gitlab/resource_gitlab_project.go +++ b/gitlab/resource_gitlab_project.go @@ -76,7 +76,22 @@ func resourceGitlabProject() *schema.Resource { ValidateFunc: validation.StringInSlice([]string{"private", "internal", "public"}, true), Default: "private", }, - + "merge_method": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"merge", "rebase_merge", "ff"}, true), + Default: "merge", + }, + "only_allow_merge_if_pipeline_succeeds": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "only_allow_merge_if_all_discussions_are_resolved": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, "ssh_url_to_repo": { Type: schema.TypeString, Computed: true, @@ -130,8 +145,10 @@ func resourceGitlabProjectSetToState(d *schema.ResourceData, project *gitlab.Pro d.Set("wiki_enabled", project.WikiEnabled) d.Set("snippets_enabled", project.SnippetsEnabled) d.Set("visibility_level", string(project.Visibility)) + d.Set("merge_method", string(project.MergeMethod)) + d.Set("only_allow_merge_if_pipeline_succeeds", project.OnlyAllowMergeIfPipelineSucceeds) + d.Set("only_allow_merge_if_all_discussions_are_resolved", project.OnlyAllowMergeIfAllDiscussionsAreResolved) d.Set("namespace_id", project.Namespace.ID) - d.Set("ssh_url_to_repo", project.SSHURLToRepo) d.Set("http_url_to_repo", project.HTTPURLToRepo) d.Set("web_url", project.WebURL) @@ -142,12 +159,15 @@ func resourceGitlabProjectSetToState(d *schema.ResourceData, project *gitlab.Pro func resourceGitlabProjectCreate(d *schema.ResourceData, meta interface{}) error { client := meta.(*gitlab.Client) options := &gitlab.CreateProjectOptions{ - Name: gitlab.String(d.Get("name").(string)), - IssuesEnabled: gitlab.Bool(d.Get("issues_enabled").(bool)), - MergeRequestsEnabled: gitlab.Bool(d.Get("merge_requests_enabled").(bool)), - WikiEnabled: gitlab.Bool(d.Get("wiki_enabled").(bool)), - SnippetsEnabled: gitlab.Bool(d.Get("snippets_enabled").(bool)), - Visibility: stringToVisibilityLevel(d.Get("visibility_level").(string)), + Name: gitlab.String(d.Get("name").(string)), + IssuesEnabled: gitlab.Bool(d.Get("issues_enabled").(bool)), + MergeRequestsEnabled: gitlab.Bool(d.Get("merge_requests_enabled").(bool)), + WikiEnabled: gitlab.Bool(d.Get("wiki_enabled").(bool)), + SnippetsEnabled: gitlab.Bool(d.Get("snippets_enabled").(bool)), + Visibility: stringToVisibilityLevel(d.Get("visibility_level").(string)), + MergeMethod: stringToMergeMethod(d.Get("merge_method").(string)), + OnlyAllowMergeIfPipelineSucceeds: gitlab.Bool(d.Get("only_allow_merge_if_pipeline_succeeds").(bool)), + OnlyAllowMergeIfAllDiscussionsAreResolved: gitlab.Bool(d.Get("only_allow_merge_if_all_discussions_are_resolved").(bool)), } if v, ok := d.GetOk("path"); ok { @@ -229,6 +249,18 @@ func resourceGitlabProjectUpdate(d *schema.ResourceData, meta interface{}) error options.Visibility = stringToVisibilityLevel(d.Get("visibility_level").(string)) } + if d.HasChange("merge_method") { + options.MergeMethod = stringToMergeMethod(d.Get("merge_method").(string)) + } + + if d.HasChange("only_allow_merge_if_pipeline_succeeds") { + options.OnlyAllowMergeIfPipelineSucceeds = gitlab.Bool(d.Get("only_allow_merge_if_pipeline_succeeds").(bool)) + } + + if d.HasChange("only_allow_merge_if_all_discussions_are_resolved") { + options.OnlyAllowMergeIfAllDiscussionsAreResolved = gitlab.Bool(d.Get("only_allow_merge_if_all_discussions_are_resolved").(bool)) + } + if d.HasChange("issues_enabled") { options.IssuesEnabled = gitlab.Bool(d.Get("issues_enabled").(bool)) } diff --git a/gitlab/resource_gitlab_project_test.go b/gitlab/resource_gitlab_project_test.go index fc476d340..81ceee300 100644 --- a/gitlab/resource_gitlab_project_test.go +++ b/gitlab/resource_gitlab_project_test.go @@ -25,14 +25,17 @@ func TestAccGitlabProject_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckGitlabProjectExists("gitlab_project.foo", &project), testAccCheckGitlabProjectAttributes(&project, &testAccGitlabProjectExpectedAttributes{ - Name: fmt.Sprintf("foo-%d", rInt), - Path: fmt.Sprintf("foo.%d", rInt), - Description: "Terraform acceptance tests", - IssuesEnabled: true, - MergeRequestsEnabled: true, - WikiEnabled: true, - SnippetsEnabled: true, - Visibility: gitlab.PublicVisibility, + Name: fmt.Sprintf("foo-%d", rInt), + Path: fmt.Sprintf("foo.%d", rInt), + Description: "Terraform acceptance tests", + IssuesEnabled: true, + MergeRequestsEnabled: true, + WikiEnabled: true, + SnippetsEnabled: true, + Visibility: gitlab.PublicVisibility, + MergeMethod: gitlab.FastForwardMerge, + OnlyAllowMergeIfPipelineSucceeds: true, + OnlyAllowMergeIfAllDiscussionsAreResolved: true, }), ), }, @@ -42,27 +45,33 @@ func TestAccGitlabProject_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckGitlabProjectExists("gitlab_project.foo", &project), testAccCheckGitlabProjectAttributes(&project, &testAccGitlabProjectExpectedAttributes{ - Name: fmt.Sprintf("foo-%d", rInt), - Path: fmt.Sprintf("foo.%d", rInt), - Description: "Terraform acceptance tests!", - Visibility: gitlab.PublicVisibility, + Name: fmt.Sprintf("foo-%d", rInt), + Path: fmt.Sprintf("foo.%d", rInt), + Description: "Terraform acceptance tests!", + Visibility: gitlab.PublicVisibility, + MergeMethod: gitlab.FastForwardMerge, + OnlyAllowMergeIfPipelineSucceeds: true, + OnlyAllowMergeIfAllDiscussionsAreResolved: true, }), ), }, - //Update the project to turn the features on again + // Update the project to turn the features on again { Config: testAccGitlabProjectConfig(rInt), Check: resource.ComposeTestCheckFunc( testAccCheckGitlabProjectExists("gitlab_project.foo", &project), testAccCheckGitlabProjectAttributes(&project, &testAccGitlabProjectExpectedAttributes{ - Name: fmt.Sprintf("foo-%d", rInt), - Path: fmt.Sprintf("foo.%d", rInt), - Description: "Terraform acceptance tests", - IssuesEnabled: true, - MergeRequestsEnabled: true, - WikiEnabled: true, - SnippetsEnabled: true, - Visibility: gitlab.PublicVisibility, + Name: fmt.Sprintf("foo-%d", rInt), + Path: fmt.Sprintf("foo.%d", rInt), + Description: "Terraform acceptance tests", + IssuesEnabled: true, + MergeRequestsEnabled: true, + WikiEnabled: true, + SnippetsEnabled: true, + Visibility: gitlab.PublicVisibility, + MergeMethod: gitlab.FastForwardMerge, + OnlyAllowMergeIfPipelineSucceeds: true, + OnlyAllowMergeIfAllDiscussionsAreResolved: true, }), ), }, @@ -72,14 +81,17 @@ func TestAccGitlabProject_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckGitlabProjectExists("gitlab_project.foo", &project), testAccCheckGitlabProjectAttributes(&project, &testAccGitlabProjectExpectedAttributes{ - Name: fmt.Sprintf("foo-%d", rInt), - Path: fmt.Sprintf("foo.%d", rInt), - Description: "Terraform acceptance tests", - IssuesEnabled: true, - MergeRequestsEnabled: true, - WikiEnabled: true, - SnippetsEnabled: true, - Visibility: gitlab.PublicVisibility, + Name: fmt.Sprintf("foo-%d", rInt), + Path: fmt.Sprintf("foo.%d", rInt), + Description: "Terraform acceptance tests", + IssuesEnabled: true, + MergeRequestsEnabled: true, + WikiEnabled: true, + SnippetsEnabled: true, + Visibility: gitlab.PublicVisibility, + MergeMethod: gitlab.FastForwardMerge, + OnlyAllowMergeIfPipelineSucceeds: false, + OnlyAllowMergeIfAllDiscussionsAreResolved: false, SharedWithGroups: []struct { GroupID int GroupName string @@ -94,14 +106,17 @@ func TestAccGitlabProject_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckGitlabProjectExists("gitlab_project.foo", &project), testAccCheckGitlabProjectAttributes(&project, &testAccGitlabProjectExpectedAttributes{ - Name: fmt.Sprintf("foo-%d", rInt), - Path: fmt.Sprintf("foo.%d", rInt), - Description: "Terraform acceptance tests", - IssuesEnabled: true, - MergeRequestsEnabled: true, - WikiEnabled: true, - SnippetsEnabled: true, - Visibility: gitlab.PublicVisibility, + Name: fmt.Sprintf("foo-%d", rInt), + Path: fmt.Sprintf("foo.%d", rInt), + Description: "Terraform acceptance tests", + IssuesEnabled: true, + MergeRequestsEnabled: true, + WikiEnabled: true, + SnippetsEnabled: true, + Visibility: gitlab.PublicVisibility, + MergeMethod: gitlab.FastForwardMerge, + OnlyAllowMergeIfPipelineSucceeds: false, + OnlyAllowMergeIfAllDiscussionsAreResolved: false, SharedWithGroups: []struct { GroupID int GroupName string @@ -116,14 +131,17 @@ func TestAccGitlabProject_basic(t *testing.T) { Check: resource.ComposeTestCheckFunc( testAccCheckGitlabProjectExists("gitlab_project.foo", &project), testAccCheckGitlabProjectAttributes(&project, &testAccGitlabProjectExpectedAttributes{ - Name: fmt.Sprintf("foo-%d", rInt), - Path: fmt.Sprintf("foo.%d", rInt), - Description: "Terraform acceptance tests", - IssuesEnabled: true, - MergeRequestsEnabled: true, - WikiEnabled: true, - SnippetsEnabled: true, - Visibility: gitlab.PublicVisibility, + Name: fmt.Sprintf("foo-%d", rInt), + Path: fmt.Sprintf("foo.%d", rInt), + Description: "Terraform acceptance tests", + IssuesEnabled: true, + MergeRequestsEnabled: true, + WikiEnabled: true, + SnippetsEnabled: true, + Visibility: gitlab.PublicVisibility, + MergeMethod: gitlab.FastForwardMerge, + OnlyAllowMergeIfPipelineSucceeds: true, + OnlyAllowMergeIfAllDiscussionsAreResolved: true, SharedWithGroups: []struct { GroupID int GroupName string @@ -199,16 +217,19 @@ func testAccCheckGitlabProjectExists(n string, project *gitlab.Project) resource } type testAccGitlabProjectExpectedAttributes struct { - Name string - Path string - Description string - DefaultBranch string - IssuesEnabled bool - MergeRequestsEnabled bool - WikiEnabled bool - SnippetsEnabled bool - Visibility gitlab.VisibilityValue - SharedWithGroups []struct { + Name string + Path string + Description string + DefaultBranch string + IssuesEnabled bool + MergeRequestsEnabled bool + WikiEnabled bool + SnippetsEnabled bool + Visibility gitlab.VisibilityValue + MergeMethod gitlab.MergeMethodValue + OnlyAllowMergeIfPipelineSucceeds bool + OnlyAllowMergeIfAllDiscussionsAreResolved bool + SharedWithGroups []struct { GroupID int GroupName string GroupAccessLevel int @@ -257,6 +278,18 @@ func testAccCheckGitlabProjectAttributes(project *gitlab.Project, want *testAccG } } + if project.MergeMethod != want.MergeMethod { + return fmt.Errorf("got merge_method %q; want %q", project.MergeMethod, want.MergeMethod) + } + + if project.OnlyAllowMergeIfPipelineSucceeds != want.OnlyAllowMergeIfPipelineSucceeds { + return fmt.Errorf("got only_allow_merge_if_pipeline_succeeds %t; want %t", project.OnlyAllowMergeIfPipelineSucceeds, want.OnlyAllowMergeIfPipelineSucceeds) + } + + if project.OnlyAllowMergeIfAllDiscussionsAreResolved != want.OnlyAllowMergeIfAllDiscussionsAreResolved { + return fmt.Errorf("got only_allow_merge_if_all_discussions_are_resolved %t; want %t", project.OnlyAllowMergeIfAllDiscussionsAreResolved, want.OnlyAllowMergeIfAllDiscussionsAreResolved) + } + return nil } } @@ -313,6 +346,9 @@ resource "gitlab_project" "foo" { # So that acceptance tests can be run in a gitlab organization # with no billing visibility_level = "public" + merge_method = "ff" + only_allow_merge_if_pipeline_succeeds = true + only_allow_merge_if_all_discussions_are_resolved = true } `, rInt, rInt) } @@ -327,6 +363,9 @@ resource "gitlab_project" "foo" { # So that acceptance tests can be run in a gitlab organization # with no billing visibility_level = "public" + merge_method = "ff" + only_allow_merge_if_pipeline_succeeds = true + only_allow_merge_if_all_discussions_are_resolved = true issues_enabled = false merge_requests_enabled = false @@ -343,6 +382,9 @@ resource "gitlab_project" "foo" { path = "foo.%d" description = "Terraform acceptance tests" visibility_level = "public" + merge_method = "ff" + only_allow_merge_if_pipeline_succeeds = false + only_allow_merge_if_all_discussions_are_resolved = false shared_with_groups = [ { @@ -368,6 +410,9 @@ resource "gitlab_project" "foo" { path = "foo.%d" description = "Terraform acceptance tests" visibility_level = "public" + merge_method = "ff" + only_allow_merge_if_pipeline_succeeds = false + only_allow_merge_if_all_discussions_are_resolved = false shared_with_groups = [ { diff --git a/gitlab/util.go b/gitlab/util.go index 401156a1b..afe311f30 100644 --- a/gitlab/util.go +++ b/gitlab/util.go @@ -3,11 +3,12 @@ package gitlab import ( "fmt" - "github.com/hashicorp/terraform/helper/schema" - "github.com/xanzy/go-gitlab" "regexp" "strings" "time" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/xanzy/go-gitlab" ) var accessLevelNameToValue = map[string]gitlab.AccessLevelValue{ @@ -71,6 +72,20 @@ func stringToVisibilityLevel(s string) *gitlab.VisibilityValue { return &value } +func stringToMergeMethod(s string) *gitlab.MergeMethodValue { + lookup := map[string]gitlab.MergeMethodValue{ + "merge": gitlab.NoFastForwardMerge, + "ff": gitlab.FastForwardMerge, + "rebase_merge": gitlab.RebaseMerge, + } + + value, ok := lookup[s] + if !ok { + return nil + } + return &value +} + func StringIsGitlabVariableName() schema.SchemaValidateFunc { return func(v interface{}, k string) (s []string, es []error) { value, ok := v.(string) diff --git a/website/docs/r/project.html.markdown b/website/docs/r/project.html.markdown index 9960d474c..4401e1c48 100644 --- a/website/docs/r/project.html.markdown +++ b/website/docs/r/project.html.markdown @@ -50,6 +50,14 @@ The following arguments are supported: Valid values are `private`, `internal`, `public`. Repositories are created as private by default. +* `merge_method` - (Optional) Set to `ff` to create fast-forward merges + Valid values are `merge`, `rebase_merge`, `ff` + Repositories are created with `merge` by default + +* `only_allow_merge_if_pipeline_succeeds` - (Optional) Set to true if you want allow merges only if a pipeline succeeds. + +* `only_allow_merge_if_all_discussions_are_resolved` - (Optional) Set to true if you want allow merges only if all discussions are resolved. + * `shared_with_groups` - (Optional) Enable sharing the project with a list of groups (maps). * `group_id` - (Required) Group id of the group you want to share the project with. * `group_access_level` - (Optional) Group's sharing permissions. See [group members permission][group_members_permissions] for more info.