From 56eb09507e917de9c962a3249435d05f4dbf7e4b Mon Sep 17 00:00:00 2001 From: brinchm Date: Wed, 15 Jun 2022 15:25:43 +0200 Subject: [PATCH] feat: Add Azure DevOps SCM Provider Generator; add branchNormalized to SCM Generator template fields. (#9283) * feat: add Azure DevOps SCM provider Signed-off-by: Christer Brinchmann * feat: add branchNormalized scm provider parameter. Signed-off-by: Christer Brinchmann * add Azure DevOps SCM provider docs. Signed-off-by: Christer Brinchmann * add branchNormalized docs. Signed-off-by: Christer Brinchmann * Changes to Azure DevOps SCM generator from PR feeback. Signed-off-by: Christer Brinchmann * fix linting error and failing tests. Signed-off-by: Christer Brinchmann * remove NoError assertion Signed-off-by: Christer Brinchmann * handle errors when repos are disabled, fix branch name in query when getting default branch. Signed-off-by: Christer Brinchmann * set proper example values for SCMProviderGeneratorAzureDevOps fields. Signed-off-by: Christer Brinchmann * sort dependencies properly by name Signed-off-by: Christer Brinchmann --- applicationset/generators/scm_provider.go | 22 +- .../services/scm_provider/azure_devops.go | 219 ++ .../azure_devops/git/mocks/Client.go | 2554 +++++++++++++++++ .../scm_provider/azure_devops_test.go | 530 ++++ .../applicationset/Generators-SCM-Provider.md | 38 + go.mod | 1 + go.sum | 2 + manifests/core-install.yaml | 75 + manifests/crds/applicationset-crd.yaml | 75 + manifests/ha/install.yaml | 75 + manifests/install.yaml | 75 + .../v1alpha1/applicationset_types.go | 15 + .../v1alpha1/zz_generated.deepcopy.go | 25 + 13 files changed, 3700 insertions(+), 6 deletions(-) create mode 100644 applicationset/services/scm_provider/azure_devops.go create mode 100644 applicationset/services/scm_provider/azure_devops/git/mocks/Client.go create mode 100644 applicationset/services/scm_provider/azure_devops_test.go diff --git a/applicationset/generators/scm_provider.go b/applicationset/generators/scm_provider.go index 4fb063f531fca..17abde67c1792 100644 --- a/applicationset/generators/scm_provider.go +++ b/applicationset/generators/scm_provider.go @@ -101,6 +101,15 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha if scmError != nil { return nil, fmt.Errorf("error initializing Bitbucket Server service: %v", scmError) } + } else if providerConfig.AzureDevOps != nil { + token, err := g.getSecretRef(ctx, providerConfig.AzureDevOps.AccessTokenRef, applicationSetInfo.Namespace) + if err != nil { + return nil, fmt.Errorf("error fetching Azure Devops access token: %v", err) + } + provider, err = scm_provider.NewAzureDevOpsProvider(ctx, token, providerConfig.AzureDevOps.Organization, providerConfig.AzureDevOps.API, providerConfig.AzureDevOps.TeamProject, providerConfig.AzureDevOps.AllBranches) + if err != nil { + return nil, fmt.Errorf("error initializing Azure Devops service: %v", err) + } } else { return nil, fmt.Errorf("no SCM provider implementation configured") } @@ -113,12 +122,13 @@ func (g *SCMProviderGenerator) GenerateParams(appSetGenerator *argoprojiov1alpha params := make([]map[string]string, 0, len(repos)) for _, repo := range repos { params = append(params, map[string]string{ - "organization": repo.Organization, - "repository": repo.Repository, - "url": repo.URL, - "branch": repo.Branch, - "sha": repo.SHA, - "labels": strings.Join(repo.Labels, ","), + "organization": repo.Organization, + "repository": repo.Repository, + "url": repo.URL, + "branch": repo.Branch, + "sha": repo.SHA, + "labels": strings.Join(repo.Labels, ","), + "branchNormalized": sanitizeName(repo.Branch), }) } return params, nil diff --git a/applicationset/services/scm_provider/azure_devops.go b/applicationset/services/scm_provider/azure_devops.go new file mode 100644 index 0000000000000..c71dabd0509f1 --- /dev/null +++ b/applicationset/services/scm_provider/azure_devops.go @@ -0,0 +1,219 @@ +package scm_provider + +import ( + "context" + "fmt" + netUrl "net/url" + "strings" + + "github.com/google/uuid" + "github.com/microsoft/azure-devops-go-api/azuredevops" + azureGit "github.com/microsoft/azure-devops-go-api/azuredevops/git" +) + +const AZURE_DEVOPS_DEFAULT_URL = "https://dev.azure.com" + +type azureDevOpsErrorTypeKeyValuesType struct { + GitRepositoryNotFound string + GitItemNotFound string +} + +var AzureDevOpsErrorsTypeKeyValues = azureDevOpsErrorTypeKeyValuesType{ + GitRepositoryNotFound: "GitRepositoryNotFoundException", + GitItemNotFound: "GitItemNotFoundException", +} + +type AzureDevOpsClientFactory interface { + // Returns an Azure Devops Client interface. + GetClient(ctx context.Context) (azureGit.Client, error) +} + +type devopsFactoryImpl struct { + connection *azuredevops.Connection +} + +func (factory *devopsFactoryImpl) GetClient(ctx context.Context) (azureGit.Client, error) { + gitClient, err := azureGit.NewClient(ctx, factory.connection) + if err != nil { + return nil, fmt.Errorf("failed to get new Azure DevOps git client for SCM generator: %w", err) + } + return gitClient, nil +} + +// Contains Azure Devops REST API implementation of SCMProviderService. +// See https://docs.microsoft.com/en-us/rest/api/azure/devops + +type AzureDevOpsProvider struct { + organization string + teamProject string + accessToken string + clientFactory AzureDevOpsClientFactory + allBranches bool +} + +var _ SCMProviderService = &AzureDevOpsProvider{} +var _ AzureDevOpsClientFactory = &devopsFactoryImpl{} + +func NewAzureDevOpsProvider(ctx context.Context, accessToken string, org string, url string, project string, allBranches bool) (*AzureDevOpsProvider, error) { + if accessToken == "" { + return nil, fmt.Errorf("no access token provided") + } + + devOpsURL, err := getValidDevOpsURL(url, org) + + if err != nil { + return nil, err + } + + connection := azuredevops.NewPatConnection(devOpsURL, accessToken) + + return &AzureDevOpsProvider{organization: org, teamProject: project, accessToken: accessToken, clientFactory: &devopsFactoryImpl{connection: connection}, allBranches: allBranches}, nil +} + +func (g *AzureDevOpsProvider) ListRepos(ctx context.Context, cloneProtocol string) ([]*Repository, error) { + gitClient, err := g.clientFactory.GetClient(ctx) + if err != nil { + return nil, fmt.Errorf("failed to get Azure DevOps client: %w", err) + } + getRepoArgs := azureGit.GetRepositoriesArgs{Project: &g.teamProject} + azureRepos, err := gitClient.GetRepositories(ctx, getRepoArgs) + + if err != nil { + return nil, err + } + repos := []*Repository{} + for _, azureRepo := range *azureRepos { + if azureRepo.Name == nil || azureRepo.DefaultBranch == nil || azureRepo.RemoteUrl == nil || azureRepo.Id == nil { + continue + } + repos = append(repos, &Repository{ + Organization: g.organization, + Repository: *azureRepo.Name, + URL: *azureRepo.RemoteUrl, + Branch: *azureRepo.DefaultBranch, + Labels: []string{}, + RepositoryId: *azureRepo.Id, + }) + } + + return repos, nil +} + +func (g *AzureDevOpsProvider) RepoHasPath(ctx context.Context, repo *Repository, path string) (bool, error) { + gitClient, err := g.clientFactory.GetClient(ctx) + if err != nil { + return false, fmt.Errorf("failed to get Azure DevOps client: %w", err) + } + + var repoId string + if uuid, isUuid := repo.RepositoryId.(uuid.UUID); isUuid { //most likely an UUID, but do type-safe check anyway. Do %v fallback if not expected type. + repoId = uuid.String() + } else { + repoId = fmt.Sprintf("%v", repo.RepositoryId) + } + + branchName := repo.Branch + getItemArgs := azureGit.GetItemArgs{RepositoryId: &repoId, Project: &g.teamProject, Path: &path, VersionDescriptor: &azureGit.GitVersionDescriptor{Version: &branchName}} + _, err = gitClient.GetItem(ctx, getItemArgs) + + if err != nil { + if wrappedError, isWrappedError := err.(azuredevops.WrappedError); isWrappedError && wrappedError.TypeKey != nil { + if *wrappedError.TypeKey == AzureDevOpsErrorsTypeKeyValues.GitItemNotFound { + return false, nil + } + } + + return false, fmt.Errorf("failed to check for path existence in Azure DevOps: %w", err) + } + + return true, nil +} + +func (g *AzureDevOpsProvider) GetBranches(ctx context.Context, repo *Repository) ([]*Repository, error) { + gitClient, err := g.clientFactory.GetClient(ctx) + if err != nil { + return nil, fmt.Errorf("failed to get Azure DevOps client: %w", err) + } + + repos := []*Repository{} + + if !g.allBranches { + defaultBranchName := strings.Replace(repo.Branch, "refs/heads/", "", 1) //Azure DevOps returns default branch info like 'refs/heads/main', but does not support branch lookup of this format. + getBranchArgs := azureGit.GetBranchArgs{RepositoryId: &repo.Repository, Project: &g.teamProject, Name: &defaultBranchName} + branchResult, err := gitClient.GetBranch(ctx, getBranchArgs) + if err != nil { + if wrappedError, isWrappedError := err.(azuredevops.WrappedError); isWrappedError && wrappedError.TypeKey != nil { + if *wrappedError.TypeKey == AzureDevOpsErrorsTypeKeyValues.GitRepositoryNotFound { + return repos, nil + } + } + return nil, fmt.Errorf("could not get default branch %v (%v) from repository %v: %w", defaultBranchName, repo.Branch, repo.Repository, err) + } + + if branchResult.Name == nil || branchResult.Commit == nil { + return nil, fmt.Errorf("invalid branch result after requesting branch %v from repository %v", repo.Branch, repo.Repository) + } + + repos = append(repos, &Repository{ + Branch: *branchResult.Name, + SHA: *branchResult.Commit.CommitId, + Organization: repo.Organization, + Repository: repo.Repository, + URL: repo.URL, + Labels: []string{}, + RepositoryId: repo.RepositoryId, + }) + + return repos, nil + } + + getBranchesRequest := azureGit.GetBranchesArgs{RepositoryId: &repo.Repository, Project: &g.teamProject} + branches, err := gitClient.GetBranches(ctx, getBranchesRequest) + if err != nil { + if wrappedError, isWrappedError := err.(azuredevops.WrappedError); isWrappedError && wrappedError.TypeKey != nil { + if *wrappedError.TypeKey == AzureDevOpsErrorsTypeKeyValues.GitRepositoryNotFound { + return repos, nil + } + } + return nil, fmt.Errorf("failed getting branches from repository %v, project %v: %w", repo.Repository, g.teamProject, err) + } + + if branches == nil { + return nil, fmt.Errorf("got empty branch result from repository %v, project %v: %w", repo.Repository, g.teamProject, err) + } + + for _, azureBranch := range *branches { + repos = append(repos, &Repository{ + Branch: *azureBranch.Name, + SHA: *azureBranch.Commit.CommitId, + Organization: repo.Organization, + Repository: repo.Repository, + URL: repo.URL, + Labels: []string{}, + RepositoryId: repo.RepositoryId, + }) + } + + return repos, nil +} + +func getValidDevOpsURL(url string, org string) (string, error) { + if url == "" { + url = AZURE_DEVOPS_DEFAULT_URL + } + separator := "" + if !strings.HasSuffix(url, "/") { + separator = "/" + } + + devOpsURL := fmt.Sprintf("%s%s%s", url, separator, org) + + urlCheck, err := netUrl.ParseRequestURI(devOpsURL) + + if err != nil { + return "", fmt.Errorf("got an invalid URL for the Azure SCM generator: %w", err) + } + + ret := urlCheck.String() + return ret, nil +} diff --git a/applicationset/services/scm_provider/azure_devops/git/mocks/Client.go b/applicationset/services/scm_provider/azure_devops/git/mocks/Client.go new file mode 100644 index 0000000000000..7843753c9df5b --- /dev/null +++ b/applicationset/services/scm_provider/azure_devops/git/mocks/Client.go @@ -0,0 +1,2554 @@ +// Code generated by mockery v2.10.4. DO NOT EDIT. + +package mocks + +import ( + context "context" + + core "github.com/microsoft/azure-devops-go-api/azuredevops/core" + git "github.com/microsoft/azure-devops-go-api/azuredevops/git" + + io "io" + + mock "github.com/stretchr/testify/mock" + + webapi "github.com/microsoft/azure-devops-go-api/azuredevops/webapi" +) + +// Client is an autogenerated mock type for the Client type +type Client struct { + mock.Mock +} + +// CreateAnnotatedTag provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateAnnotatedTag(_a0 context.Context, _a1 git.CreateAnnotatedTagArgs) (*git.GitAnnotatedTag, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitAnnotatedTag + if rf, ok := ret.Get(0).(func(context.Context, git.CreateAnnotatedTagArgs) *git.GitAnnotatedTag); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitAnnotatedTag) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreateAnnotatedTagArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateAttachment provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateAttachment(_a0 context.Context, _a1 git.CreateAttachmentArgs) (*git.Attachment, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.Attachment + if rf, ok := ret.Get(0).(func(context.Context, git.CreateAttachmentArgs) *git.Attachment); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.Attachment) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreateAttachmentArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateCherryPick provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateCherryPick(_a0 context.Context, _a1 git.CreateCherryPickArgs) (*git.GitCherryPick, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitCherryPick + if rf, ok := ret.Get(0).(func(context.Context, git.CreateCherryPickArgs) *git.GitCherryPick); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitCherryPick) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreateCherryPickArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateComment provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateComment(_a0 context.Context, _a1 git.CreateCommentArgs) (*git.Comment, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.Comment + if rf, ok := ret.Get(0).(func(context.Context, git.CreateCommentArgs) *git.Comment); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.Comment) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreateCommentArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateCommitStatus provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateCommitStatus(_a0 context.Context, _a1 git.CreateCommitStatusArgs) (*git.GitStatus, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitStatus + if rf, ok := ret.Get(0).(func(context.Context, git.CreateCommitStatusArgs) *git.GitStatus); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitStatus) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreateCommitStatusArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateFavorite provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateFavorite(_a0 context.Context, _a1 git.CreateFavoriteArgs) (*git.GitRefFavorite, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitRefFavorite + if rf, ok := ret.Get(0).(func(context.Context, git.CreateFavoriteArgs) *git.GitRefFavorite); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRefFavorite) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreateFavoriteArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateForkSyncRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateForkSyncRequest(_a0 context.Context, _a1 git.CreateForkSyncRequestArgs) (*git.GitForkSyncRequest, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitForkSyncRequest + if rf, ok := ret.Get(0).(func(context.Context, git.CreateForkSyncRequestArgs) *git.GitForkSyncRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitForkSyncRequest) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreateForkSyncRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateImportRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateImportRequest(_a0 context.Context, _a1 git.CreateImportRequestArgs) (*git.GitImportRequest, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitImportRequest + if rf, ok := ret.Get(0).(func(context.Context, git.CreateImportRequestArgs) *git.GitImportRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitImportRequest) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreateImportRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateLike provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateLike(_a0 context.Context, _a1 git.CreateLikeArgs) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.CreateLikeArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// CreateMergeRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateMergeRequest(_a0 context.Context, _a1 git.CreateMergeRequestArgs) (*git.GitMerge, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitMerge + if rf, ok := ret.Get(0).(func(context.Context, git.CreateMergeRequestArgs) *git.GitMerge); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitMerge) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreateMergeRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreatePullRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreatePullRequest(_a0 context.Context, _a1 git.CreatePullRequestArgs) (*git.GitPullRequest, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitPullRequest + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestArgs) *git.GitPullRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequest) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreatePullRequestIterationStatus provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreatePullRequestIterationStatus(_a0 context.Context, _a1 git.CreatePullRequestIterationStatusArgs) (*git.GitPullRequestStatus, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitPullRequestStatus + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestIterationStatusArgs) *git.GitPullRequestStatus); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestStatus) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestIterationStatusArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreatePullRequestLabel provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreatePullRequestLabel(_a0 context.Context, _a1 git.CreatePullRequestLabelArgs) (*core.WebApiTagDefinition, error) { + ret := _m.Called(_a0, _a1) + + var r0 *core.WebApiTagDefinition + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestLabelArgs) *core.WebApiTagDefinition); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*core.WebApiTagDefinition) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestLabelArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreatePullRequestReviewer provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreatePullRequestReviewer(_a0 context.Context, _a1 git.CreatePullRequestReviewerArgs) (*git.IdentityRefWithVote, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.IdentityRefWithVote + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestReviewerArgs) *git.IdentityRefWithVote); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.IdentityRefWithVote) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestReviewerArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreatePullRequestReviewers provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreatePullRequestReviewers(_a0 context.Context, _a1 git.CreatePullRequestReviewersArgs) (*[]git.IdentityRefWithVote, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.IdentityRefWithVote + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestReviewersArgs) *[]git.IdentityRefWithVote); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.IdentityRefWithVote) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestReviewersArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreatePullRequestStatus provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreatePullRequestStatus(_a0 context.Context, _a1 git.CreatePullRequestStatusArgs) (*git.GitPullRequestStatus, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitPullRequestStatus + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePullRequestStatusArgs) *git.GitPullRequestStatus); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestStatus) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreatePullRequestStatusArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreatePush provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreatePush(_a0 context.Context, _a1 git.CreatePushArgs) (*git.GitPush, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitPush + if rf, ok := ret.Get(0).(func(context.Context, git.CreatePushArgs) *git.GitPush); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPush) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreatePushArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateRepository provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateRepository(_a0 context.Context, _a1 git.CreateRepositoryArgs) (*git.GitRepository, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitRepository + if rf, ok := ret.Get(0).(func(context.Context, git.CreateRepositoryArgs) *git.GitRepository); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRepository) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreateRepositoryArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateRevert provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateRevert(_a0 context.Context, _a1 git.CreateRevertArgs) (*git.GitRevert, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitRevert + if rf, ok := ret.Get(0).(func(context.Context, git.CreateRevertArgs) *git.GitRevert); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRevert) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreateRevertArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// CreateThread provides a mock function with given fields: _a0, _a1 +func (_m *Client) CreateThread(_a0 context.Context, _a1 git.CreateThreadArgs) (*git.GitPullRequestCommentThread, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitPullRequestCommentThread + if rf, ok := ret.Get(0).(func(context.Context, git.CreateThreadArgs) *git.GitPullRequestCommentThread); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestCommentThread) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.CreateThreadArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// DeleteAttachment provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeleteAttachment(_a0 context.Context, _a1 git.DeleteAttachmentArgs) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeleteAttachmentArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteComment provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeleteComment(_a0 context.Context, _a1 git.DeleteCommentArgs) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeleteCommentArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteLike provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeleteLike(_a0 context.Context, _a1 git.DeleteLikeArgs) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeleteLikeArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeletePullRequestIterationStatus provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeletePullRequestIterationStatus(_a0 context.Context, _a1 git.DeletePullRequestIterationStatusArgs) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeletePullRequestIterationStatusArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeletePullRequestLabels provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeletePullRequestLabels(_a0 context.Context, _a1 git.DeletePullRequestLabelsArgs) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeletePullRequestLabelsArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeletePullRequestReviewer provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeletePullRequestReviewer(_a0 context.Context, _a1 git.DeletePullRequestReviewerArgs) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeletePullRequestReviewerArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeletePullRequestStatus provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeletePullRequestStatus(_a0 context.Context, _a1 git.DeletePullRequestStatusArgs) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeletePullRequestStatusArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteRefFavorite provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeleteRefFavorite(_a0 context.Context, _a1 git.DeleteRefFavoriteArgs) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeleteRefFavoriteArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteRepository provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeleteRepository(_a0 context.Context, _a1 git.DeleteRepositoryArgs) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeleteRepositoryArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// DeleteRepositoryFromRecycleBin provides a mock function with given fields: _a0, _a1 +func (_m *Client) DeleteRepositoryFromRecycleBin(_a0 context.Context, _a1 git.DeleteRepositoryFromRecycleBinArgs) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.DeleteRepositoryFromRecycleBinArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// GetAnnotatedTag provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetAnnotatedTag(_a0 context.Context, _a1 git.GetAnnotatedTagArgs) (*git.GitAnnotatedTag, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitAnnotatedTag + if rf, ok := ret.Get(0).(func(context.Context, git.GetAnnotatedTagArgs) *git.GitAnnotatedTag); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitAnnotatedTag) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetAnnotatedTagArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetAttachmentContent provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetAttachmentContent(_a0 context.Context, _a1 git.GetAttachmentContentArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + var r0 io.ReadCloser + if rf, ok := ret.Get(0).(func(context.Context, git.GetAttachmentContentArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetAttachmentContentArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetAttachmentZip provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetAttachmentZip(_a0 context.Context, _a1 git.GetAttachmentZipArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + var r0 io.ReadCloser + if rf, ok := ret.Get(0).(func(context.Context, git.GetAttachmentZipArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetAttachmentZipArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetAttachments provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetAttachments(_a0 context.Context, _a1 git.GetAttachmentsArgs) (*[]git.Attachment, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.Attachment + if rf, ok := ret.Get(0).(func(context.Context, git.GetAttachmentsArgs) *[]git.Attachment); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.Attachment) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetAttachmentsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBlob provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetBlob(_a0 context.Context, _a1 git.GetBlobArgs) (*git.GitBlobRef, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitBlobRef + if rf, ok := ret.Get(0).(func(context.Context, git.GetBlobArgs) *git.GitBlobRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitBlobRef) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetBlobArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBlobContent provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetBlobContent(_a0 context.Context, _a1 git.GetBlobContentArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + var r0 io.ReadCloser + if rf, ok := ret.Get(0).(func(context.Context, git.GetBlobContentArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetBlobContentArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBlobZip provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetBlobZip(_a0 context.Context, _a1 git.GetBlobZipArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + var r0 io.ReadCloser + if rf, ok := ret.Get(0).(func(context.Context, git.GetBlobZipArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetBlobZipArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBlobsZip provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetBlobsZip(_a0 context.Context, _a1 git.GetBlobsZipArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + var r0 io.ReadCloser + if rf, ok := ret.Get(0).(func(context.Context, git.GetBlobsZipArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetBlobsZipArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBranch provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetBranch(_a0 context.Context, _a1 git.GetBranchArgs) (*git.GitBranchStats, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitBranchStats + if rf, ok := ret.Get(0).(func(context.Context, git.GetBranchArgs) *git.GitBranchStats); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitBranchStats) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetBranchArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBranches provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetBranches(_a0 context.Context, _a1 git.GetBranchesArgs) (*[]git.GitBranchStats, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitBranchStats + if rf, ok := ret.Get(0).(func(context.Context, git.GetBranchesArgs) *[]git.GitBranchStats); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitBranchStats) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetBranchesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetChanges provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetChanges(_a0 context.Context, _a1 git.GetChangesArgs) (*git.GitCommitChanges, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitCommitChanges + if rf, ok := ret.Get(0).(func(context.Context, git.GetChangesArgs) *git.GitCommitChanges); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitCommitChanges) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetChangesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetCherryPick provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetCherryPick(_a0 context.Context, _a1 git.GetCherryPickArgs) (*git.GitCherryPick, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitCherryPick + if rf, ok := ret.Get(0).(func(context.Context, git.GetCherryPickArgs) *git.GitCherryPick); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitCherryPick) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetCherryPickArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetCherryPickForRefName provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetCherryPickForRefName(_a0 context.Context, _a1 git.GetCherryPickForRefNameArgs) (*git.GitCherryPick, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitCherryPick + if rf, ok := ret.Get(0).(func(context.Context, git.GetCherryPickForRefNameArgs) *git.GitCherryPick); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitCherryPick) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetCherryPickForRefNameArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetComment provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetComment(_a0 context.Context, _a1 git.GetCommentArgs) (*git.Comment, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.Comment + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommentArgs) *git.Comment); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.Comment) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetCommentArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetComments provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetComments(_a0 context.Context, _a1 git.GetCommentsArgs) (*[]git.Comment, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.Comment + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommentsArgs) *[]git.Comment); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.Comment) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetCommentsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetCommit provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetCommit(_a0 context.Context, _a1 git.GetCommitArgs) (*git.GitCommit, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitCommit + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommitArgs) *git.GitCommit); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitCommit) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetCommitArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetCommitDiffs provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetCommitDiffs(_a0 context.Context, _a1 git.GetCommitDiffsArgs) (*git.GitCommitDiffs, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitCommitDiffs + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommitDiffsArgs) *git.GitCommitDiffs); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitCommitDiffs) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetCommitDiffsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetCommits provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetCommits(_a0 context.Context, _a1 git.GetCommitsArgs) (*[]git.GitCommitRef, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitCommitRef + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommitsArgs) *[]git.GitCommitRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitCommitRef) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetCommitsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetCommitsBatch provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetCommitsBatch(_a0 context.Context, _a1 git.GetCommitsBatchArgs) (*[]git.GitCommitRef, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitCommitRef + if rf, ok := ret.Get(0).(func(context.Context, git.GetCommitsBatchArgs) *[]git.GitCommitRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitCommitRef) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetCommitsBatchArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetDeletedRepositories provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetDeletedRepositories(_a0 context.Context, _a1 git.GetDeletedRepositoriesArgs) (*[]git.GitDeletedRepository, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitDeletedRepository + if rf, ok := ret.Get(0).(func(context.Context, git.GetDeletedRepositoriesArgs) *[]git.GitDeletedRepository); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitDeletedRepository) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetDeletedRepositoriesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetForkSyncRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetForkSyncRequest(_a0 context.Context, _a1 git.GetForkSyncRequestArgs) (*git.GitForkSyncRequest, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitForkSyncRequest + if rf, ok := ret.Get(0).(func(context.Context, git.GetForkSyncRequestArgs) *git.GitForkSyncRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitForkSyncRequest) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetForkSyncRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetForkSyncRequests provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetForkSyncRequests(_a0 context.Context, _a1 git.GetForkSyncRequestsArgs) (*[]git.GitForkSyncRequest, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitForkSyncRequest + if rf, ok := ret.Get(0).(func(context.Context, git.GetForkSyncRequestsArgs) *[]git.GitForkSyncRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitForkSyncRequest) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetForkSyncRequestsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetForks provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetForks(_a0 context.Context, _a1 git.GetForksArgs) (*[]git.GitRepositoryRef, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitRepositoryRef + if rf, ok := ret.Get(0).(func(context.Context, git.GetForksArgs) *[]git.GitRepositoryRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitRepositoryRef) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetForksArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetImportRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetImportRequest(_a0 context.Context, _a1 git.GetImportRequestArgs) (*git.GitImportRequest, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitImportRequest + if rf, ok := ret.Get(0).(func(context.Context, git.GetImportRequestArgs) *git.GitImportRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitImportRequest) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetImportRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetItem provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetItem(_a0 context.Context, _a1 git.GetItemArgs) (*git.GitItem, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitItem + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemArgs) *git.GitItem); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitItem) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetItemArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetItemContent provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetItemContent(_a0 context.Context, _a1 git.GetItemContentArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + var r0 io.ReadCloser + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemContentArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetItemContentArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetItemText provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetItemText(_a0 context.Context, _a1 git.GetItemTextArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + var r0 io.ReadCloser + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemTextArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetItemTextArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetItemZip provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetItemZip(_a0 context.Context, _a1 git.GetItemZipArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + var r0 io.ReadCloser + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemZipArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetItemZipArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetItems provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetItems(_a0 context.Context, _a1 git.GetItemsArgs) (*[]git.GitItem, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitItem + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemsArgs) *[]git.GitItem); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitItem) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetItemsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetItemsBatch provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetItemsBatch(_a0 context.Context, _a1 git.GetItemsBatchArgs) (*[][]git.GitItem, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[][]git.GitItem + if rf, ok := ret.Get(0).(func(context.Context, git.GetItemsBatchArgs) *[][]git.GitItem); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[][]git.GitItem) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetItemsBatchArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetLikes provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetLikes(_a0 context.Context, _a1 git.GetLikesArgs) (*[]webapi.IdentityRef, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]webapi.IdentityRef + if rf, ok := ret.Get(0).(func(context.Context, git.GetLikesArgs) *[]webapi.IdentityRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]webapi.IdentityRef) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetLikesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetMergeBases provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetMergeBases(_a0 context.Context, _a1 git.GetMergeBasesArgs) (*[]git.GitCommitRef, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitCommitRef + if rf, ok := ret.Get(0).(func(context.Context, git.GetMergeBasesArgs) *[]git.GitCommitRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitCommitRef) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetMergeBasesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetMergeRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetMergeRequest(_a0 context.Context, _a1 git.GetMergeRequestArgs) (*git.GitMerge, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitMerge + if rf, ok := ret.Get(0).(func(context.Context, git.GetMergeRequestArgs) *git.GitMerge); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitMerge) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetMergeRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPolicyConfigurations provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPolicyConfigurations(_a0 context.Context, _a1 git.GetPolicyConfigurationsArgs) (*git.GitPolicyConfigurationResponse, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitPolicyConfigurationResponse + if rf, ok := ret.Get(0).(func(context.Context, git.GetPolicyConfigurationsArgs) *git.GitPolicyConfigurationResponse); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPolicyConfigurationResponse) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPolicyConfigurationsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequest(_a0 context.Context, _a1 git.GetPullRequestArgs) (*git.GitPullRequest, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitPullRequest + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestArgs) *git.GitPullRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequest) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestById provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestById(_a0 context.Context, _a1 git.GetPullRequestByIdArgs) (*git.GitPullRequest, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitPullRequest + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestByIdArgs) *git.GitPullRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequest) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestByIdArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestCommits provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestCommits(_a0 context.Context, _a1 git.GetPullRequestCommitsArgs) (*git.GetPullRequestCommitsResponseValue, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GetPullRequestCommitsResponseValue + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestCommitsArgs) *git.GetPullRequestCommitsResponseValue); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GetPullRequestCommitsResponseValue) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestCommitsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestIteration provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestIteration(_a0 context.Context, _a1 git.GetPullRequestIterationArgs) (*git.GitPullRequestIteration, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitPullRequestIteration + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationArgs) *git.GitPullRequestIteration); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestIteration) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestIterationChanges provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestIterationChanges(_a0 context.Context, _a1 git.GetPullRequestIterationChangesArgs) (*git.GitPullRequestIterationChanges, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitPullRequestIterationChanges + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationChangesArgs) *git.GitPullRequestIterationChanges); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestIterationChanges) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationChangesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestIterationCommits provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestIterationCommits(_a0 context.Context, _a1 git.GetPullRequestIterationCommitsArgs) (*[]git.GitCommitRef, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitCommitRef + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationCommitsArgs) *[]git.GitCommitRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitCommitRef) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationCommitsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestIterationStatus provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestIterationStatus(_a0 context.Context, _a1 git.GetPullRequestIterationStatusArgs) (*git.GitPullRequestStatus, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitPullRequestStatus + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationStatusArgs) *git.GitPullRequestStatus); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestStatus) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationStatusArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestIterationStatuses provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestIterationStatuses(_a0 context.Context, _a1 git.GetPullRequestIterationStatusesArgs) (*[]git.GitPullRequestStatus, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitPullRequestStatus + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationStatusesArgs) *[]git.GitPullRequestStatus); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitPullRequestStatus) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationStatusesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestIterations provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestIterations(_a0 context.Context, _a1 git.GetPullRequestIterationsArgs) (*[]git.GitPullRequestIteration, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitPullRequestIteration + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestIterationsArgs) *[]git.GitPullRequestIteration); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitPullRequestIteration) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestIterationsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestLabel provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestLabel(_a0 context.Context, _a1 git.GetPullRequestLabelArgs) (*core.WebApiTagDefinition, error) { + ret := _m.Called(_a0, _a1) + + var r0 *core.WebApiTagDefinition + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestLabelArgs) *core.WebApiTagDefinition); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*core.WebApiTagDefinition) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestLabelArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestLabels provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestLabels(_a0 context.Context, _a1 git.GetPullRequestLabelsArgs) (*[]core.WebApiTagDefinition, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]core.WebApiTagDefinition + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestLabelsArgs) *[]core.WebApiTagDefinition); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]core.WebApiTagDefinition) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestLabelsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestProperties provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestProperties(_a0 context.Context, _a1 git.GetPullRequestPropertiesArgs) (interface{}, error) { + ret := _m.Called(_a0, _a1) + + var r0 interface{} + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestPropertiesArgs) interface{}); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(interface{}) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestPropertiesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestQuery provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestQuery(_a0 context.Context, _a1 git.GetPullRequestQueryArgs) (*git.GitPullRequestQuery, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitPullRequestQuery + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestQueryArgs) *git.GitPullRequestQuery); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestQuery) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestQueryArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestReviewer provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestReviewer(_a0 context.Context, _a1 git.GetPullRequestReviewerArgs) (*git.IdentityRefWithVote, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.IdentityRefWithVote + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestReviewerArgs) *git.IdentityRefWithVote); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.IdentityRefWithVote) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestReviewerArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestReviewers provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestReviewers(_a0 context.Context, _a1 git.GetPullRequestReviewersArgs) (*[]git.IdentityRefWithVote, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.IdentityRefWithVote + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestReviewersArgs) *[]git.IdentityRefWithVote); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.IdentityRefWithVote) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestReviewersArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestStatus provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestStatus(_a0 context.Context, _a1 git.GetPullRequestStatusArgs) (*git.GitPullRequestStatus, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitPullRequestStatus + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestStatusArgs) *git.GitPullRequestStatus); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestStatus) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestStatusArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestStatuses provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestStatuses(_a0 context.Context, _a1 git.GetPullRequestStatusesArgs) (*[]git.GitPullRequestStatus, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitPullRequestStatus + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestStatusesArgs) *[]git.GitPullRequestStatus); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitPullRequestStatus) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestStatusesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestThread provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestThread(_a0 context.Context, _a1 git.GetPullRequestThreadArgs) (*git.GitPullRequestCommentThread, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitPullRequestCommentThread + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestThreadArgs) *git.GitPullRequestCommentThread); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestCommentThread) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestThreadArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestWorkItemRefs provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestWorkItemRefs(_a0 context.Context, _a1 git.GetPullRequestWorkItemRefsArgs) (*[]webapi.ResourceRef, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]webapi.ResourceRef + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestWorkItemRefsArgs) *[]webapi.ResourceRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]webapi.ResourceRef) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestWorkItemRefsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequests provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequests(_a0 context.Context, _a1 git.GetPullRequestsArgs) (*[]git.GitPullRequest, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitPullRequest + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestsArgs) *[]git.GitPullRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitPullRequest) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPullRequestsByProject provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPullRequestsByProject(_a0 context.Context, _a1 git.GetPullRequestsByProjectArgs) (*[]git.GitPullRequest, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitPullRequest + if rf, ok := ret.Get(0).(func(context.Context, git.GetPullRequestsByProjectArgs) *[]git.GitPullRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitPullRequest) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPullRequestsByProjectArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPush provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPush(_a0 context.Context, _a1 git.GetPushArgs) (*git.GitPush, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitPush + if rf, ok := ret.Get(0).(func(context.Context, git.GetPushArgs) *git.GitPush); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPush) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPushArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPushCommits provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPushCommits(_a0 context.Context, _a1 git.GetPushCommitsArgs) (*[]git.GitCommitRef, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitCommitRef + if rf, ok := ret.Get(0).(func(context.Context, git.GetPushCommitsArgs) *[]git.GitCommitRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitCommitRef) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPushCommitsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetPushes provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetPushes(_a0 context.Context, _a1 git.GetPushesArgs) (*[]git.GitPush, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitPush + if rf, ok := ret.Get(0).(func(context.Context, git.GetPushesArgs) *[]git.GitPush); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitPush) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetPushesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRecycleBinRepositories provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRecycleBinRepositories(_a0 context.Context, _a1 git.GetRecycleBinRepositoriesArgs) (*[]git.GitDeletedRepository, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitDeletedRepository + if rf, ok := ret.Get(0).(func(context.Context, git.GetRecycleBinRepositoriesArgs) *[]git.GitDeletedRepository); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitDeletedRepository) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetRecycleBinRepositoriesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRefFavorite provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRefFavorite(_a0 context.Context, _a1 git.GetRefFavoriteArgs) (*git.GitRefFavorite, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitRefFavorite + if rf, ok := ret.Get(0).(func(context.Context, git.GetRefFavoriteArgs) *git.GitRefFavorite); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRefFavorite) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetRefFavoriteArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRefFavorites provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRefFavorites(_a0 context.Context, _a1 git.GetRefFavoritesArgs) (*[]git.GitRefFavorite, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitRefFavorite + if rf, ok := ret.Get(0).(func(context.Context, git.GetRefFavoritesArgs) *[]git.GitRefFavorite); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitRefFavorite) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetRefFavoritesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRefs provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRefs(_a0 context.Context, _a1 git.GetRefsArgs) (*git.GetRefsResponseValue, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GetRefsResponseValue + if rf, ok := ret.Get(0).(func(context.Context, git.GetRefsArgs) *git.GetRefsResponseValue); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GetRefsResponseValue) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetRefsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRepositories provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRepositories(_a0 context.Context, _a1 git.GetRepositoriesArgs) (*[]git.GitRepository, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitRepository + if rf, ok := ret.Get(0).(func(context.Context, git.GetRepositoriesArgs) *[]git.GitRepository); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitRepository) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetRepositoriesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRepository provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRepository(_a0 context.Context, _a1 git.GetRepositoryArgs) (*git.GitRepository, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitRepository + if rf, ok := ret.Get(0).(func(context.Context, git.GetRepositoryArgs) *git.GitRepository); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRepository) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetRepositoryArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRepositoryWithParent provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRepositoryWithParent(_a0 context.Context, _a1 git.GetRepositoryWithParentArgs) (*git.GitRepository, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitRepository + if rf, ok := ret.Get(0).(func(context.Context, git.GetRepositoryWithParentArgs) *git.GitRepository); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRepository) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetRepositoryWithParentArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRevert provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRevert(_a0 context.Context, _a1 git.GetRevertArgs) (*git.GitRevert, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitRevert + if rf, ok := ret.Get(0).(func(context.Context, git.GetRevertArgs) *git.GitRevert); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRevert) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetRevertArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRevertForRefName provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetRevertForRefName(_a0 context.Context, _a1 git.GetRevertForRefNameArgs) (*git.GitRevert, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitRevert + if rf, ok := ret.Get(0).(func(context.Context, git.GetRevertForRefNameArgs) *git.GitRevert); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRevert) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetRevertForRefNameArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetStatuses provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetStatuses(_a0 context.Context, _a1 git.GetStatusesArgs) (*[]git.GitStatus, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitStatus + if rf, ok := ret.Get(0).(func(context.Context, git.GetStatusesArgs) *[]git.GitStatus); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitStatus) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetStatusesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetSuggestions provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetSuggestions(_a0 context.Context, _a1 git.GetSuggestionsArgs) (*[]git.GitSuggestion, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitSuggestion + if rf, ok := ret.Get(0).(func(context.Context, git.GetSuggestionsArgs) *[]git.GitSuggestion); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitSuggestion) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetSuggestionsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetThreads provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetThreads(_a0 context.Context, _a1 git.GetThreadsArgs) (*[]git.GitPullRequestCommentThread, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitPullRequestCommentThread + if rf, ok := ret.Get(0).(func(context.Context, git.GetThreadsArgs) *[]git.GitPullRequestCommentThread); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitPullRequestCommentThread) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetThreadsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetTree provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetTree(_a0 context.Context, _a1 git.GetTreeArgs) (*git.GitTreeRef, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitTreeRef + if rf, ok := ret.Get(0).(func(context.Context, git.GetTreeArgs) *git.GitTreeRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitTreeRef) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetTreeArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetTreeZip provides a mock function with given fields: _a0, _a1 +func (_m *Client) GetTreeZip(_a0 context.Context, _a1 git.GetTreeZipArgs) (io.ReadCloser, error) { + ret := _m.Called(_a0, _a1) + + var r0 io.ReadCloser + if rf, ok := ret.Get(0).(func(context.Context, git.GetTreeZipArgs) io.ReadCloser); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(io.ReadCloser) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.GetTreeZipArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// QueryImportRequests provides a mock function with given fields: _a0, _a1 +func (_m *Client) QueryImportRequests(_a0 context.Context, _a1 git.QueryImportRequestsArgs) (*[]git.GitImportRequest, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitImportRequest + if rf, ok := ret.Get(0).(func(context.Context, git.QueryImportRequestsArgs) *[]git.GitImportRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitImportRequest) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.QueryImportRequestsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RestoreRepositoryFromRecycleBin provides a mock function with given fields: _a0, _a1 +func (_m *Client) RestoreRepositoryFromRecycleBin(_a0 context.Context, _a1 git.RestoreRepositoryFromRecycleBinArgs) (*git.GitRepository, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitRepository + if rf, ok := ret.Get(0).(func(context.Context, git.RestoreRepositoryFromRecycleBinArgs) *git.GitRepository); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRepository) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.RestoreRepositoryFromRecycleBinArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SharePullRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) SharePullRequest(_a0 context.Context, _a1 git.SharePullRequestArgs) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.SharePullRequestArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// UpdateComment provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdateComment(_a0 context.Context, _a1 git.UpdateCommentArgs) (*git.Comment, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.Comment + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateCommentArgs) *git.Comment); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.Comment) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.UpdateCommentArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateImportRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdateImportRequest(_a0 context.Context, _a1 git.UpdateImportRequestArgs) (*git.GitImportRequest, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitImportRequest + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateImportRequestArgs) *git.GitImportRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitImportRequest) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.UpdateImportRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdatePullRequest provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdatePullRequest(_a0 context.Context, _a1 git.UpdatePullRequestArgs) (*git.GitPullRequest, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitPullRequest + if rf, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestArgs) *git.GitPullRequest); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequest) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.UpdatePullRequestArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdatePullRequestIterationStatuses provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdatePullRequestIterationStatuses(_a0 context.Context, _a1 git.UpdatePullRequestIterationStatusesArgs) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestIterationStatusesArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// UpdatePullRequestProperties provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdatePullRequestProperties(_a0 context.Context, _a1 git.UpdatePullRequestPropertiesArgs) (interface{}, error) { + ret := _m.Called(_a0, _a1) + + var r0 interface{} + if rf, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestPropertiesArgs) interface{}); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(interface{}) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.UpdatePullRequestPropertiesArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdatePullRequestReviewers provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdatePullRequestReviewers(_a0 context.Context, _a1 git.UpdatePullRequestReviewersArgs) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestReviewersArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// UpdatePullRequestStatuses provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdatePullRequestStatuses(_a0 context.Context, _a1 git.UpdatePullRequestStatusesArgs) error { + ret := _m.Called(_a0, _a1) + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, git.UpdatePullRequestStatusesArgs) error); ok { + r0 = rf(_a0, _a1) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// UpdateRef provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdateRef(_a0 context.Context, _a1 git.UpdateRefArgs) (*git.GitRef, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitRef + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateRefArgs) *git.GitRef); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRef) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.UpdateRefArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateRefs provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdateRefs(_a0 context.Context, _a1 git.UpdateRefsArgs) (*[]git.GitRefUpdateResult, error) { + ret := _m.Called(_a0, _a1) + + var r0 *[]git.GitRefUpdateResult + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateRefsArgs) *[]git.GitRefUpdateResult); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*[]git.GitRefUpdateResult) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.UpdateRefsArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateRepository provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdateRepository(_a0 context.Context, _a1 git.UpdateRepositoryArgs) (*git.GitRepository, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitRepository + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateRepositoryArgs) *git.GitRepository); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitRepository) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.UpdateRepositoryArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UpdateThread provides a mock function with given fields: _a0, _a1 +func (_m *Client) UpdateThread(_a0 context.Context, _a1 git.UpdateThreadArgs) (*git.GitPullRequestCommentThread, error) { + ret := _m.Called(_a0, _a1) + + var r0 *git.GitPullRequestCommentThread + if rf, ok := ret.Get(0).(func(context.Context, git.UpdateThreadArgs) *git.GitPullRequestCommentThread); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*git.GitPullRequestCommentThread) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(context.Context, git.UpdateThreadArgs) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} diff --git a/applicationset/services/scm_provider/azure_devops_test.go b/applicationset/services/scm_provider/azure_devops_test.go new file mode 100644 index 0000000000000..219e770d71250 --- /dev/null +++ b/applicationset/services/scm_provider/azure_devops_test.go @@ -0,0 +1,530 @@ +package scm_provider + +import ( + "context" + "fmt" + "testing" + + "github.com/google/uuid" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/mock" + "k8s.io/utils/pointer" + + azureMock "github.com/argoproj/argo-cd/v2/applicationset/services/scm_provider/azure_devops/git/mocks" + "github.com/microsoft/azure-devops-go-api/azuredevops" + azureGit "github.com/microsoft/azure-devops-go-api/azuredevops/git" +) + +func s(input string) *string { + return pointer.String(input) +} + +func TestAzureDevopsRepoHasPath(t *testing.T) { + organization := "myorg" + teamProject := "myorg_project" + repoName := "myorg_project_repo" + path := "dir/subdir/item.yaml" + branchName := "my/featurebranch" + + ctx := context.Background() + uuid := uuid.New().String() + + testCases := []struct { + name string + pathFound bool + azureDevopsError error + returnError bool + errorMessage string + clientError error + }{ + { + name: "RepoHasPath when Azure DevOps client factory fails returns error", + clientError: fmt.Errorf("Client factory error"), + }, + { + name: "RepoHasPath when found returns true", + pathFound: true, + }, + { + name: "RepoHasPath when no path found returns false", + pathFound: false, + azureDevopsError: azuredevops.WrappedError{TypeKey: s(AzureDevOpsErrorsTypeKeyValues.GitItemNotFound)}, + }, + { + name: "RepoHasPath when unknown Azure DevOps WrappedError occurs returns error", + pathFound: false, + azureDevopsError: azuredevops.WrappedError{TypeKey: s("OtherAzureDevopsException")}, + returnError: true, + errorMessage: "failed to check for path existence", + }, + { + name: "RepoHasPath when unknown Azure DevOps error occurs returns error", + pathFound: false, + azureDevopsError: fmt.Errorf("Undefined error from Azure Devops"), + returnError: true, + errorMessage: "failed to check for path existence", + }, + { + name: "RepoHasPath when wrapped Azure DevOps error occurs without TypeKey returns error", + pathFound: false, + azureDevopsError: azuredevops.WrappedError{}, + returnError: true, + errorMessage: "failed to check for path existence", + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + gitClientMock := azureMock.Client{} + + clientFactoryMock := &AzureClientFactoryMock{mock: &mock.Mock{}} + clientFactoryMock.mock.On("GetClient", mock.Anything).Return(&gitClientMock, testCase.clientError) + + repoId := &uuid + gitClientMock.On("GetItem", ctx, azureGit.GetItemArgs{Project: &teamProject, Path: &path, VersionDescriptor: &azureGit.GitVersionDescriptor{Version: &branchName}, RepositoryId: repoId}).Return(nil, testCase.azureDevopsError) + + provider := AzureDevOpsProvider{organization: organization, teamProject: teamProject, clientFactory: clientFactoryMock} + + repo := &Repository{Organization: organization, Repository: repoName, RepositoryId: uuid, Branch: branchName} + hasPath, err := provider.RepoHasPath(ctx, repo, path) + + if testCase.clientError != nil { + assert.ErrorContains(t, err, testCase.clientError.Error()) + gitClientMock.AssertNotCalled(t, "GetItem", ctx, azureGit.GetItemArgs{Project: &teamProject, Path: &path, VersionDescriptor: &azureGit.GitVersionDescriptor{Version: &branchName}, RepositoryId: repoId}) + + return + } + + if testCase.returnError { + assert.ErrorContains(t, err, testCase.errorMessage) + } + + assert.Equal(t, testCase.pathFound, hasPath) + + gitClientMock.AssertCalled(t, "GetItem", ctx, azureGit.GetItemArgs{Project: &teamProject, Path: &path, VersionDescriptor: &azureGit.GitVersionDescriptor{Version: &branchName}, RepositoryId: repoId}) + + }) + } +} + +func TestGetDefaultBranchOnDisabledRepo(t *testing.T) { + + organization := "myorg" + teamProject := "myorg_project" + repoName := "myorg_project_repo" + defaultBranch := "main" + + ctx := context.Background() + + testCases := []struct { + name string + azureDevOpsError error + shouldReturnError bool + }{ + { + name: "azure devops error when disabled repo causes empty return value", + azureDevOpsError: azuredevops.WrappedError{TypeKey: s(AzureDevOpsErrorsTypeKeyValues.GitRepositoryNotFound)}, + shouldReturnError: false, + }, + { + name: "azure devops error with unknown error type returns error", + azureDevOpsError: azuredevops.WrappedError{TypeKey: s("OtherError")}, + shouldReturnError: true, + }, + { + name: "other error when calling azure devops returns error", + azureDevOpsError: fmt.Errorf("some unknown error"), + shouldReturnError: true, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + uuid := uuid.New().String() + + gitClientMock := azureMock.Client{} + + clientFactoryMock := &AzureClientFactoryMock{mock: &mock.Mock{}} + clientFactoryMock.mock.On("GetClient", mock.Anything).Return(&gitClientMock, nil) + + gitClientMock.On("GetBranch", ctx, azureGit.GetBranchArgs{RepositoryId: &repoName, Project: &teamProject, Name: &defaultBranch}).Return(nil, testCase.azureDevOpsError) + + repo := &Repository{Organization: organization, Repository: repoName, RepositoryId: uuid, Branch: defaultBranch} + + provider := AzureDevOpsProvider{organization: organization, teamProject: teamProject, clientFactory: clientFactoryMock, allBranches: false} + branches, err := provider.GetBranches(ctx, repo) + + if testCase.shouldReturnError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + + assert.Empty(t, branches) + + gitClientMock.AssertExpectations(t) + }) + } +} + +func TestGetAllBranchesOnDisabledRepo(t *testing.T) { + + organization := "myorg" + teamProject := "myorg_project" + repoName := "myorg_project_repo" + defaultBranch := "main" + + ctx := context.Background() + + testCases := []struct { + name string + azureDevOpsError error + shouldReturnError bool + }{ + { + name: "azure devops error when disabled repo causes empty return value", + azureDevOpsError: azuredevops.WrappedError{TypeKey: s(AzureDevOpsErrorsTypeKeyValues.GitRepositoryNotFound)}, + shouldReturnError: false, + }, + { + name: "azure devops error with unknown error type returns error", + azureDevOpsError: azuredevops.WrappedError{TypeKey: s("OtherError")}, + shouldReturnError: true, + }, + { + name: "other error when calling azure devops returns error", + azureDevOpsError: fmt.Errorf("some unknown error"), + shouldReturnError: true, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + uuid := uuid.New().String() + + gitClientMock := azureMock.Client{} + + clientFactoryMock := &AzureClientFactoryMock{mock: &mock.Mock{}} + clientFactoryMock.mock.On("GetClient", mock.Anything).Return(&gitClientMock, nil) + + gitClientMock.On("GetBranches", ctx, azureGit.GetBranchesArgs{RepositoryId: &repoName, Project: &teamProject}).Return(nil, testCase.azureDevOpsError) + + repo := &Repository{Organization: organization, Repository: repoName, RepositoryId: uuid, Branch: defaultBranch} + + provider := AzureDevOpsProvider{organization: organization, teamProject: teamProject, clientFactory: clientFactoryMock, allBranches: true} + branches, err := provider.GetBranches(ctx, repo) + + if testCase.shouldReturnError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + + assert.Empty(t, branches) + + gitClientMock.AssertExpectations(t) + }) + } +} + +func TestAzureDevOpsGetDefaultBranchStripsRefsName(t *testing.T) { + + t.Run("Get branches only default branch removes characters before querying azure devops", func(t *testing.T) { + + organization := "myorg" + teamProject := "myorg_project" + repoName := "myorg_project_repo" + + ctx := context.Background() + uuid := uuid.New().String() + strippedBranchName := "somebranch" + defaultBranch := fmt.Sprintf("refs/heads/%v", strippedBranchName) + + branchReturn := &azureGit.GitBranchStats{Name: &strippedBranchName, Commit: &azureGit.GitCommitRef{CommitId: s("abc123233223")}} + repo := &Repository{Organization: organization, Repository: repoName, RepositoryId: uuid, Branch: defaultBranch} + + gitClientMock := azureMock.Client{} + + clientFactoryMock := &AzureClientFactoryMock{mock: &mock.Mock{}} + clientFactoryMock.mock.On("GetClient", mock.Anything).Return(&gitClientMock, nil) + + gitClientMock.On("GetBranch", ctx, azureGit.GetBranchArgs{RepositoryId: &repoName, Project: &teamProject, Name: &strippedBranchName}).Return(branchReturn, nil) + + provider := AzureDevOpsProvider{organization: organization, teamProject: teamProject, clientFactory: clientFactoryMock, allBranches: false} + branches, err := provider.GetBranches(ctx, repo) + + assert.NoError(t, err) + assert.Len(t, branches, 1) + assert.Equal(t, strippedBranchName, branches[0].Branch) + + gitClientMock.AssertCalled(t, "GetBranch", ctx, azureGit.GetBranchArgs{RepositoryId: &repoName, Project: &teamProject, Name: &strippedBranchName}) + }) +} + +func TestAzureDevOpsGetBranchesDefultBranchOnly(t *testing.T) { + organization := "myorg" + teamProject := "myorg_project" + repoName := "myorg_project_repo" + + ctx := context.Background() + uuid := uuid.New().String() + + defaultBranch := "main" + + testCases := []struct { + name string + expectedBranch *azureGit.GitBranchStats + getBranchesApiError error + clientError error + }{ + { + name: "GetBranches AllBranches false when single branch returned returns branch", + expectedBranch: &azureGit.GitBranchStats{Name: &defaultBranch, Commit: &azureGit.GitCommitRef{CommitId: s("abc123233223")}}, + }, + { + name: "GetBranches AllBranches false when request fails returns error and empty result", + getBranchesApiError: fmt.Errorf("Remote Azure Devops GetBranches error"), + }, + { + name: "GetBranches AllBranches false when Azure DevOps client fails returns error", + clientError: fmt.Errorf("Could not get Azure Devops API client"), + }, + { + name: "GetBranches AllBranches false when branch returned with long commit SHA", + expectedBranch: &azureGit.GitBranchStats{Name: &defaultBranch, Commit: &azureGit.GitCommitRef{CommitId: s("53863052ADF24229AB72154B4D83DAB7")}}, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + gitClientMock := azureMock.Client{} + + clientFactoryMock := &AzureClientFactoryMock{mock: &mock.Mock{}} + clientFactoryMock.mock.On("GetClient", mock.Anything).Return(&gitClientMock, testCase.clientError) + + gitClientMock.On("GetBranch", ctx, azureGit.GetBranchArgs{RepositoryId: &repoName, Project: &teamProject, Name: &defaultBranch}).Return(testCase.expectedBranch, testCase.getBranchesApiError) + + repo := &Repository{Organization: organization, Repository: repoName, RepositoryId: uuid, Branch: defaultBranch} + + provider := AzureDevOpsProvider{organization: organization, teamProject: teamProject, clientFactory: clientFactoryMock, allBranches: false} + branches, err := provider.GetBranches(ctx, repo) + + if testCase.clientError != nil { + assert.ErrorContains(t, err, testCase.clientError.Error()) + gitClientMock.AssertNotCalled(t, "GetBranch", ctx, azureGit.GetBranchArgs{RepositoryId: &repoName, Project: &teamProject, Name: &defaultBranch}) + + return + } + + if testCase.getBranchesApiError != nil { + assert.Empty(t, branches) + assert.ErrorContains(t, err, testCase.getBranchesApiError.Error()) + } else { + if testCase.expectedBranch != nil { + assert.NotEmpty(t, branches) + } + assert.Len(t, branches, 1) + assert.Equal(t, repo.RepositoryId, branches[0].RepositoryId) + } + + gitClientMock.AssertCalled(t, "GetBranch", ctx, azureGit.GetBranchArgs{RepositoryId: &repoName, Project: &teamProject, Name: &defaultBranch}) + }) + } +} + +func TestAzureDevopsGetBranches(t *testing.T) { + organization := "myorg" + teamProject := "myorg_project" + repoName := "myorg_project_repo" + + ctx := context.Background() + uuid := uuid.New().String() + + testCases := []struct { + name string + expectedBranches *[]azureGit.GitBranchStats + getBranchesApiError error + clientError error + allBranches bool + expectedProcessingErrorMsg string + }{ + { + name: "GetBranches when single branch returned returns this branch info", + expectedBranches: &[]azureGit.GitBranchStats{{Name: s("feature-feat1"), Commit: &azureGit.GitCommitRef{CommitId: s("abc123233223")}}}, + allBranches: true, + }, + { + name: "GetBranches when Azure DevOps request fails returns error and empty result", + getBranchesApiError: fmt.Errorf("Remote Azure Devops GetBranches error"), + allBranches: true, + }, + { + name: "GetBranches when no branches returned returns error", + allBranches: true, + expectedProcessingErrorMsg: "empty branch result", + }, + { + name: "GetBranches when git client retrievel fails returns error", + clientError: fmt.Errorf("Could not get Azure Devops API client"), + allBranches: true, + }, + { + name: "GetBranches when multiple branches returned returns branch info for all branches", + expectedBranches: &[]azureGit.GitBranchStats{ + {Name: s("feature-feat1"), Commit: &azureGit.GitCommitRef{CommitId: s("abc123233223")}}, + {Name: s("feature/feat2"), Commit: &azureGit.GitCommitRef{CommitId: s("4334")}}, + {Name: s("feature/feat2"), Commit: &azureGit.GitCommitRef{CommitId: s("53863052ADF24229AB72154B4D83DAB7")}}, + }, + allBranches: true, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + gitClientMock := azureMock.Client{} + + clientFactoryMock := &AzureClientFactoryMock{mock: &mock.Mock{}} + clientFactoryMock.mock.On("GetClient", mock.Anything).Return(&gitClientMock, testCase.clientError) + + gitClientMock.On("GetBranches", ctx, azureGit.GetBranchesArgs{RepositoryId: &repoName, Project: &teamProject}).Return(testCase.expectedBranches, testCase.getBranchesApiError) + + repo := &Repository{Organization: organization, Repository: repoName, RepositoryId: uuid} + + provider := AzureDevOpsProvider{organization: organization, teamProject: teamProject, clientFactory: clientFactoryMock, allBranches: testCase.allBranches} + branches, err := provider.GetBranches(ctx, repo) + + if testCase.expectedProcessingErrorMsg != "" { + assert.ErrorContains(t, err, testCase.expectedProcessingErrorMsg) + assert.Nil(t, branches) + + return + } + if testCase.clientError != nil { + assert.ErrorContains(t, err, testCase.clientError.Error()) + gitClientMock.AssertNotCalled(t, "GetBranches", ctx, azureGit.GetBranchesArgs{RepositoryId: &repoName, Project: &teamProject}) + return + + } + + if testCase.getBranchesApiError != nil { + assert.Empty(t, branches) + assert.ErrorContains(t, err, testCase.getBranchesApiError.Error()) + } else { + if len(*testCase.expectedBranches) > 0 { + assert.NotEmpty(t, branches) + } + assert.Len(t, branches, len(*testCase.expectedBranches)) + for _, branch := range branches { + assert.NotEmpty(t, branch.RepositoryId) + assert.Equal(t, repo.RepositoryId, branch.RepositoryId) + } + } + + gitClientMock.AssertCalled(t, "GetBranches", ctx, azureGit.GetBranchesArgs{RepositoryId: &repoName, Project: &teamProject}) + }) + } +} + +func TestGetAzureDevopsRepositories(t *testing.T) { + organization := "myorg" + teamProject := "myorg_project" + + uuid := uuid.New() + ctx := context.Background() + + repoId := &uuid + + testCases := []struct { + name string + getRepositoriesError error + repositories []azureGit.GitRepository + expectedNumberOfRepos int + }{ + { + name: "ListRepos when single repo found returns repo info", + repositories: []azureGit.GitRepository{{Name: s("repo1"), DefaultBranch: s("main"), RemoteUrl: s("https://remoteurl.u"), Id: repoId}}, + expectedNumberOfRepos: 1, + }, + { + name: "ListRepos when repo has no default branch returns empty list", + repositories: []azureGit.GitRepository{{Name: s("repo2"), RemoteUrl: s("https://remoteurl.u"), Id: repoId}}, + }, + { + name: "ListRepos when Azure DevOps request fails returns error", + getRepositoriesError: fmt.Errorf("Could not get repos"), + }, + { + name: "ListRepos when repo has no name returns empty list", + repositories: []azureGit.GitRepository{{DefaultBranch: s("main"), RemoteUrl: s("https://remoteurl.u"), Id: repoId}}, + }, + { + name: "ListRepos when repo has no remote URL returns empty list", + repositories: []azureGit.GitRepository{{DefaultBranch: s("main"), Name: s("repo_name"), Id: repoId}}, + }, + { + name: "ListRepos when repo has no ID returns empty list", + repositories: []azureGit.GitRepository{{DefaultBranch: s("main"), Name: s("repo_name"), RemoteUrl: s("https://remoteurl.u")}}, + }, + { + name: "ListRepos when multiple repos returned returns list of eligible repos only", + repositories: []azureGit.GitRepository{ + {Name: s("returned1"), DefaultBranch: s("main"), RemoteUrl: s("https://remoteurl.u"), Id: repoId}, + {Name: s("missing_default_branch"), RemoteUrl: s("https://remoteurl.u"), Id: repoId}, + {DefaultBranch: s("missing_name"), RemoteUrl: s("https://remoteurl.u"), Id: repoId}, + {Name: s("missing_remote_url"), DefaultBranch: s("main"), Id: repoId}, + {Name: s("missing_id"), DefaultBranch: s("main"), RemoteUrl: s("https://remoteurl.u")}}, + expectedNumberOfRepos: 1, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + + gitClientMock := azureMock.Client{} + gitClientMock.On("GetRepositories", ctx, azureGit.GetRepositoriesArgs{Project: s(teamProject)}).Return(&testCase.repositories, testCase.getRepositoriesError) + + clientFactoryMock := &AzureClientFactoryMock{mock: &mock.Mock{}} + clientFactoryMock.mock.On("GetClient", mock.Anything).Return(&gitClientMock) + + provider := AzureDevOpsProvider{organization: organization, teamProject: teamProject, clientFactory: clientFactoryMock} + + repositories, err := provider.ListRepos(ctx, "https") + + if testCase.getRepositoriesError != nil { + assert.Error(t, err, "Expected an error from test case %v", testCase.name) + } + + if testCase.expectedNumberOfRepos == 0 { + assert.Empty(t, repositories) + } else { + assert.NotEmpty(t, repositories) + assert.Len(t, repositories, testCase.expectedNumberOfRepos) + } + + gitClientMock.AssertExpectations(t) + }) + } +} + +type AzureClientFactoryMock struct { + mock *mock.Mock +} + +func (m *AzureClientFactoryMock) GetClient(ctx context.Context) (azureGit.Client, error) { + args := m.mock.Called(ctx) + + var client azureGit.Client + c := args.Get(0) + if c != nil { + client = c.(azureGit.Client) + } + + var err error + if len(args) > 1 { + if e, ok := args.Get(1).(error); ok { + err = e + } + } + + return client, err +} diff --git a/docs/operator-manual/applicationset/Generators-SCM-Provider.md b/docs/operator-manual/applicationset/Generators-SCM-Provider.md index ee430fcd0778b..54d0de7da0fe6 100644 --- a/docs/operator-manual/applicationset/Generators-SCM-Provider.md +++ b/docs/operator-manual/applicationset/Generators-SCM-Provider.md @@ -178,6 +178,43 @@ If you want to access a private repository, you must also provide the credential Available clone protocols are `ssh` and `https`. +## Azure DevOps + +Uses the Azure DevOps API to look up eligible repositories based on a team project within an Azure DevOps organization. +The default Azure DevOps URL is `https://dev.azure.com`, but this can be overridden with the environment variable `AZURE_DEVOPS_BASE_URL`. + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: ApplicationSet +metadata: + name: myapps +spec: + generators: + - scmProvider: + azureDevOps: + # The Azure DevOps organization. + organization: myorg + # URL to Azure DevOps. Optional. Defaults to https://dev.azure.com. + api: https://dev.azure.com + # If true, scan every branch of eligible repositories. If false, check only the default branch of the eligible repositories. Defaults to false. + allBranches: true + # The team project within the specified Azure DevOps organization. + teamProject: myProject + # Reference to a Secret containing the Azure DevOps Personal Access Token (PAT) used for accessing Azure DevOps. + accessTokenRef: + secretName: azure-devops-scm + key: accesstoken + template: + # ... +``` + +* `organization`: Required. Name of the Azure DevOps organization. +* `teamProject`: Required. The name of the team project within the specified `organization`. +* `accessTokenRef`: Required. A `Secret` name and key containing the Azure DevOps Personal Access Token (PAT) to use for requests. +* `api`: Optional. URL to Azure DevOps. If not set, `https://dev.azure.com` is used. +* `allBranches`: Optional, default `false`. If `true`, scans every branch of eligible repositories. If `false`, check only the default branch of the eligible repositories. + + ## Filters Filters allow selecting which repositories to generate for. Each filter can declare one or more conditions, all of which must pass. If multiple filters are present, any can match for a repository to be included. If no filters are specified, all repositories will be processed. @@ -242,3 +279,4 @@ spec: * `branch`: The default branch of the repository. * `sha`: The Git commit SHA for the branch * `labels`: A comma-separated list of repository labels +* `branchNormalized`: The value of `branch` normalized to contain only lowercase alphanumeric characters, '-' or '.'. diff --git a/go.mod b/go.mod index 6d8c97fb802d2..a1d2ff2929c2b 100644 --- a/go.mod +++ b/go.mod @@ -231,6 +231,7 @@ require ( require ( github.com/gosimple/slug v1.12.0 + github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.31.0 go.opentelemetry.io/otel v1.6.3 go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.6.3 diff --git a/go.sum b/go.sum index bf1840ab03acd..cea0662af0434 100644 --- a/go.sum +++ b/go.sum @@ -810,6 +810,8 @@ github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpe github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5 h1:YH424zrwLTlyHSH/GzLMJeu5zhYVZSx5RQxGKm1h96s= +github.com/microsoft/azure-devops-go-api/azuredevops v1.0.0-b5/go.mod h1:PoGiBqKSQK1vIfQ+yVaFcGjDySHvym6FM1cNYnwzbrY= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= diff --git a/manifests/core-install.yaml b/manifests/core-install.yaml index 546ba4d327a6e..e23ced767ccf9 100644 --- a/manifests/core-install.yaml +++ b/manifests/core-install.yaml @@ -4831,6 +4831,31 @@ spec: type: object scmProvider: properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object bitbucket: properties: allBranches: @@ -7009,6 +7034,31 @@ spec: type: object scmProvider: properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object bitbucket: properties: allBranches: @@ -8052,6 +8102,31 @@ spec: type: object scmProvider: properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object bitbucket: properties: allBranches: diff --git a/manifests/crds/applicationset-crd.yaml b/manifests/crds/applicationset-crd.yaml index cc1e8938541d2..e642c5d9ce6ac 100644 --- a/manifests/crds/applicationset-crd.yaml +++ b/manifests/crds/applicationset-crd.yaml @@ -2679,6 +2679,31 @@ spec: type: object scmProvider: properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object bitbucket: properties: allBranches: @@ -4857,6 +4882,31 @@ spec: type: object scmProvider: properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object bitbucket: properties: allBranches: @@ -5900,6 +5950,31 @@ spec: type: object scmProvider: properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object bitbucket: properties: allBranches: diff --git a/manifests/ha/install.yaml b/manifests/ha/install.yaml index cd444f6015c28..af7f3b5ae63ad 100644 --- a/manifests/ha/install.yaml +++ b/manifests/ha/install.yaml @@ -4831,6 +4831,31 @@ spec: type: object scmProvider: properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object bitbucket: properties: allBranches: @@ -7009,6 +7034,31 @@ spec: type: object scmProvider: properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object bitbucket: properties: allBranches: @@ -8052,6 +8102,31 @@ spec: type: object scmProvider: properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object bitbucket: properties: allBranches: diff --git a/manifests/install.yaml b/manifests/install.yaml index 9d87bb456cfc6..f6e94de0a54f6 100644 --- a/manifests/install.yaml +++ b/manifests/install.yaml @@ -4831,6 +4831,31 @@ spec: type: object scmProvider: properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object bitbucket: properties: allBranches: @@ -7009,6 +7034,31 @@ spec: type: object scmProvider: properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object bitbucket: properties: allBranches: @@ -8052,6 +8102,31 @@ spec: type: object scmProvider: properties: + azureDevOps: + properties: + accessTokenRef: + properties: + key: + type: string + secretName: + type: string + required: + - key + - secretName + type: object + allBranches: + type: boolean + api: + type: string + organization: + type: string + teamProject: + type: string + required: + - accessTokenRef + - organization + - teamProject + type: object bitbucket: properties: allBranches: diff --git a/pkg/apis/applicationset/v1alpha1/applicationset_types.go b/pkg/apis/applicationset/v1alpha1/applicationset_types.go index 8da9e62a9ce19..2cdf13786a0e9 100644 --- a/pkg/apis/applicationset/v1alpha1/applicationset_types.go +++ b/pkg/apis/applicationset/v1alpha1/applicationset_types.go @@ -298,6 +298,7 @@ type SCMProviderGenerator struct { Bitbucket *SCMProviderGeneratorBitbucket `json:"bitbucket,omitempty"` BitbucketServer *SCMProviderGeneratorBitbucketServer `json:"bitbucketServer,omitempty"` Gitea *SCMProviderGeneratorGitea `json:"gitea,omitempty"` + AzureDevOps *SCMProviderGeneratorAzureDevOps `json:"azureDevOps,omitempty"` // Filters for which repos should be considered. Filters []SCMProviderGeneratorFilter `json:"filters,omitempty"` // Which protocol to use for the SCM URL. Default is provider-specific but ssh if possible. Not all providers @@ -372,6 +373,20 @@ type SCMProviderGeneratorBitbucketServer struct { AllBranches bool `json:"allBranches,omitempty"` } +// SCMProviderGeneratorAzureDevOps defines connection info specific to Azure DevOps. +type SCMProviderGeneratorAzureDevOps struct { + // Azure Devops organization. Required. E.g. "my-organization". + Organization string `json:"organization"` + // The URL to Azure DevOps. If blank, use https://dev.azure.com. + API string `json:"api,omitempty"` + // Azure Devops team project. Required. E.g. "my-team". + TeamProject string `json:"teamProject"` + // The Personal Access Token (PAT) to use when connecting. Required. + AccessTokenRef *SecretRef `json:"accessTokenRef"` + // Scan all branches instead of just the default branch. + AllBranches bool `json:"allBranches,omitempty"` +} + // SCMProviderGeneratorFilter is a single repository filter. // If multiple filter types are set on a single struct, they will be AND'd together. All filters must // pass for a repo to be included. diff --git a/pkg/apis/applicationset/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/applicationset/v1alpha1/zz_generated.deepcopy.go index 80635db9191e8..e043dcb302fb2 100644 --- a/pkg/apis/applicationset/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/applicationset/v1alpha1/zz_generated.deepcopy.go @@ -858,6 +858,11 @@ func (in *SCMProviderGenerator) DeepCopyInto(out *SCMProviderGenerator) { *out = new(SCMProviderGeneratorGitea) (*in).DeepCopyInto(*out) } + if in.AzureDevOps != nil { + in, out := &in.AzureDevOps, &out.AzureDevOps + *out = new(SCMProviderGeneratorAzureDevOps) + (*in).DeepCopyInto(*out) + } if in.Filters != nil { in, out := &in.Filters, &out.Filters *out = make([]SCMProviderGeneratorFilter, len(*in)) @@ -883,6 +888,26 @@ func (in *SCMProviderGenerator) DeepCopy() *SCMProviderGenerator { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SCMProviderGeneratorAzureDevOps) DeepCopyInto(out *SCMProviderGeneratorAzureDevOps) { + *out = *in + if in.AccessTokenRef != nil { + in, out := &in.AccessTokenRef, &out.AccessTokenRef + *out = new(SecretRef) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SCMProviderGeneratorAzureDevOps. +func (in *SCMProviderGeneratorAzureDevOps) DeepCopy() *SCMProviderGeneratorAzureDevOps { + if in == nil { + return nil + } + out := new(SCMProviderGeneratorAzureDevOps) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SCMProviderGeneratorBitbucket) DeepCopyInto(out *SCMProviderGeneratorBitbucket) { *out = *in