Skip to content
This repository has been archived by the owner on Dec 10, 2024. It is now read-only.

feat: add Bitbucket Cloud and Server import endpoints #1979

Merged
merged 2 commits into from
Aug 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions examples/bitbucket_import.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package main

import (
"log"

"github.com/xanzy/go-gitlab"
)

func bitbucketCloudExample() {
git, err := gitlab.NewClient("yourtokengoeshere")
if err != nil {
log.Fatal(err)
}

cloudOpt := &gitlab.ImportRepositoryFromBitbucketCloudOptions{
BitbucketUsername: gitlab.Ptr("username"),
BitbucketAppPassword: gitlab.Ptr("password"),
RepoPath: gitlab.Ptr("some/repo"),
TargetNamespace: gitlab.Ptr("some-group"),
NewName: gitlab.Ptr("some-repo"),
}
cloudResp, _, err := git.Import.ImportRepositoryFromBitbucketCloud(cloudOpt)
if err != nil {
log.Fatal(err)
}
log.Print(cloudResp.String())
}

func bitbucketServerExample() {
git, err := gitlab.NewClient("yourtokengoeshere")
if err != nil {
log.Fatal(err)
}

serverOpt := &gitlab.ImportRepositoryFromBitbucketServerOptions{
BitbucketServerUrl: gitlab.Ptr("https://bitbucket.example.com"),
BitbucketServerUsername: gitlab.Ptr("username"),
PersonalAccessToken: gitlab.Ptr("access-token"),
BitbucketServerProject: gitlab.Ptr("some-project"),
BitbucketServerRepo: gitlab.Ptr("some-repo"),
NewName: gitlab.Ptr("some-other-repo"),
NewNamespace: gitlab.Ptr("some-group"),
TimeoutStrategy: gitlab.Ptr("pessimistic"),
}
serverResp, _, err := git.Import.ImportRepositoryFromBitbucketServer(serverOpt)
if err != nil {
log.Fatal(err)
}
log.Print(serverResp.String())
}
106 changes: 106 additions & 0 deletions import.go
Original file line number Diff line number Diff line change
Expand Up @@ -158,3 +158,109 @@ func (s *ImportService) ImportGitHubGistsIntoGitLabSnippets(opt *ImportGitHubGis

return s.client.Do(req, nil)
}

// BitbucketServerImport represents the response from an import from Bitbucket
// Server.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-server
type BitbucketServerImport struct {
ID int `json:"id"`
Name string `json:"name"`
FullPath string `json:"full_path"`
FullName string `json:"full_name"`
RefsUrl string `json:"refs_url"`
}

func (s BitbucketServerImport) String() string {
return Stringify(s)
}

// ImportRepositoryFromBitbucketServerOptions represents the available ImportRepositoryFromBitbucketServer() options.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-server
type ImportRepositoryFromBitbucketServerOptions struct {
BitbucketServerUrl *string `url:"bitbucket_server_url,omitempty" json:"bitbucket_server_url,omitempty"`
BitbucketServerUsername *string `url:"bitbucket_server_username,omitempty" json:"bitbucket_server_username,omitempty"`
PersonalAccessToken *string `url:"personal_access_token,omitempty" json:"personal_access_token,omitempty"`
BitbucketServerProject *string `url:"bitbucket_server_project,omitempty" json:"bitbucket_server_project,omitempty"`
BitbucketServerRepo *string `url:"bitbucket_server_repo,omitempty" json:"bitbucket_server_repo,omitempty"`
NewName *string `url:"new_name,omitempty" json:"new_name,omitempty"`
NewNamespace *string `url:"new_namespace,omitempty" json:"new_namespace,omitempty"`
TimeoutStrategy *string `url:"timeout_strategy,omitempty" json:"timeout_strategy,omitempty"`
}

// Import a repository from Bitbucket Server.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-server
func (s *ImportService) ImportRepositoryFromBitbucketServer(opt *ImportRepositoryFromBitbucketServerOptions, options ...RequestOptionFunc) (*BitbucketServerImport, *Response, error) {
req, err := s.client.NewRequest(http.MethodPost, "import/bitbucket_server", opt, options)
if err != nil {
return nil, nil, err
}

bsi := new(BitbucketServerImport)
resp, err := s.client.Do(req, bsi)
if err != nil {
return nil, resp, err
}

return bsi, resp, nil
}

// BitbucketCloudImport represents the response from an import from Bitbucket
// Cloud.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-cloud
type BitbucketCloudImport 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 BitbucketCloudImport) String() string {
return Stringify(s)
}

// ImportRepositoryFromBitbucketCloudOptions represents the available
// ImportRepositoryFromBitbucketCloud() options.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-cloud
type ImportRepositoryFromBitbucketCloudOptions struct {
BitbucketUsername *string `url:"bitbucket_username,omitempty" json:"bitbucket_username,omitempty"`
BitbucketAppPassword *string `url:"bitbucket_app_password,omitempty" json:"bitbucket_app_password,omitempty"`
RepoPath *string `url:"repo_path,omitempty" json:"repo_path,omitempty"`
TargetNamespace *string `url:"target_namespace,omitempty" json:"target_namespace,omitempty"`
NewName *string `url:"new_name,omitempty" json:"new_name,omitempty"`
}

// Import a repository from Bitbucket Cloud.
//
// GitLab API docs:
// https://docs.gitlab.com/ee/api/import.html#import-repository-from-bitbucket-cloud
func (s *ImportService) ImportRepositoryFromBitbucketCloud(opt *ImportRepositoryFromBitbucketCloudOptions, options ...RequestOptionFunc) (*BitbucketCloudImport, *Response, error) {
req, err := s.client.NewRequest(http.MethodPost, "import/bitbucket", opt, options)
if err != nil {
return nil, nil, err
}

bci := new(BitbucketCloudImport)
resp, err := s.client.Do(req, bci)
if err != nil {
return nil, resp, err
}

return bci, resp, nil
}
99 changes: 99 additions & 0 deletions import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,102 @@ func TestImportService_ImportGitHubGistsIntoGitLabSnippets(t *testing.T) {
require.EqualError(t, err, "RequestOptionFunc returns an error")
require.Nil(t, resp)
}

func TestImportService_ImportRepositoryFromBitbucketServer(t *testing.T) {
mux, client := setup(t)

mux.HandleFunc("/api/v4/import/bitbucket_server", 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"
}
`)
})

want := &BitbucketServerImport{
ID: 27,
Name: "my-repo",
FullPath: "/root/my-repo",
FullName: "Administrator / my-repo",
RefsUrl: "/root/my-repo/refs",
}

opt := &ImportRepositoryFromBitbucketServerOptions{
BitbucketServerUrl: Ptr("https://bitbucket.example.com"),
BitbucketServerUsername: Ptr("username"),
PersonalAccessToken: Ptr("token"),
BitbucketServerProject: Ptr("root"),
BitbucketServerRepo: Ptr("my-repo"),
NewName: Ptr("my-repo"),
NewNamespace: Ptr("root"),
TimeoutStrategy: Ptr("pessimistic"),
}

bsi, resp, err := client.Import.ImportRepositoryFromBitbucketServer(opt)
require.NoError(t, err)
require.NotNil(t, resp)
require.Equal(t, want, bsi)

bsi, resp, err = client.Import.ImportRepositoryFromBitbucketServer(opt, errorOption)
require.EqualError(t, err, "RequestOptionFunc returns an error")
require.Nil(t, resp)
require.Nil(t, bsi)
}

func TestImportService_ImportRepositoryFromBitbucketCloud(t *testing.T) {
mux, client := setup(t)

mux.HandleFunc("/api/v4/import/bitbucket", 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-bitbucket/repo",
"import_status": "scheduled",
"human_import_status_name": "scheduled",
"provider_link": "/my-bitbucket/repo",
"relation_type": null,
"import_warning": null
}
`)
})

want := &BitbucketCloudImport{
ID: 27,
Name: "my-repo",
FullPath: "/root/my-repo",
FullName: "Administrator / my-repo",
RefsUrl: "/root/my-repo/refs",
ImportSource: "my-bitbucket/repo",
ImportStatus: "scheduled",
HumanImportStatusName: "scheduled",
ProviderLink: "/my-bitbucket/repo",
}

opt := &ImportRepositoryFromBitbucketCloudOptions{
BitbucketUsername: Ptr("username"),
BitbucketAppPassword: Ptr("password"),
RepoPath: Ptr("/root/my-repo"),
TargetNamespace: Ptr("/root/"),
NewName: Ptr("my-repo"),
}

bci, resp, err := client.Import.ImportRepositoryFromBitbucketCloud(opt)
require.NoError(t, err)
require.NotNil(t, resp)
require.Equal(t, want, bci)

bci, resp, err = client.Import.ImportRepositoryFromBitbucketCloud(opt, errorOption)
require.EqualError(t, err, "RequestOptionFunc returns an error")
require.Nil(t, resp)
require.Nil(t, bci)
}