diff --git a/main.go b/main.go index 6d50416..79a6ae7 100644 --- a/main.go +++ b/main.go @@ -4,6 +4,7 @@ import ( "os" "code.obermui.de/6543/GitLab_MergeDevel2Default/merge" + "code.obermui.de/6543/GitLab_MergeDevel2Default/tags" "code.obermui.de/6543/GitLab_MergeDevel2Default/utils" "github.com/urfave/cli/v2" @@ -22,6 +23,7 @@ func main() { app.Version = Version app.Commands = []*cli.Command{ &merge.CmdMerge, + &tags.CmdCreateTag, } app.EnableBashCompletion = true diff --git a/merge/merge.go b/merge/merge.go index 9df32c2..f3d8a49 100644 --- a/merge/merge.go +++ b/merge/merge.go @@ -1,10 +1,10 @@ package merge import ( - "code.obermui.de/6543/GitLab_MergeDevel2Default/context" "fmt" "time" + "code.obermui.de/6543/GitLab_MergeDevel2Default/context" "code.obermui.de/6543/GitLab_MergeDevel2Default/utils" "github.com/AlecAivazis/survey/v2" @@ -30,7 +30,7 @@ const ( var CmdMerge = cli.Command{ Name: "merge", - Usage: "run script for merge subcommand", + Usage: "Merge develop branch into default branch", Description: `run script for merge subcommand`, Action: runMerge, Flags: []cli.Flag{ @@ -164,7 +164,7 @@ func runMerge(ctx *cli.Context) error { for { fmt.Printf("%d", page) repos, _, err := client.Groups.ListGroupProjects(orgID, &gitlab.ListGroupProjectsOptions{ - ListOptions: gitlab.ListOptions{PerPage: 10, Page: page}, + ListOptions: gitlab.ListOptions{PerPage: perPage, Page: page}, Archived: utils.OptBool(false), IncludeSubgroups: utils.OptBool(false), }) @@ -173,7 +173,7 @@ func runMerge(ctx *cli.Context) error { } repoList = append(repoList, repos...) - if len(repos) < 10 { + if len(repos) < perPage { break } page++ @@ -218,7 +218,7 @@ func threatRepo(baseBranchRule glob.Glob, client *gitlab.Client, repo *gitlab.Pr } branchList = append(branchList, bL...) - if len(bL) < 10 { + if len(bL) < perPage { break } page++ diff --git a/tags/taging.go b/tags/taging.go new file mode 100644 index 0000000..7cbbffe --- /dev/null +++ b/tags/taging.go @@ -0,0 +1,188 @@ +package tags + +import ( + "fmt" + + "code.obermui.de/6543/GitLab_MergeDevel2Default/context" + "code.obermui.de/6543/GitLab_MergeDevel2Default/utils" + + "github.com/AlecAivazis/survey/v2" + "github.com/gobwas/glob" + "github.com/urfave/cli/v2" + "github.com/xanzy/go-gitlab" +) + +var ( + perPage = 10 +) + +var CmdCreateTag = cli.Command{ + Name: "create-tag", + Usage: "Create a tag on commit of latest default branch", + Description: `run script for merge subcommand`, + Action: createTag, + Flags: []cli.Flag{ + &cli.StringFlag{ + Name: "token", + Usage: "GitLab Access Token", + EnvVars: []string{"TOKEN"}, + Required: false, + }, + &cli.StringFlag{ + Name: "url", + Usage: "GitLab Base URL", + EnvVars: []string{"BASE_URL"}, + Required: false, + }, + &cli.IntFlag{ + Name: "group-id", + Usage: "Group ID where repositories are stored", + EnvVars: []string{"GROUP_ID"}, + Required: false, + }, + &cli.StringFlag{ + Name: "group-name", + Usage: "Group Name where repositories are stored, it's used if group-id is not set", + EnvVars: []string{"GROUP_NAME"}, + Required: false, + }, + &cli.StringFlag{ + Name: "repo-ignore-pattern", + Usage: "Repo Ignore Pattern", + EnvVars: []string{"REPO_IGNORE_PATTERN"}, + Required: false, + }, + + &cli.StringFlag{ + Name: "tag", + Usage: "name of tag to create", + EnvVars: []string{"TAG"}, + Required: false, + }, + }, +} + +func createTag(ctx *cli.Context) error { + values := context.LoadCache() + interactive := false + + if ctx.IsSet("token") { + values.Token = ctx.String("token") + } else { + interactive = true + if err := survey.AskOne(&survey.Input{Message: "GitLab Token:", Default: values.Token}, &values.Token); err != nil { + return err + } + } + + if ctx.IsSet("url") { + values.BaseURL = ctx.String("url") + } else { + interactive = true + if err := survey.AskOne(&survey.Input{Message: "GitLab Base URL:", Default: values.BaseURL}, &values.BaseURL); err != nil { + return err + } + } + + orgID := ctx.Int("group-id") + if orgID == 0 { + if ctx.IsSet("group-name") { + values.OrgName = ctx.String("group-name") + } else { + interactive = true + if err := survey.AskOne(&survey.Input{Message: "Group Name:", Default: values.OrgName}, &values.OrgName); err != nil { + return err + } + } + } + + if ctx.IsSet("repo-ignore-pattern") { + values.RepoExclude = ctx.String("repo-ignore-pattern") + } else { + interactive = true + if err := survey.AskOne(&survey.Input{Message: "Ignore Repo with patter:", Default: values.RepoExclude}, &values.RepoExclude); err != nil { + return err + } + } + + tag := ctx.String("tag") + if len(tag) == 0 { + interactive = true + if err := survey.AskOne(&survey.Input{Message: "Tag Name:", Default: tag}, &tag); err != nil { + return err + } + } + + if interactive { + context.SaveCache(values) + } + + // Compile glob regex + excludeRule, err := glob.Compile(values.RepoExclude) + if err != nil { + return fmt.Errorf("not able to compile regex '%s'", values.RepoExclude) + } + + // connect to gitlab + client, err := gitlab.NewClient(values.Token, gitlab.WithBaseURL(values.BaseURL)) + if err != nil { + return fmt.Errorf("Could not create Client: %v\n", err) + } + + if orgID == 0 { + // discover GroupID by name + org, _, err := client.Groups.GetGroup(values.OrgName) + if err != nil { + return fmt.Errorf("Error cant get information for Organisation \"%s\": %v", values.OrgName, err) + } + fmt.Printf("Found \"%s\"\n", org.WebURL) + + orgID = org.ID + } + + var repoList []*gitlab.Project + var page = 1 + fmt.Printf("Retrieving repository list... ") + for { + fmt.Printf("%d ", page) + repos, _, err := client.Groups.ListGroupProjects(orgID, &gitlab.ListGroupProjectsOptions{ + ListOptions: gitlab.ListOptions{PerPage: perPage, Page: page}, + Archived: utils.OptBool(false), + IncludeSubgroups: utils.OptBool(false), + }) + if err != nil { + return fmt.Errorf("Could not obtain repo list: %v\n", err) + } + + repoList = append(repoList, repos...) + if len(repos) < perPage { + break + } + page++ + } + fmt.Printf("... DONE\nFound %d Repos\n", len(repoList)) + + for i := range repoList { + if !excludeRule.Match(repoList[i].Name) { + // for each NOT excluded repo ... + if err := threatRepo(client, tag, repoList[i]); err != nil { + return err + } + } + } + + return nil +} + +func threatRepo(client *gitlab.Client, tagName string, repo *gitlab.Project) error { + tag, _, err := client.Tags.CreateTag(repo.ID, &gitlab.CreateTagOptions{ + TagName: &tagName, + Ref: &repo.DefaultBranch, + }) + if err != nil { + return err + } + + fmt.Printf(" - Created tag '%s' in '%s'\n", tag.Name, repo.WebURL) + return nil +}