Skip to content

Commit de14c7d

Browse files
authored
Merge pull request #381 from armsnyder/42-import-url
Add import_url to gitlab_project
2 parents 2b8eb30 + ca8a3f7 commit de14c7d

File tree

3 files changed

+104
-0
lines changed

3 files changed

+104
-0
lines changed

gitlab/resource_gitlab_project.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,11 @@ var resourceGitLabProjectSchema = map[string]*schema.Schema{
6262
return old == new
6363
},
6464
},
65+
"import_url": {
66+
Type: schema.TypeString,
67+
Optional: true,
68+
ForceNew: true,
69+
},
6570
"request_access_enabled": {
6671
Type: schema.TypeBool,
6772
Optional: true,
@@ -309,6 +314,11 @@ func resourceGitlabProjectCreate(d *schema.ResourceData, meta interface{}) error
309314
setProperties = append(setProperties, "initialize_with_readme")
310315
}
311316

317+
if v, ok := d.GetOk("import_url"); ok {
318+
options.ImportURL = gitlab.String(v.(string))
319+
setProperties = append(setProperties, "import_url")
320+
}
321+
312322
log.Printf("[DEBUG] create gitlab project %q", *options.Name)
313323

314324
project, _, err := client.Projects.CreateProject(options)
@@ -325,6 +335,28 @@ func resourceGitlabProjectCreate(d *schema.ResourceData, meta interface{}) error
325335
// is committed to state since we set its ID
326336
d.SetId(fmt.Sprintf("%d", project.ID))
327337

338+
if _, ok := d.GetOk("import_url"); ok {
339+
log.Printf("[DEBUG] waiting for project %q import to finish", *options.Name)
340+
341+
stateConf := &resource.StateChangeConf{
342+
Pending: []string{"scheduled", "started"},
343+
Target: []string{"finished"},
344+
Timeout: time.Minute,
345+
Refresh: func() (interface{}, string, error) {
346+
status, _, err := client.ProjectImportExport.ImportStatus(d.Id())
347+
if err != nil {
348+
return nil, "", err
349+
}
350+
351+
return status, status.ImportStatus, nil
352+
},
353+
}
354+
355+
if _, err := stateConf.WaitForState(); err != nil {
356+
return fmt.Errorf("error while waiting for project %q import to finish: %w", *options.Name, err)
357+
}
358+
}
359+
328360
if v, ok := d.GetOk("shared_with_groups"); ok {
329361
for _, option := range expandSharedWithGroupsOptions(v) {
330362
if _, err := client.Projects.ShareProjectWithGroup(project.ID, option); err != nil {

gitlab/resource_gitlab_project_test.go

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package gitlab
22

33
import (
44
"fmt"
5+
"os"
56
"regexp"
67
"testing"
78

@@ -352,6 +353,61 @@ func TestAccGitlabProject_transfer(t *testing.T) {
352353
})
353354
}
354355

356+
func TestAccGitlabProject_importURL(t *testing.T) {
357+
// Since we do some manual setup in this test, we need to handle the test skip first.
358+
if os.Getenv(resource.TestEnvVar) == "" {
359+
t.Skip(fmt.Sprintf("Acceptance tests skipped unless env '%s' set", resource.TestEnvVar))
360+
}
361+
362+
client := testAccProvider.Meta().(*gitlab.Client)
363+
rInt := acctest.RandInt()
364+
365+
// Create a base project for importing.
366+
baseProject, _, err := client.Projects.CreateProject(&gitlab.CreateProjectOptions{
367+
Name: gitlab.String(fmt.Sprintf("base-%d", rInt)),
368+
Visibility: gitlab.Visibility(gitlab.PublicVisibility),
369+
})
370+
if err != nil {
371+
t.Fatalf("failed to create base project: %v", err)
372+
}
373+
374+
defer client.Projects.DeleteProject(baseProject.ID)
375+
376+
// Add a file to the base project, for later verifying the import.
377+
_, _, err = client.RepositoryFiles.CreateFile(baseProject.ID, "foo.txt", &gitlab.CreateFileOptions{
378+
Branch: gitlab.String("master"),
379+
CommitMessage: gitlab.String("add file"),
380+
Content: gitlab.String(""),
381+
})
382+
if err != nil {
383+
t.Fatalf("failed to commit file to base project: %v", err)
384+
}
385+
386+
resource.Test(t, resource.TestCase{
387+
PreCheck: func() { testAccPreCheck(t) },
388+
Providers: testAccProviders,
389+
CheckDestroy: testAccCheckGitlabProjectDestroy,
390+
Steps: []resource.TestStep{
391+
{
392+
Config: testAccGitlabProjectConfigImportURL(rInt, baseProject.HTTPURLToRepo),
393+
Check: resource.ComposeTestCheckFunc(
394+
resource.TestCheckResourceAttr("gitlab_project.imported", "import_url", baseProject.HTTPURLToRepo),
395+
func(state *terraform.State) error {
396+
projectID := state.RootModule().Resources["gitlab_project.imported"].Primary.ID
397+
398+
_, _, err := client.RepositoryFiles.GetFile(projectID, "foo.txt", &gitlab.GetFileOptions{Ref: gitlab.String("master")}, nil)
399+
if err != nil {
400+
return fmt.Errorf("failed to get file from imported project: %w", err)
401+
}
402+
403+
return nil
404+
},
405+
),
406+
},
407+
},
408+
})
409+
}
410+
355411
func testAccCheckGitlabProjectExists(n string, project *gitlab.Project) resource.TestCheckFunc {
356412
return func(s *terraform.State) error {
357413
var err error
@@ -667,3 +723,17 @@ resource "gitlab_project" "foo" {
667723
}
668724
`, rInt, rInt)
669725
}
726+
727+
func testAccGitlabProjectConfigImportURL(rInt int, importURL string) string {
728+
return fmt.Sprintf(`
729+
resource "gitlab_project" "imported" {
730+
name = "imported-%d"
731+
default_branch = "master"
732+
import_url = "%s"
733+
734+
# So that acceptance tests can be run in a gitlab organization
735+
# with no billing
736+
visibility_level = "public"
737+
}
738+
`, rInt, importURL)
739+
}

website/docs/r/project.html.markdown

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ The following arguments are supported:
4040

4141
* `default_branch` - (Optional) The default branch for the project.
4242

43+
* `import_url` - (Optional) Git URL to a repository to be imported.
44+
4345
* `request_access_enabled` - Allow users to request member access.
4446

4547
* `issues_enabled` - (Optional) Enable issue tracking for the project.

0 commit comments

Comments
 (0)