Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/feat/pr-adevops'
Browse files Browse the repository at this point in the history
Signed-off-by: Felipe Rios <felipe.rios.silva@outlook.com>
  • Loading branch information
rios0rios0 committed Oct 3, 2023
2 parents f53cd0e + f6cd9df commit 6afc964
Show file tree
Hide file tree
Showing 5 changed files with 88 additions and 47 deletions.
1 change: 1 addition & 0 deletions cmd/autobump/azuredevops.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ func createAzureDevOpsPullRequest(
return err
}

// TODO: refactor to use this library: https://github.com/microsoft/azure-devops-go-api
url := fmt.Sprintf("https://dev.azure.com/%s/%s/_apis/git/repositories/%s/pullrequests?api-version=6.0",
azureInfo.OrganizationName, azureInfo.ProjectName, azureInfo.RepositoryID)
prTitle := fmt.Sprintf("chore(bump): bumped version to %s", newVersion)
Expand Down
102 changes: 79 additions & 23 deletions cmd/autobump/git.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package main

import (
"errors"
"fmt"
"github.com/go-git/go-git/v5/plumbing/protocol/packp/capability"
"github.com/go-git/go-git/v5/plumbing/transport"
"os"
"path/filepath"
"strings"
Expand Down Expand Up @@ -129,20 +132,64 @@ func pushChangesHttps(
RemoteName: "origin",
}

// use the project access token if available
if projectConfig.ProjectAccessToken != "" {
pushOptions.Auth = &http.BasicAuth{
Username: repoCfg.User.Name,
Password: projectConfig.ProjectAccessToken,
service, err := getRemoteServiceType(repo)
if err != nil {
return err
}
auth, err := getAuthenticationMethod(service, repoCfg.User.Name, globalConfig, projectConfig)
if err != nil {
return err
}

pushOptions.Auth = auth
return repo.Push(pushOptions)
}

// getAuthenticationMethod returns the authentication method to use for cloning/pushing changes
func getAuthenticationMethod(service string, username string, globalConfig *GlobalConfig, projectConfig *ProjectConfig,
) (transport.AuthMethod, error) {
var auth transport.AuthMethod

switch service {
case "GitLab":
// TODO: this lines of code MUST be refactored to avoid code duplication
// authenticate with CI job token if running in a GitLab CI pipeline
if projectConfig.ProjectAccessToken != "" {
log.Infof("Using project access token to authenticate")
auth = &http.BasicAuth{
Username: "oauth2",
Password: projectConfig.ProjectAccessToken,
}
} else if globalConfig.GitLabCIJobToken != "" {
log.Infof("Using GitLab CI job token to authenticate")
auth = &http.BasicAuth{
Username: "gitlab-ci-token",
Password: globalConfig.GitLabCIJobToken,
}
} else if globalConfig.GitLabAccessToken != "" {
log.Infof("Using GitLab access token to authenticate")
auth = &http.BasicAuth{
Username: username,
Password: globalConfig.GitLabAccessToken,
}
}
break
case "AzureDevOps":
log.Infof("Using Azure DevOps access token to authenticate")
transport.UnsupportedCapabilities = []capability.Capability{
capability.ThinPack,
}
} else {
pushOptions.Auth = &http.BasicAuth{
Username: repoCfg.User.Name,
Password: globalConfig.GitLabAccessToken,
auth = &http.BasicAuth{
Username: username,
Password: globalConfig.AzureDevOpsAccessToken,
}
break
default:
log.Errorf("No authentication mechanism implemented for service type '%s'", service)
return nil, errors.New("no authentication mechanism implemented")
}

return repo.Push(pushOptions)
return auth, nil
}

// getRemoteServiceType returns the type of the remote service (e.g. GitHub, GitLab)
Expand All @@ -152,22 +199,31 @@ func getRemoteServiceType(repo *git.Repository) (string, error) {
return "", err
}

// TODO: this could be better using Adapter pattern
var firstRemote string
for _, remote := range cfg.Remotes {
if strings.Contains(remote.URLs[0], "gitlab.com") {
return "GitLab", nil
} else if strings.Contains(remote.URLs[0], "github.com") {
return "GitHub", nil
} else if strings.Contains(remote.URLs[0], "bitbucket.org") {
return "Bitbucket", nil
} else if strings.Contains(remote.URLs[0], "git-codecommit") {
return "CodeCommit", nil
} else if strings.Contains(remote.URLs[0], "dev.azure.com") {
return "AzureDevOps", nil
}
firstRemote = remote.URLs[0]
break
}

return getServiceTypeByURL(firstRemote), nil
}

// getServiceTypeByURL returns the type of the remote service (e.g. GitHub, GitLab) by URL
func getServiceTypeByURL(remoteURL string) string {
// TODO: this could be better using the Adapter pattern
if strings.Contains(remoteURL, "gitlab.com") {
return "GitLab"
} else if strings.Contains(remoteURL, "github.com") {
return "GitHub"
} else if strings.Contains(remoteURL, "bitbucket.org") {
return "Bitbucket"
} else if strings.Contains(remoteURL, "git-codecommit") {
return "CodeCommit"
} else if strings.Contains(remoteURL, "dev.azure.com") {
return "AzureDevOps"
}

return "Unknown", nil
return "Unknown"
}

// getRemoteRepoURL returns the URL of the remote repository
Expand Down
1 change: 1 addition & 0 deletions cmd/autobump/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ func findReadAndValidateConfig(configPath string) *GlobalConfig {

var defaultConfig *GlobalConfig
defaultConfig, err = decodeConfig(data)
// TODO: this merge could be done, for each language
globalConfig.LanguagesConfig = defaultConfig.LanguagesConfig
} else {
log.Fatalf("Config validation failed: %v", err)
Expand Down
25 changes: 5 additions & 20 deletions cmd/autobump/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"github.com/ProtonMail/go-crypto/openpgp"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config"
"github.com/go-git/go-git/v5/plumbing/transport/http"
log "github.com/sirupsen/logrus"
)

Expand Down Expand Up @@ -106,27 +105,13 @@ func processRepo(globalConfig *GlobalConfig, projectConfig *ProjectConfig) error
Depth: 1,
}

// authenticate with CI job token if running in a GitLab CI pipeline
if projectConfig.ProjectAccessToken != "" {
log.Infof("Using project access token to authenticate")
cloneOptions.Auth = &http.BasicAuth{
Username: "oauth2",
Password: projectConfig.ProjectAccessToken,
}
} else if globalConfig.GitLabCIJobToken != "" {
log.Infof("Using GitLab CI job token to authenticate")
cloneOptions.Auth = &http.BasicAuth{
Username: "gitlab-ci-token",
Password: globalConfig.GitLabCIJobToken,
}
} else {
log.Infof("Using GitLab access token to authenticate")
cloneOptions.Auth = &http.BasicAuth{
Username: globalGitConfig.Raw.Section("user").Option("name"),
Password: globalConfig.GitLabAccessToken,
}
service := getServiceTypeByURL(projectConfig.Path)
auth, err := getAuthenticationMethod(service, globalGitConfig.Raw.Section("user").Option("name"), globalConfig, projectConfig)
if err != nil {
return err
}

cloneOptions.Auth = auth
_, err = git.PlainClone(tmpDir, false, cloneOptions)
if err != nil {
return err
Expand Down
6 changes: 2 additions & 4 deletions configs/autobump.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,8 @@ languages:
special_patterns:
- "*\\.sln"
version_files:
- path: "Setup64bit/Setup64bit.vdproj"
patterns: [ "(\\s*\"ProductVersion\"\\s*=\\s*\"\\d*)\\d+\\.\\d+\\.\\d+(\")" ]
- path: "Setup32bit/Setup32bit.vdproj"
patterns: [ "(\\s*\"ProductVersion\"\\s*=\\s*\"\\d*)\\d+\\.\\d+\\.\\d+(\")" ]
- path: "*/*.vdproj"
patterns: [ "(.*\"ProductVersion\"\\s*=\\s*\"\\d*:?) \\d+\\.\\d+\\.\\d+ (\")" ]
- path: "*/*.csproj"
patterns:
- "(\\s*<Version>)\\d+\\.\\d+\\.\\d+(</Version>)"
Expand Down

0 comments on commit 6afc964

Please sign in to comment.