Skip to content

Commit

Permalink
FTR-92: Add features to support wiki creation
Browse files Browse the repository at this point in the history
  • Loading branch information
CDA0 committed Oct 24, 2023
1 parent 6e3f446 commit 3d6299b
Show file tree
Hide file tree
Showing 10 changed files with 331 additions and 0 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Utils Changelog

## v0.0.6

* Added `HasChanges` to `external_git`.
* Added `SetPullRequestAutoComplete` to `azuredevops`.
* Added `wiki` to `azuredevops`.
* Added `identity` to `azuredevops`.
* Added create and init repository to `azuredevops`.
* Added `getProjectUUID` to `azuredevops`.

## v0.0.5

* Improved error handling in `azuredevops` package.

## v0.0.4

* Updated `azuredevops` package to include pull request support.
Expand Down
19 changes: 19 additions & 0 deletions azuredevops/artifacts.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package azuredevops

import (
"github.com/microsoft/azure-devops-go-api/azuredevops/feed"
)

// GetPackageVersion gets all GitRepository
func (a *AzureDevOps) GetPackageVersion(projectName string, feedName string) (*[]feed.Package, error) {
feedClient, err := feed.NewClient(a.ctx, a.connection)
if err != nil {
return nil, err
}

getPackagesArgs := feed.GetPackagesArgs{
FeedId: &feedName,
Project: &projectName,
}
return feedClient.GetPackages(a.ctx, getPackagesArgs)
}
28 changes: 28 additions & 0 deletions azuredevops/git.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package azuredevops

import (
"github.com/microsoft/azure-devops-go-api/azuredevops/git"
)

// GetPackageVersion gets all GitRepository
func (a *AzureDevOps) GetFileContent(projectName string, repoName string, version string) (*git.GitItem, error) {
client, err := git.NewClient(a.ctx, a.connection)
if err != nil {
return nil, err
}

path := "README.md"
includeContent := true
gitVersionDescriptor := git.GitVersionDescriptor{
VersionType: &git.GitVersionTypeValues.Tag,
Version: &version,
}
getItemArgs := git.GetItemArgs{
RepositoryId: &repoName,
Project: &projectName,
Path: &path,
IncludeContent: &includeContent,
VersionDescriptor: &gitVersionDescriptor,
}
return client.GetItem(a.ctx, getItemArgs)
}
18 changes: 18 additions & 0 deletions azuredevops/identity.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package azuredevops

import (
"github.com/google/uuid"
"github.com/microsoft/azure-devops-go-api/azuredevops/location"
)

// GetIdentityId gets the UUID of the authenticated user. Yes this is weird, see https://github.com/microsoft/azure-devops-python-api/issues/188#issuecomment-494858123
func (a *AzureDevOps) GetIdentityId() (*uuid.UUID, error) {
client := location.NewClient(a.ctx, a.connection)

self, err := client.GetConnectionData(a.ctx, location.GetConnectionDataArgs{})
if err != nil {
return nil, err
}

return self.AuthenticatedUser.Id, nil
}
30 changes: 30 additions & 0 deletions azuredevops/project.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package azuredevops

import (
"fmt"

"github.com/google/uuid"
"github.com/microsoft/azure-devops-go-api/azuredevops/core"
)

// getProjectUUID gets the UUID of a project
func (a *AzureDevOps) getProjectUUID(projectName string) (*uuid.UUID, error) {
client, err := core.NewClient(a.ctx, a.connection)
if err != nil {
return nil, err
}

getProjectsArgs := core.GetProjectsArgs{}
projects, err := client.GetProjects(a.ctx, getProjectsArgs)
if err != nil {
return nil, err
}

for _, project := range *&projects.Value {
if *project.Name == projectName {
return project.Id, nil
}
}

return nil, fmt.Errorf("project %s not found", projectName)
}
30 changes: 30 additions & 0 deletions azuredevops/pull_request.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package azuredevops

import (
"github.com/google/uuid"
"github.com/microsoft/azure-devops-go-api/azuredevops/git"
"github.com/microsoft/azure-devops-go-api/azuredevops/webapi"
)

// AbandonPullRequest abandons a GitPullRequest
Expand Down Expand Up @@ -74,3 +76,31 @@ func (a *AzureDevOps) CreatePullRequest(projectName string, repositoryName strin
}
return client.CreatePullRequest(a.ctx, createPullRequestArgs)
}

// CompletePullRequest completes a GitPullRequest
func (a *AzureDevOps) SetPullRequestAutoComplete(projectName string, repositoryName string, pullRequestId int, userId *uuid.UUID) error {
client, err := git.NewClient(a.ctx, a.connection)
if err != nil {
return err
}

id := userId.String()
deleteSourceBranch := true

_, err = client.UpdatePullRequest(a.ctx, git.UpdatePullRequestArgs{
Project: &projectName,
PullRequestId: &pullRequestId,
RepositoryId: &repositoryName,
GitPullRequestToUpdate: &git.GitPullRequest{
AutoCompleteSetBy: &webapi.IdentityRef{
Id: &id,
},
CompletionOptions: &git.GitPullRequestCompletionOptions{
DeleteSourceBranch: &deleteSourceBranch,
MergeStrategy: &git.GitPullRequestMergeStrategyValues.Squash,
},
},
})

return err
}
115 changes: 115 additions & 0 deletions azuredevops/repository.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ package azuredevops

import (
"fmt"
"os"
"path/filepath"

egit "github.com/frontierdigital/utils/git/external_git"
"github.com/frontierdigital/utils/output"
"github.com/microsoft/azure-devops-go-api/azuredevops/git"
"golang.org/x/exp/slices"
)
Expand Down Expand Up @@ -36,3 +40,114 @@ func (a *AzureDevOps) GetRepository(projectName string, name string) (*git.GitRe

return &(*repositories)[repositoryIdx], nil
}

// configureRepository configures a repository
func configureRepository(repo *egit.ExternalGit, gitEmail string, gitUsername string) error {
err := repo.SetConfig("user.email", gitEmail)
if err != nil {
return err
}
err = repo.SetConfig("user.name", gitUsername)
if err != nil {
return err
}
return nil
}

// createRepositoryIfNotExists creates a repository if it does not exist
func createRepositoryIfNotExists(a *AzureDevOps, projectName string, repoName string, gitEmail string, gitUsername string, adoPat string) (*git.GitRepository, *string, error) {
client, err := git.NewClient(a.ctx, a.connection)
if err != nil {
return nil, nil, err
}

getRepositoryArgs := git.GetRepositoryArgs{
RepositoryId: &repoName,
Project: &projectName,
}

r, err := client.GetRepository(a.ctx, getRepositoryArgs)

if err == nil {
repoPath, err := os.MkdirTemp("", "")
if err != nil {
return nil, nil, err
}
repo := egit.NewGit(repoPath)
err = repo.CloneOverHttp(*r.RemoteUrl, adoPat, "x-oauth-basic")
if err != nil {
return nil, nil, err
}
err = configureRepository(repo, gitEmail, gitUsername)
if err != nil {
return nil, nil, err
}
return r, &repoPath, nil
}

createRepositoryArgs := git.CreateRepositoryArgs{
GitRepositoryToCreate: &git.GitRepositoryCreateOptions{
Name: &repoName,
},
Project: &projectName,
}

r, err = client.CreateRepository(a.ctx, createRepositoryArgs)

if err != nil {
return nil, nil, err
}

localPath, err := initRepository("frontierdigital", projectName, repoName, gitEmail, gitUsername, adoPat)

if err != nil {
return nil, nil, err
}

return r, localPath, nil
}

// initRepository creates a main branch
func initRepository(organisationName string, projectName string, repoName string, gitEmail string, gitUsername string, adoPat string) (*string, error) {
repoUrl := fmt.Sprintf("https://dev.azure.com/%s/%s/_git/%s", organisationName, projectName, repoName)

repoPath, err := os.MkdirTemp("", "")
if err != nil {
return nil, err
}
repo := egit.NewGit(repoPath)
err = repo.CloneOverHttp(repoUrl, adoPat, "x-oauth-basic")
if err != nil {
return nil, err
}
err = configureRepository(repo, gitEmail, gitUsername)
if err != nil {
return nil, err
}

file, err := os.Create(filepath.Join(repoPath, "README.md"))
if err != nil {
return nil, err
}
defer file.Close()

err = repo.AddAll()
if err != nil {
return nil, err
}

commitMessage := "Initial Commit"
_, err = repo.Commit(commitMessage)
if err != nil {
return nil, err
}

err = repo.Push(false)
if err != nil {
return nil, err
}

output.PrintlnfInfo("Pushed.")

return &repoPath, nil
}
59 changes: 59 additions & 0 deletions azuredevops/wiki.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package azuredevops

import (
"github.com/microsoft/azure-devops-go-api/azuredevops/git"
"github.com/microsoft/azure-devops-go-api/azuredevops/wiki"
)

func (a *AzureDevOps) CreateWikiIfNotExists(projectName string, wikiName string, gitEmail string, gitUsername string, adoPat string) (*string, error) {
client, err := wiki.NewClient(a.ctx, a.connection)
if err != nil {
return nil, err
}

getWikiArgs := wiki.GetWikiArgs{
Project: &projectName,
WikiIdentifier: &wikiName,
}

r, localPath, err := createRepositoryIfNotExists(a, projectName, wikiName, gitEmail, gitUsername, adoPat)
if err != nil {
return nil, err
}

_, err = client.GetWiki(a.ctx, getWikiArgs)

if err == nil {
return localPath, nil
}

projectId, err := a.getProjectUUID(projectName)
if err != nil {
return nil, err
}

branch := "main"
mappedPath := "/"
wikiCreateArgs := wiki.CreateWikiArgs{
Project: &projectName,
WikiCreateParams: &wiki.WikiCreateParametersV2{
MappedPath: &mappedPath,
Name: &wikiName,
ProjectId: projectId,
Type: &wiki.WikiTypeValues.CodeWiki,
RepositoryId: r.Id,
Version: &git.GitVersionDescriptor{
VersionType: &git.GitVersionTypeValues.Branch,
Version: &branch,
},
},
}
_, err = client.CreateWiki(a.ctx, wikiCreateArgs)

if err != nil {
return nil, err
}

return localPath, nil

}
18 changes: 18 additions & 0 deletions git/external_git/status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package external_git

// HasChanges checks for changes in the current branch
func (g *ExternalGit) HasChanges() (bool, error) {
var args []string
args = []string{"status", "-s"}

content, err := g.Exec(args...)
if err != nil {
return false, err
}

if content == "" {
return false, nil
}

return true, nil
}
1 change: 1 addition & 0 deletions git/external_git/status_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package external_git

0 comments on commit 3d6299b

Please sign in to comment.