DRAFT1
This commit is contained in:
parent
c2b959219e
commit
794a1980f7
1
go.mod
1
go.mod
@ -4,5 +4,6 @@ go 1.16
|
||||
|
||||
require (
|
||||
github.com/AlecAivazis/survey/v2 v2.2.12
|
||||
github.com/gobwas/glob v0.2.3
|
||||
github.com/xanzy/go-gitlab v0.48.0
|
||||
)
|
||||
|
2
go.sum
2
go.sum
@ -5,6 +5,8 @@ github.com/Netflix/go-expect v0.0.0-20180615182759-c93bf25de8e8/go.mod h1:oX5x61
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
|
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/google/go-querystring v1.0.0 h1:Xkwi/a1rcvNg1PPYe5vI8GbeBY/jrVuDX5ASuANWTrk=
|
||||
|
174
main.go
Normal file
174
main.go
Normal file
@ -0,0 +1,174 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/gobwas/glob"
|
||||
"github.com/xanzy/go-gitlab"
|
||||
)
|
||||
|
||||
var (
|
||||
Version = "dev"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// default values
|
||||
var token string = "XXXXXXXXXXXXXXXXXX"
|
||||
var baseURL string = "https://gitlab.com"
|
||||
var orgName string = "scr-test"
|
||||
var repoExclude string = "exclude*"
|
||||
var pullBaseBranch string = "devel*"
|
||||
|
||||
// ask for infos
|
||||
if err := survey.AskOne(&survey.Input{Message: "GitLab Base URL:", Default: baseURL}, &baseURL); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := survey.AskOne(&survey.Input{Message: "GitLab Token:", Default: token}, &token); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := survey.AskOne(&survey.Input{Message: "Group Name:", Default: orgName}, &orgName); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := survey.AskOne(&survey.Input{Message: "Ignore Repo with patter:", Default: repoExclude}, &repoExclude); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
if err := survey.AskOne(&survey.Input{Message: "Merge Branches with patter:", Default: pullBaseBranch}, &pullBaseBranch); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// Compile glob regex
|
||||
excludeRule, err := glob.Compile(repoExclude)
|
||||
if err != nil {
|
||||
error(2, "not able to compile regex '%s'", repoExclude)
|
||||
}
|
||||
baseBranchRule, err := glob.Compile(pullBaseBranch)
|
||||
if err != nil {
|
||||
error(3, "not able to compile regex '%s'", pullBaseBranch)
|
||||
}
|
||||
|
||||
// connect to gitlab
|
||||
client, err := gitlab.NewClient(token, gitlab.WithBaseURL(baseURL))
|
||||
if err != nil {
|
||||
error(4, "Could not create Client: %v\n", err)
|
||||
}
|
||||
|
||||
// discover GroupID by name
|
||||
org, _, err := client.Groups.GetGroup(orgName)
|
||||
if err != nil {
|
||||
error(5, "Error cant get information for Organisation \"%s\": %v", orgName, err)
|
||||
}
|
||||
fmt.Printf("Found \"%s\"\n", org.WebURL)
|
||||
|
||||
repoList, _, err := client.Groups.ListGroupProjects(org.ID, &gitlab.ListGroupProjectsOptions{
|
||||
ListOptions: gitlab.ListOptions{},
|
||||
Archived: optBool(false),
|
||||
IncludeSubgroups: optBool(false),
|
||||
})
|
||||
if err != nil {
|
||||
error(5, "Could not obtain repo list: %v\n", err)
|
||||
}
|
||||
|
||||
for i := range repoList {
|
||||
if !excludeRule.Match(repoList[i].Name) {
|
||||
// for each NOT excluded repo ...
|
||||
threatRepo(baseBranchRule, client, repoList[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// threatRepo create (if needed) & merge "develop[ment]" branch in DefaultBranch
|
||||
func threatRepo(baseBranchRule glob.Glob, client *gitlab.Client, repo *gitlab.Project) {
|
||||
fmt.Printf("Handle Repository '%s'\n", repo.Name)
|
||||
|
||||
// TODO: handle pagination
|
||||
branchList, _, err := client.Branches.ListBranches(repo.ID, nil)
|
||||
if err != nil {
|
||||
error(10, "Could not obtain branch list from '%s': %v\n", repo.Name, err)
|
||||
}
|
||||
|
||||
for _, baseBranch := range branchList {
|
||||
if baseBranchRule.Match(baseBranch.Name) && !baseBranch.Default {
|
||||
fmt.Printf(" found branch '%s'\n", baseBranch.Name)
|
||||
|
||||
// check if source is ahead target branch
|
||||
diff, _, err := client.Repositories.Compare(repo.ID, &gitlab.CompareOptions{
|
||||
From: &repo.DefaultBranch,
|
||||
To: &baseBranch.Name,
|
||||
})
|
||||
if err != nil {
|
||||
error(10, "Could not compare '%s'...'%s' at '%s': %v\n", repo.DefaultBranch, baseBranch.Name, repo.Name, err)
|
||||
}
|
||||
|
||||
if len(diff.Commits) == 0 {
|
||||
fmt.Printf(" branch '%s' is not ahead of '%s', skiping\n", baseBranch.Name, repo.DefaultBranch)
|
||||
return
|
||||
}
|
||||
|
||||
// check if pull already exist
|
||||
pullList, _, err := client.MergeRequests.ListProjectMergeRequests(repo.ID, &gitlab.ListProjectMergeRequestsOptions{
|
||||
SourceBranch: &baseBranch.Name,
|
||||
TargetBranch: &repo.DefaultBranch,
|
||||
State: optString("opened"),
|
||||
})
|
||||
if err != nil {
|
||||
error(11, "Could not obtain merge request list from '%s': %v\n", repo.Name, err)
|
||||
}
|
||||
|
||||
// if not create one
|
||||
if len(pullList) == 0 {
|
||||
fmt.Printf(" no existing pull for %s, creating one ...\n", baseBranch.Name)
|
||||
pull, _, err := client.MergeRequests.CreateMergeRequest(repo.ID, &gitlab.CreateMergeRequestOptions{
|
||||
Title: optString(fmt.Sprintf("%s <- %s", repo.DefaultBranch, baseBranch.Name)), // TODO: better title (required)
|
||||
Description: optString("Auto created by https://code.obermui.de/6543/GitLab_MergeDevel2Default"),
|
||||
SourceBranch: &baseBranch.Name,
|
||||
TargetBranch: &repo.DefaultBranch,
|
||||
AllowCollaboration: optBool(true),
|
||||
})
|
||||
if err != nil {
|
||||
fmt.Printf(" could not create merge request '%s <- %s', skiping '%s'\n", repo.DefaultBranch, baseBranch.Name, repo.Name)
|
||||
return
|
||||
}
|
||||
pullList = []*gitlab.MergeRequest{pull}
|
||||
} else {
|
||||
// check if changes exist for pull
|
||||
changes, _, err := client.MergeRequests.GetMergeRequestChanges(repo.ID, pullList[0].IID, nil)
|
||||
if err != nil {
|
||||
fmt.Printf(" could not obtain changes of merge request '%s', skiping '%s'\n", pullList[0].WebURL, repo.Name)
|
||||
return
|
||||
}
|
||||
|
||||
if len(changes.Changes) == 0 {
|
||||
fmt.Printf(" pull '%s' does not conatin changes, skiping\n", changes.WebURL)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check and wait for pull to get ready
|
||||
|
||||
// merge pull
|
||||
if pull, _, err := client.MergeRequests.AcceptMergeRequest(repo.ID, pullList[0].IID, nil); err != nil {
|
||||
fmt.Printf(" pull '%s' can not be merged: %v\n", pullList[0].WebURL, err)
|
||||
} else {
|
||||
fmt.Printf(" pull '%s' got merged successfully\n", pull.WebURL)
|
||||
}
|
||||
|
||||
// since we had a match go to next repo ...
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func optBool(val bool) *bool {
|
||||
return &val
|
||||
}
|
||||
|
||||
func optString(val string) *string {
|
||||
return &val
|
||||
}
|
||||
|
||||
func error(id int, format string, a ...interface{}) {
|
||||
fmt.Printf(format, a...)
|
||||
os.Exit(id)
|
||||
}
|
Loading…
Reference in New Issue
Block a user