diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 087c389..907b0d0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,5 +1,5 @@ repos: - repo: https://github.com/golangci/golangci-lint.git - rev: v1.45.2 + rev: v1.51.2 hooks: - id: golangci-lint diff --git a/README.md b/README.md index ac73172..72dd2b1 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,8 @@ Contents: name: email: toBranch: # default main + additionalBranches: # push more than one branch to new repos + signKey: # Optional key for signing the commit. If the key is encrypted the password will be requested on running the tool. protectToBranch: <false|true> # whether only maintainer can push, default false clone: @@ -127,6 +129,10 @@ algdati: url: git@gitlab.lrz.de:algdati/startercode/startercodeBlatt1.git fromBranch: ws20 protectToBranch: true + additionalBranches: + - ss20 + - 22ss + - main # accesslevel: developer # default clone: localpath: /tmp diff --git a/config/repo.go b/config/repo.go index 9af9d72..cd66589 100644 --- a/config/repo.go +++ b/config/repo.go @@ -34,12 +34,18 @@ func startercode(assignmentKey string) *Startercode { devBranch = dB } + additionalBranches := []string{} + if addB := viper.GetStringSlice(assignmentKey + ".startercode.additionalBranches"); len(addB) > 0 { + additionalBranches = addB + } + return &Startercode{ - URL: url, - FromBranch: fromBranch, - ToBranch: toBranch, - DevBranch: devBranch, - ProtectToBranch: viper.GetBool(assignmentKey + ".startercode.protectToBranch"), + URL: url, + FromBranch: fromBranch, + ToBranch: toBranch, + DevBranch: devBranch, + AdditionalBranches: additionalBranches, + ProtectToBranch: viper.GetBool(assignmentKey + ".startercode.protectToBranch"), } } diff --git a/config/show.go b/config/show.go index 47a7f73..e3b36fb 100644 --- a/config/show.go +++ b/config/show.go @@ -16,15 +16,17 @@ func (cfg *AssignmentConfig) Show() { startercode := aurora.Sprintf(aurora.Red("not defined")) if cfg.Startercode != nil { startercode = aurora.Sprintf(aurora.Cyan(` - URL: %s - FromBranch: %s - ToBranch: %s - DevBranch: %s - ProtectToBranch: %t`), + URL: %s + FromBranch: %s + ToBranch: %s + DevBranch: %s + AdditionalBranches: %s + ProtectToBranch: %t`), aurora.Yellow(cfg.Startercode.URL), aurora.Yellow(cfg.Startercode.FromBranch), aurora.Yellow(cfg.Startercode.ToBranch), aurora.Yellow(cfg.Startercode.DevBranch), + aurora.Yellow(cfg.Startercode.AdditionalBranches), aurora.Yellow(cfg.Startercode.ProtectToBranch), ) } diff --git a/config/types.go b/config/types.go index a09edaf..434789b 100644 --- a/config/types.go +++ b/config/types.go @@ -45,11 +45,12 @@ type Seeder struct { } type Startercode struct { - URL string - FromBranch string - ToBranch string - DevBranch string - ProtectToBranch bool + URL string + FromBranch string + ToBranch string + DevBranch string + AdditionalBranches []string + ProtectToBranch bool } type Clone struct { diff --git a/gitlab/projects.go b/gitlab/projects.go index 02c0d89..579e606 100644 --- a/gitlab/projects.go +++ b/gitlab/projects.go @@ -12,15 +12,16 @@ import ( func (c *Client) generateProject(assignmentCfg *config.AssignmentConfig, name string, inID int) (*gitlab.Project, bool, error) { generated := false p := &gitlab.CreateProjectOptions{ - Name: gitlab.String(name), - Description: gitlab.String(assignmentCfg.Description), - NamespaceID: gitlab.Int(inID), - MergeRequestsAccessLevel: gitlab.AccessControl("enabled"), - IssuesAccessLevel: gitlab.AccessControl("enabled"), - BuildsAccessLevel: gitlab.AccessControl("enabled"), - JobsEnabled: gitlab.Bool(true), - Visibility: gitlab.Visibility(gitlab.PrivateVisibility), - ContainerRegistryEnabled: gitlab.Bool(assignmentCfg.ContainerRegistry), + Name: gitlab.String(name), + Description: gitlab.String(assignmentCfg.Description), + NamespaceID: gitlab.Int(inID), + MergeRequestsAccessLevel: gitlab.AccessControl("enabled"), + IssuesAccessLevel: gitlab.AccessControl("enabled"), + BuildsAccessLevel: gitlab.AccessControl("enabled"), + JobsEnabled: gitlab.Bool(true), + Visibility: gitlab.Visibility(gitlab.PrivateVisibility), + ContainerRegistryEnabled: gitlab.Bool(assignmentCfg.ContainerRegistry), + OnlyAllowMergeIfAllStatusChecksPassed: gitlab.Bool(false), } project, _, err := c.Projects.CreateProject(p) diff --git a/gitlab/protect.go b/gitlab/protect.go index 341a1a2..56d9662 100644 --- a/gitlab/protect.go +++ b/gitlab/protect.go @@ -7,13 +7,12 @@ import ( "github.com/logrusorgru/aurora" "github.com/obcode/glabs/config" - cfg "github.com/obcode/glabs/config" "github.com/rs/zerolog/log" "github.com/theckman/yacspin" "github.com/xanzy/go-gitlab" ) -func (c *Client) ProtectToBranch(assignmentCfg *cfg.AssignmentConfig) { +func (c *Client) ProtectToBranch(assignmentCfg *config.AssignmentConfig) { assignmentGitLabGroupID, err := c.getGroupID(assignmentCfg) if err != nil { fmt.Printf("error: GitLab group for assignment does not exist, please create the group %s\n", assignmentCfg.URL) @@ -31,7 +30,7 @@ func (c *Client) ProtectToBranch(assignmentCfg *cfg.AssignmentConfig) { } } -func (c *Client) protectBranch(assignmentCfg *cfg.AssignmentConfig, project *gitlab.Project, spin bool) error { +func (c *Client) protectBranch(assignmentCfg *config.AssignmentConfig, project *gitlab.Project, spin bool) error { if assignmentCfg.Startercode.ProtectToBranch { // var cfg yacspin.Config var spinner *yacspin.Spinner diff --git a/gitlab/starterrepo.go b/gitlab/starterrepo.go index 19b0e5f..473ed97 100644 --- a/gitlab/starterrepo.go +++ b/gitlab/starterrepo.go @@ -25,8 +25,11 @@ func (c *Client) pushStartercode(assignmentCfg *cfg.AssignmentConfig, from *g.St return fmt.Errorf("cannot create remote: %w", err) } - refSpec := config.RefSpec("refs/heads/" + assignmentCfg.Startercode.FromBranch + - ":refs/heads/" + assignmentCfg.Startercode.ToBranch) + refSpec := config.RefSpec( + fmt.Sprintf("+refs/heads/%s:refs/heads/%s", + assignmentCfg.Startercode.FromBranch, + assignmentCfg.Startercode.ToBranch), + ) log.Debug(). Str("refSpec", string(refSpec)). @@ -66,6 +69,41 @@ func (c *Client) pushStartercode(assignmentCfg *cfg.AssignmentConfig, from *g.St } } + for _, additionalBranch := range assignmentCfg.Startercode.AdditionalBranches { + log.Debug().Str("branch", additionalBranch).Msg("pushing additional branch") + + // worktree, err := from.Repo.Worktree() + // if err != nil { + // log.Debug().Err(err). + // Str("branch", additionalBranch). + // Str("name", project.Name).Str("url", project.SSHURLToRepo). + // Msg("cannot get worktree") + // return fmt.Errorf("cannot get worktree: %w", err) + // } + + // worktree.Checkout(&git.CheckoutOptions{ + // Branch: plumbing.ReferenceName(additionalBranch), + // }) + + refSpec := config.RefSpec(fmt.Sprintf("+refs/remotes/origin/%s:refs/heads/%s", additionalBranch, additionalBranch)) + + pushOpts := &git.PushOptions{ + RemoteName: remote.Config().Name, + RefSpecs: []config.RefSpec{refSpec}, + Auth: from.Auth, + } + err = from.Repo.Push(pushOpts) + if err != nil { + log.Debug().Err(err). + Str("branch", additionalBranch). + Str("refspec", refSpec.String()). + Str("name", project.Name).Str("url", project.SSHURLToRepo). + Msg("cannot push to remote") + return fmt.Errorf("cannot push to remote: %w", err) + } + + } + return nil }