Skip to content

Commit 02b1bd3

Browse files
author
Julien Pivotto
authored
Merge pull request #247 from ringods/transfer-project
When changing the namespace_id, transfer project from old to new namespace
2 parents e8f3a34 + 4ef0514 commit 02b1bd3

File tree

2 files changed

+92
-1
lines changed

2 files changed

+92
-1
lines changed

gitlab/resource_gitlab_project.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ var resourceGitLabProjectSchema = map[string]*schema.Schema{
2929
"namespace_id": {
3030
Type: schema.TypeInt,
3131
Optional: true,
32-
ForceNew: true,
3332
Computed: true,
3433
},
3534
"description": {
@@ -362,6 +361,7 @@ func resourceGitlabProjectUpdate(d *schema.ResourceData, meta interface{}) error
362361
client := meta.(*gitlab.Client)
363362

364363
options := &gitlab.EditProjectOptions{}
364+
transferOptions := &gitlab.TransferProjectOptions{}
365365

366366
// need to manage partial state since project archiving requires
367367
// a separate API call which could fail
@@ -378,6 +378,11 @@ func resourceGitlabProjectUpdate(d *schema.ResourceData, meta interface{}) error
378378
updatedProperties = append(updatedProperties, "path")
379379
}
380380

381+
if d.HasChange("namespace_id") {
382+
transferOptions.Namespace = gitlab.Int(d.Get("namespace_id").(int))
383+
updatedProperties = append(updatedProperties, "namespace_id")
384+
}
385+
381386
if d.HasChange("description") {
382387
options.Description = gitlab.String(d.Get("description").(string))
383388
updatedProperties = append(updatedProperties, "description")
@@ -475,6 +480,16 @@ func resourceGitlabProjectUpdate(d *schema.ResourceData, meta interface{}) error
475480
}
476481
}
477482

483+
if *transferOptions != (gitlab.TransferProjectOptions{}) {
484+
log.Printf("[DEBUG] transferring project %s to namespace %d", d.Id(), transferOptions.Namespace)
485+
_, _, err := client.Projects.TransferProject(d.Id(), transferOptions)
486+
if err != nil {
487+
return err
488+
}
489+
log.Printf("[DEBUG] partial gitlab project %s update of property namespace_id", d.Id())
490+
d.SetPartial("namespace_id")
491+
}
492+
478493
if d.HasChange("shared_with_groups") {
479494
err := updateSharedWithGroups(d, meta)
480495
// TODO: check if handling partial state update in this simplistic

gitlab/resource_gitlab_project_test.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,56 @@ func TestAccGitlabProject_nestedImport(t *testing.T) {
302302
})
303303
}
304304

305+
func TestAccGitlabProject_transfer(t *testing.T) {
306+
var transferred, received gitlab.Project
307+
rInt := acctest.RandInt()
308+
309+
transferred = gitlab.Project{
310+
Namespace: &gitlab.ProjectNamespace{Name: fmt.Sprintf("foo2group-%d", rInt)},
311+
Name: fmt.Sprintf("foo-%d", rInt),
312+
Path: fmt.Sprintf("foo-%d", rInt),
313+
Description: "Terraform acceptance tests",
314+
TagList: []string{},
315+
RequestAccessEnabled: true,
316+
IssuesEnabled: true,
317+
MergeRequestsEnabled: true,
318+
JobsEnabled: true,
319+
ApprovalsBeforeMerge: 0,
320+
WikiEnabled: true,
321+
SnippetsEnabled: true,
322+
ContainerRegistryEnabled: true,
323+
LFSEnabled: true,
324+
SharedRunnersEnabled: true,
325+
Visibility: gitlab.PublicVisibility,
326+
MergeMethod: gitlab.NoFastForwardMerge,
327+
OnlyAllowMergeIfPipelineSucceeds: false,
328+
OnlyAllowMergeIfAllDiscussionsAreResolved: false,
329+
}
330+
331+
resource.Test(t, resource.TestCase{
332+
PreCheck: func() { testAccPreCheck(t) },
333+
Providers: testAccProviders,
334+
CheckDestroy: testAccCheckGitlabProjectDestroy,
335+
Steps: []resource.TestStep{
336+
// Create a project in a group
337+
{
338+
Config: testAccGitlabProjectInGroupConfig(rInt),
339+
Check: resource.ComposeTestCheckFunc(
340+
testAccCheckGitlabProjectExists("gitlab_project.foo", &received),
341+
),
342+
},
343+
// Create a second group and set the transfer the project to this group
344+
{
345+
Config: testAccGitlabProjectTransferBetweenGroups(rInt),
346+
Check: resource.ComposeTestCheckFunc(
347+
testAccCheckGitlabProjectExists("gitlab_project.foo", &received),
348+
testAccCheckAggregateGitlabProject(&transferred, &received),
349+
),
350+
},
351+
},
352+
})
353+
}
354+
305355
func testAccCheckGitlabProjectExists(n string, project *gitlab.Project) resource.TestCheckFunc {
306356
return func(s *terraform.State) error {
307357
var err error
@@ -431,6 +481,32 @@ resource "gitlab_project" "foo" {
431481
`, rInt, rInt, rInt)
432482
}
433483

484+
func testAccGitlabProjectTransferBetweenGroups(rInt int) string {
485+
return fmt.Sprintf(`
486+
resource "gitlab_group" "foo" {
487+
name = "foogroup-%d"
488+
path = "foogroup-%d"
489+
visibility_level = "public"
490+
}
491+
492+
resource "gitlab_group" "foo2" {
493+
name = "foo2group-%d"
494+
path = "foo2group-%d"
495+
visibility_level = "public"
496+
}
497+
498+
resource "gitlab_project" "foo" {
499+
name = "foo-%d"
500+
description = "Terraform acceptance tests"
501+
namespace_id = "${gitlab_group.foo2.id}"
502+
503+
# So that acceptance tests can be run in a gitlab organization
504+
# with no billing
505+
visibility_level = "public"
506+
}
507+
`, rInt, rInt, rInt, rInt, rInt)
508+
}
509+
434510
func testAccGitlabProjectConfigDefaultBranch(rInt int, defaultBranch string) string {
435511
defaultBranchStatement := ""
436512

0 commit comments

Comments
 (0)