From 24d43d8fb30e2e4038dcbac545db5ec10f9766ad Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Mon, 22 Jun 2020 09:40:53 +0300 Subject: [PATCH 1/6] Debug to detect when `default_branch` is set in .tf file WIP for fixing #299 where Terraform tries to reset the `default_branch` to null after a repository is added on GitLab side. The `default_branch` defaults to `master` on GitLab side, but it is only set if the repository is not empty. Otherwise it is `null` on remote side. The commit generates the following output, which shows no trace of `null` value from remote. 2020/06/19 20:55:55 [DEBUG] gitlab.Project default_branch (string) "" 2020/06/19 20:55:55 [DEBUG] d.Get default_branch (string) "" 2020/06/19 20:55:55 [DEBUG] d.GetOk default_branch (string) "" - false 2020/06/19 20:55:55 [DEBUG] d.HasChange default_branch false 2020/06/19 20:55:55 [DEBUG] d.GetChange default_branch (string) "", (string) "" But the actual response shows that `null` was returned in JSON. 2020/06/19 20:55:55 [DEBUG] GitLab API Response Details: ... "default_branch": null, --- gitlab/resource_gitlab_project.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/gitlab/resource_gitlab_project.go b/gitlab/resource_gitlab_project.go index 16b4c6b6d..a1f761ac6 100644 --- a/gitlab/resource_gitlab_project.go +++ b/gitlab/resource_gitlab_project.go @@ -213,6 +213,16 @@ func resourceGitlabProjectSetToState(d *schema.ResourceData, project *gitlab.Pro d.Set("name", project.Name) d.Set("path", project.Path) d.Set("description", project.Description) + + log.Printf("[DEBUG] gitlab.Project default_branch (%T) %#v", project.DefaultBranch, project.DefaultBranch) + default_branch := d.Get("default_branch") + db, ok := d.GetOk("default_branch") + changed := d.HasChange("default_branch") + old, new := d.GetChange("default_branch") + log.Printf("[DEBUG] d.Get default_branch (%T) %#v", default_branch, default_branch) + log.Printf("[DEBUG] d.GetOk default_branch (%T) %#v - %#v", db, db, ok) + log.Printf("[DEBUG] d.HasChange default_branch %#v", changed) + log.Printf("[DEBUG] d.GetChange default_branch (%T) %#v, (%T) %#v", old, old, new, new) d.Set("default_branch", project.DefaultBranch) d.Set("request_access_enabled", project.RequestAccessEnabled) d.Set("issues_enabled", project.IssuesEnabled) From 9f4b37f45f1bdb3503edc9c54913efb7921d1f25 Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Mon, 22 Jun 2020 12:36:53 +0300 Subject: [PATCH 2/6] Print GetOk and HasChange after setting the value --- gitlab/resource_gitlab_project.go | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/gitlab/resource_gitlab_project.go b/gitlab/resource_gitlab_project.go index a1f761ac6..679119160 100644 --- a/gitlab/resource_gitlab_project.go +++ b/gitlab/resource_gitlab_project.go @@ -214,16 +214,24 @@ func resourceGitlabProjectSetToState(d *schema.ResourceData, project *gitlab.Pro d.Set("path", project.Path) d.Set("description", project.Description) - log.Printf("[DEBUG] gitlab.Project default_branch (%T) %#v", project.DefaultBranch, project.DefaultBranch) + log.Printf("[DEBUG] default_branch before setting in Read function") + log.Printf("[DEBUG] gitlab.Project (%T) %#v", project.DefaultBranch, project.DefaultBranch) default_branch := d.Get("default_branch") db, ok := d.GetOk("default_branch") changed := d.HasChange("default_branch") old, new := d.GetChange("default_branch") - log.Printf("[DEBUG] d.Get default_branch (%T) %#v", default_branch, default_branch) - log.Printf("[DEBUG] d.GetOk default_branch (%T) %#v - %#v", db, db, ok) - log.Printf("[DEBUG] d.HasChange default_branch %#v", changed) - log.Printf("[DEBUG] d.GetChange default_branch (%T) %#v, (%T) %#v", old, old, new, new) + log.Printf("[DEBUG] d.Get() (%T) %#v", default_branch, default_branch) + log.Printf("[DEBUG] d.GetOk() (%T) %#v - %#v", db, db, ok) + log.Printf("[DEBUG] d.HasChange() %#v", changed) + log.Printf("[DEBUG] d.GetChange() (%T) %#v, (%T) %#v", old, old, new, new) + d.Set("default_branch", project.DefaultBranch) + + log.Printf("[DEBUG] default_branch after setting in Read function") + db, ok = d.GetOk("default_branch") + log.Printf("[DEBUG] d.GetOk() (%T) %#v - %#v", db, db, ok) + log.Printf("[DEBUG] d.HasChange() %#v", d.HasChange("default_branch")) + d.Set("request_access_enabled", project.RequestAccessEnabled) d.Set("issues_enabled", project.IssuesEnabled) d.Set("merge_requests_enabled", project.MergeRequestsEnabled) From 38eece65a2b326ac4bceb262ff5a866b1fd32c5e Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Mon, 22 Jun 2020 19:16:25 +0300 Subject: [PATCH 3/6] Fix #299 - do try to reset default_branch to `null` --- gitlab/resource_gitlab_project.go | 33 +++++++++++++++++-------------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/gitlab/resource_gitlab_project.go b/gitlab/resource_gitlab_project.go index 679119160..c83a0ed3e 100644 --- a/gitlab/resource_gitlab_project.go +++ b/gitlab/resource_gitlab_project.go @@ -38,25 +38,28 @@ var resourceGitLabProjectSchema = map[string]*schema.Schema{ "default_branch": { Type: schema.TypeString, Optional: true, - DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { - // If the old default branch is empty, it means that the project does not - // have a default branch. This can only happen if the project does not have - // branches, i.e. it is an empty project. In that case it is useless to - // try setting a specific default branch (because no branch exists). - // This code will defer the setting of a default branch to a time when the - // project is no longer empty. + DiffSuppressFunc: func(k, current, planned string, d *schema.ResourceData) bool { + old := current + new := planned + + log.Printf("[DEBUG] default_branch DiffSuppressFunc old new") + log.Printf("[DEBUG] (%T) %#v, (%T) %#v", old, old, new, new) + + // If there is no current default branch, it means that the project is + // empty and does not have branches. Setting the default branch will fail + // with 400 error. The check will defer the setting of a default branch + // to a time when the repository is no longer empty. if old == "" { return true } - // Once the initialize_with_readme attribute is set to true, Gitlab creates - // a master branch and sets it as default. If the Gitlab project resource - // doesn't have default_branch attribute specified, Terraform will - // force "master" => "" on the next run. - if v, ok := d.GetOk("initialize_with_readme"); ok { - if new == "" && v == true { - return true - } + // For non-empty repositories GitLab automatically sets master as the + // default branch. If the project resource doesn't specify default_branch + // attribute, Terraform will force "master" => "" on the next run. This + // check makes Terraform ignore default branch value until it is set in + // .tf configuration. For schema.TypeString empty is equal to "". + if new == "" { + return true } return old == new From d875e041c65a2fde6720394b378b40479561bf4c Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Mon, 22 Jun 2020 19:18:44 +0300 Subject: [PATCH 4/6] Remove DEBUG statements for tracing default_branch behavior --- gitlab/resource_gitlab_project.go | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/gitlab/resource_gitlab_project.go b/gitlab/resource_gitlab_project.go index c83a0ed3e..60e27b9f2 100644 --- a/gitlab/resource_gitlab_project.go +++ b/gitlab/resource_gitlab_project.go @@ -216,25 +216,7 @@ func resourceGitlabProjectSetToState(d *schema.ResourceData, project *gitlab.Pro d.Set("name", project.Name) d.Set("path", project.Path) d.Set("description", project.Description) - - log.Printf("[DEBUG] default_branch before setting in Read function") - log.Printf("[DEBUG] gitlab.Project (%T) %#v", project.DefaultBranch, project.DefaultBranch) - default_branch := d.Get("default_branch") - db, ok := d.GetOk("default_branch") - changed := d.HasChange("default_branch") - old, new := d.GetChange("default_branch") - log.Printf("[DEBUG] d.Get() (%T) %#v", default_branch, default_branch) - log.Printf("[DEBUG] d.GetOk() (%T) %#v - %#v", db, db, ok) - log.Printf("[DEBUG] d.HasChange() %#v", changed) - log.Printf("[DEBUG] d.GetChange() (%T) %#v, (%T) %#v", old, old, new, new) - d.Set("default_branch", project.DefaultBranch) - - log.Printf("[DEBUG] default_branch after setting in Read function") - db, ok = d.GetOk("default_branch") - log.Printf("[DEBUG] d.GetOk() (%T) %#v - %#v", db, db, ok) - log.Printf("[DEBUG] d.HasChange() %#v", d.HasChange("default_branch")) - d.Set("request_access_enabled", project.RequestAccessEnabled) d.Set("issues_enabled", project.IssuesEnabled) d.Set("merge_requests_enabled", project.MergeRequestsEnabled) From 95104870642d13b56b4be25a9f0cb56b5416270a Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Mon, 22 Jun 2020 19:58:01 +0300 Subject: [PATCH 5/6] Warn if default_branch is set, but the repo is empty --- gitlab/resource_gitlab_project.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/gitlab/resource_gitlab_project.go b/gitlab/resource_gitlab_project.go index 60e27b9f2..d12d62fa2 100644 --- a/gitlab/resource_gitlab_project.go +++ b/gitlab/resource_gitlab_project.go @@ -39,8 +39,8 @@ var resourceGitLabProjectSchema = map[string]*schema.Schema{ Type: schema.TypeString, Optional: true, DiffSuppressFunc: func(k, current, planned string, d *schema.ResourceData) bool { - old := current - new := planned + old := current // current value on GitLab side + new := planned // value that Terraform plans to set there log.Printf("[DEBUG] default_branch DiffSuppressFunc old new") log.Printf("[DEBUG] (%T) %#v, (%T) %#v", old, old, new, new) @@ -50,6 +50,9 @@ var resourceGitLabProjectSchema = map[string]*schema.Schema{ // with 400 error. The check will defer the setting of a default branch // to a time when the repository is no longer empty. if old == "" { + if new != "" { + log.Printf("[WARN] not setting default_branch %#v on empty repo", new) + } return true } From 47d3a26a2641052b9576afb7c321c11c7224c10a Mon Sep 17 00:00:00 2001 From: Anatoli Babenia Date: Thu, 25 Jun 2020 10:41:05 +0300 Subject: [PATCH 6/6] Comment arguments instead of renaming them --- gitlab/resource_gitlab_project.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gitlab/resource_gitlab_project.go b/gitlab/resource_gitlab_project.go index d12d62fa2..8ac521db9 100644 --- a/gitlab/resource_gitlab_project.go +++ b/gitlab/resource_gitlab_project.go @@ -38,9 +38,9 @@ var resourceGitLabProjectSchema = map[string]*schema.Schema{ "default_branch": { Type: schema.TypeString, Optional: true, - DiffSuppressFunc: func(k, current, planned string, d *schema.ResourceData) bool { - old := current // current value on GitLab side - new := planned // value that Terraform plans to set there + DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool { + // `old` is the current value on GitLab side + // `new` is the value that Terraform plans to set there log.Printf("[DEBUG] default_branch DiffSuppressFunc old new") log.Printf("[DEBUG] (%T) %#v, (%T) %#v", old, old, new, new)