Repository: xanzy/go-gitlab
Pull request #1939 (2024-05-11 22:11:23)

Add ability to import Github repos
Adds a function which imports a Github repository into GitLab.

See https://docs.gitlab.com/ee/api/import.html#import-repository-from-github


Patch:
diff --git a/gitlab.go b/gitlab.go
index 6df108f..18a400f 100644
--- a/gitlab.go
+++ b/gitlab.go
@@ -153,6 +153,7 @@ type Client struct {
 	GroupVariables               *GroupVariablesService
 	GroupWikis                   *GroupWikisService
 	Groups                       *GroupsService
+	Import                       *ImportService
 	InstanceCluster              *InstanceClustersService
 	InstanceVariables            *InstanceVariablesService
 	Invites                      *InvitesService
@@ -388,6 +389,7 @@ func newClient(options ...ClientOptionFunc) (*Client, error) {
 	c.GroupVariables = &GroupVariablesService{client: c}
 	c.GroupWikis = &GroupWikisService{client: c}
 	c.Groups = &GroupsService{client: c}
+	c.Import = &ImportService{client: c}
 	c.InstanceCluster = &InstanceClustersService{client: c}
 	c.InstanceVariables = &InstanceVariablesService{client: c}
 	c.Invites = &InvitesService{client: c}
diff --git a/import.go b/import.go
new file mode 100644
index 0000000..f3bdec1
--- /dev/null
+++ b/import.go
@@ -0,0 +1,90 @@
+//
+// Copyright 2021, 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 (
+	"net/http"
+)
+
+// ImportService handles communication with the import
+// related methods of the GitLab API.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/import.html
+type ImportService struct {
+	client *Client
+}
+
+// GitHubImport represents the response from an import from GitHub.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/import.html#import-repository-from-github
+type GitHubImport struct {
+	ID                    int    `json:"id"`
+	Name                  string `json:"name"`
+	FullPath              string `json:"full_path"`
+	FullName              string `json:"full_name"`
+	RefsUrl               string `json:"refs_url"`
+	ImportSource          string `json:"import_source"`
+	ImportStatus          string `json:"import_status"`
+	HumanImportStatusName string `json:"human_import_status_name"`
+	ProviderLink          string `json:"provider_link"`
+	RelationType          string `json:"relation_type"`
+	ImportWarning         string `json:"import_warning"`
+}
+
+func (s GitHubImport) String() string {
+	return Stringify(s)
+}
+
+// ImportRepositoryFromGitHubOptions represents the available
+// ImportRepositoryFromGitHub() options.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/import.html#import-repository-from-github
+type ImportRepositoryFromGitHubOptions struct {
+	PersonalAccessToken *string `url:"personal_access_token,omitempty" json:"personal_access_token,omitempty"`
+	RepoID              *int    `url:"repo_id,omitempty" json:"repo_id,omitempty"`
+	NewName             *string `url:"new_name,omitempty" json:"new_name,omitempty"`
+	TargetNamespace     *string `url:"target_namespace,omitempty" json:"target_namespace,omitempty"`
+	GitHubHostname      *string `url:"github_hostname,omitempty" json:"github_hostname,omitempty"`
+	OptionalStages      struct {
+		SingleEndpointNotesImport *bool `url:"single_endpoint_notes_import,omitempty" json:"single_endpoint_notes_import,omitempty"`
+		AttachmentsImport         *bool `url:"attachments_import,omitempty" json:"attachments_import,omitempty"`
+		CollaboratorsImport       *bool `url:"collaborators_import,omitempty" json:"collaborators_import,omitempty"`
+	} `url:"optional_stages,omitempty" json:"optional_stages,omitempty"`
+	TimeoutStrategy *string `url:"timeout_strategy,omitempty" json:"timeout_strategy,omitempty"`
+}
+
+// Import a repository from GitHub.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/import.html#import-repository-from-github
+func (s *ImportService) ImportRepositoryFromGitHub(opt *ImportRepositoryFromGitHubOptions, options ...RequestOptionFunc) (*GitHubImport, *Response, error) {
+	req, err := s.client.NewRequest(http.MethodPost, "import/github", opt, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	gi := new(GitHubImport)
+	resp, err := s.client.Do(req, gi)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return gi, resp, nil
+}


Test patch:
diff --git a/import_test.go b/import_test.go
new file mode 100644
index 0000000..733ffba
--- /dev/null
+++ b/import_test.go
@@ -0,0 +1,58 @@
+package gitlab
+
+import (
+	"fmt"
+	"net/http"
+	"reflect"
+	"testing"
+)
+
+func TestImportService_ImportRepositoryFromGitHub(t *testing.T) {
+	mux, client := setup(t)
+
+	mux.HandleFunc("/api/v4/import/github", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodPost)
+		fmt.Fprintf(w, `
+			{
+				"id": 27,
+				"name": "my-repo",
+				"full_path": "/root/my-repo",
+				"full_name": "Administrator / my-repo",
+				"refs_url": "/root/my-repo/refs",
+				"import_source": "my-github/repo",
+				"import_status": "scheduled",
+				"human_import_status_name": "scheduled",
+				"provider_link": "/my-github/repo",
+				"relation_type": null,
+				"import_warning": null
+			}
+		`)
+	})
+
+	want := &GitHubImport{
+		ID:                    27,
+		Name:                  "my-repo",
+		FullPath:              "/root/my-repo",
+		FullName:              "Administrator / my-repo",
+		RefsUrl:               "/root/my-repo/refs",
+		ImportSource:          "my-github/repo",
+		ImportStatus:          "scheduled",
+		HumanImportStatusName: "scheduled",
+		ProviderLink:          "/my-github/repo",
+	}
+
+	opt := &ImportRepositoryFromGitHubOptions{
+		PersonalAccessToken: Ptr("token"),
+		RepoID:              Ptr(34),
+		TargetNamespace:     Ptr("root"),
+	}
+
+	gi, _, err := client.Import.ImportRepositoryFromGitHub(opt)
+	if err != nil {
+		t.Errorf("Import.ImportRepositoryFromGitHub returned error: %v", err)
+	}
+
+	if !reflect.DeepEqual(want, gi) {
+		t.Errorf("Import.ImportRepositoryFromGitHub return %+v, want %+v", gi, want)
+	}
+}