Skip to content
This repository was archived by the owner on Sep 6, 2025. It is now read-only.

Commit 0098d77

Browse files
committed
Making create smarter
1 parent d8956dc commit 0098d77

File tree

3 files changed

+83
-38
lines changed

3 files changed

+83
-38
lines changed

cmd/create_repo.go

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -82,18 +82,26 @@ func RunCreateRepo(cmd *cobra.Command, args []string) {
8282

8383
color.White("Creating repository...")
8484
err = creator.CreateRepo(name, description, org, createRepoFlags.Private)
85-
checkEmpty(errors.Wrap(err, "could not create repository"), "")
85+
if errors.Cause(err) == repo.ErrRepositoryAlreadyExists {
86+
color.Cyan("Repository already exists. Trying to normalize it...")
87+
} else {
88+
checkEmpty(errors.Wrap(err, "could not create repository"), "")
89+
}
8690

8791
if createRepoFlags.HasPullApprove {
8892
color.White("Adding pull approve...")
8993
err = creator.AddPullApprove(name, org, opts.PullApprove)
90-
checkEmpty(errors.Wrap(err, "could not add pull approve"), "")
94+
if errors.Cause(err) == repo.ErrPullApproveFileAlreadyExists {
95+
color.Cyan("Pull approve already exists, moving on...")
96+
} else {
97+
checkEmpty(errors.Wrap(err, "could not add pull approve"), "")
98+
}
9199
}
92100

93101
if createRepoFlags.HasTeams {
94102
color.White("Adding teams to repository...")
95103
err = creator.AddTeamsToRepo(name, org, opts.Teams)
96-
checkEmpty(errors.Wrap(err, "could add teams to repository"), "")
104+
checkEmpty(errors.Wrap(err, "could not add teams to repository"), "")
97105
}
98106

99107
if createRepoFlags.HasCollaborators {
@@ -105,13 +113,21 @@ func RunCreateRepo(cmd *cobra.Command, args []string) {
105113
if createRepoFlags.HasLabels {
106114
color.White("Adding labels to repository...")
107115
err = creator.AddLabelsToRepo(name, org, opts.Labels)
108-
checkEmpty(errors.Wrap(err, "could add labels to repository"), "")
116+
if errors.Cause(err) == repo.ErrLabelNotFound {
117+
color.Cyan("Default labels does not exists, moving on...")
118+
} else {
119+
checkEmpty(errors.Wrap(err, "could not add labels to repository"), "")
120+
}
109121
}
110122

111123
if createRepoFlags.HasWebhooks {
112124
color.White("Adding webhooks to repository...")
113125
err = creator.AddWebhooksToRepo(name, org, opts.Webhooks)
114-
checkEmpty(errors.Wrap(err, "could add webhooks to repository"), "")
126+
if errors.Cause(err) == repo.ErrWebhookAlreadyExist {
127+
color.Cyan("Webhook already exists, moving on...")
128+
} else {
129+
checkEmpty(errors.Wrap(err, "could add webhooks to repository"), "")
130+
}
115131
}
116132

117133
if createRepoFlags.HasBranchProtections {

pkg/config/config.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,14 @@ type (
2929
Collaborators []*Collaborator
3030
Labels []*Label
3131
Webhooks []*Webhook
32-
Protections map[string][]string
32+
Protections BranchProtections
3333
// RemoveDefaultLabels Remove GitHub's default labels?
3434
RemoveDefaultLabels bool
3535
}
3636

37+
// BranchProtections represents github's branch protections
38+
BranchProtections map[string][]string
39+
3740
// Team represents a github team
3841
Team struct {
3942
ID int

pkg/repo/github.go

Lines changed: 58 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package repo
22

33
import (
44
"context"
5+
"net/http"
56

67
"github.com/google/go-github/github"
78
"github.com/hellofresh/github-cli/pkg/config"
@@ -18,42 +19,38 @@ type (
1819
// GithubRepoOpts represents the repo creation options
1920
GithubRepoOpts struct {
2021
PullApprove *PullApproveOpts
21-
Teams *TeamsOpts
22-
Collaborators *CollaboratorsOpts
22+
Teams []*config.Team
23+
Collaborators []*config.Collaborator
2324
Labels *LabelsOpts
24-
Webhooks *WebhooksOpts
25-
BranchProtections *BranchProtectionsOpts
25+
Webhooks []*config.Webhook
26+
BranchProtections config.BranchProtections
2627
}
2728

29+
// PullApproveOpts represents pull approve options
2830
PullApproveOpts struct {
2931
Client *pullapprove.Client
3032
Filename string
3133
ProtectedBranchName string
3234
}
3335

34-
TeamsOpts struct {
35-
Teams []*config.Team
36-
}
37-
38-
CollaboratorsOpts struct {
39-
Collaborators []*config.Collaborator
40-
}
41-
36+
// LabelsOpts represents label options
4237
LabelsOpts struct {
4338
RemoveDefaultLabels bool
4439
Labels []*config.Label
4540
}
46-
47-
WebhooksOpts struct {
48-
Webhooks []*config.Webhook
49-
}
50-
51-
BranchProtectionsOpts struct {
52-
Protections map[string][]string
53-
}
5441
)
5542

56-
var ctx = context.Background()
43+
var (
44+
ctx = context.Background()
45+
// ErrRepositoryAlreadyExists is used when the repository already exists
46+
ErrRepositoryAlreadyExists = errors.New("github repository already exists")
47+
// ErrPullApproveFileAlreadyExists is used when the pull approve file already exists
48+
ErrPullApproveFileAlreadyExists = errors.New("github pull approve file already exists")
49+
// ErrLabelNotFound is used when a label is not found
50+
ErrLabelNotFound = errors.New("github label does not exist")
51+
// ErrWebhookAlreadyExist is used when a webhook already exists
52+
ErrWebhookAlreadyExist = errors.New("github webhook already exists")
53+
)
5754

5855
// NewGithub creates a new instance of Client
5956
func NewGithub(githubClient *github.Client) *GithubRepo {
@@ -62,6 +59,7 @@ func NewGithub(githubClient *github.Client) *GithubRepo {
6259
}
6360
}
6461

62+
// CreateRepo creates a github repository
6563
func (c *GithubRepo) CreateRepo(name string, description string, org string, private bool) error {
6664
repo := &github.Repository{
6765
Name: github.String(name),
@@ -71,10 +69,18 @@ func (c *GithubRepo) CreateRepo(name string, description string, org string, pri
7169
}
7270

7371
_, _, err := c.GithubClient.Repositories.Create(ctx, org, repo)
72+
if githubError, ok := err.(*github.ErrorResponse); ok {
73+
if githubError.Response.StatusCode == http.StatusUnprocessableEntity {
74+
err = errors.Wrap(ErrRepositoryAlreadyExists, "repository already exists")
75+
}
76+
}
77+
7478
return err
7579
}
7680

81+
// AddPullApprove adds a file to the github repository and calls pull approve API to register the new repo
7782
func (c *GithubRepo) AddPullApprove(repo string, org string, opts *PullApproveOpts) error {
83+
var err error
7884
if opts.Client == nil {
7985
return errors.New("Cannot add pull approve, since the client is nil")
8086
}
@@ -84,8 +90,12 @@ func (c *GithubRepo) AddPullApprove(repo string, org string, opts *PullApproveOp
8490
Content: []byte("extends: hellofresh"),
8591
Branch: github.String(opts.ProtectedBranchName),
8692
}
87-
_, _, err := c.GithubClient.Repositories.CreateFile(ctx, org, repo, opts.Filename, fileOpt)
88-
if err != nil {
93+
_, _, err = c.GithubClient.Repositories.CreateFile(ctx, org, repo, opts.Filename, fileOpt)
94+
if githubError, ok := err.(*github.ErrorResponse); ok {
95+
if githubError.Response.StatusCode == http.StatusUnprocessableEntity {
96+
return errors.Wrap(ErrPullApproveFileAlreadyExists, "pull approve file already exists")
97+
}
98+
} else {
8999
return err
90100
}
91101

@@ -94,13 +104,14 @@ func (c *GithubRepo) AddPullApprove(repo string, org string, opts *PullApproveOp
94104
return err
95105
}
96106

97-
return nil
107+
return err
98108
}
99109

100-
func (c *GithubRepo) AddTeamsToRepo(repo string, org string, opts *TeamsOpts) error {
110+
// AddTeamsToRepo adds an slice of teams and their permissions to a repository
111+
func (c *GithubRepo) AddTeamsToRepo(repo string, org string, teams []*config.Team) error {
101112
var err error
102113

103-
for _, team := range opts.Teams {
114+
for _, team := range teams {
104115
opt := &github.OrganizationAddTeamRepoOptions{
105116
Permission: team.Permission,
106117
}
@@ -111,6 +122,8 @@ func (c *GithubRepo) AddTeamsToRepo(repo string, org string, opts *TeamsOpts) er
111122
return err
112123
}
113124

125+
// AddLabelsToRepo adds an slice of labels to the repository. Optionally this can also remove github's
126+
// default labels
114127
func (c *GithubRepo) AddLabelsToRepo(repo string, org string, opts *LabelsOpts) error {
115128
var err error
116129
defaultLabels := []string{"bug", "duplicate", "enhancement", "help wanted", "invalid", "question", "wontfix", "good first issue"}
@@ -127,30 +140,42 @@ func (c *GithubRepo) AddLabelsToRepo(repo string, org string, opts *LabelsOpts)
127140
if opts.RemoveDefaultLabels {
128141
for _, label := range defaultLabels {
129142
_, err = c.GithubClient.Issues.DeleteLabel(ctx, org, repo, label)
143+
if githubError, ok := err.(*github.ErrorResponse); ok {
144+
if githubError.Response.StatusCode == http.StatusNotFound {
145+
err = errors.Wrap(ErrLabelNotFound, "label not found")
146+
}
147+
}
130148
}
131149
}
132150

133151
return err
134152
}
135153

136-
func (c *GithubRepo) AddWebhooksToRepo(repo string, org string, opts *WebhooksOpts) error {
154+
// AddWebhooksToRepo adds an slice of webhooks to the repository
155+
func (c *GithubRepo) AddWebhooksToRepo(repo string, org string, webhooks []*config.Webhook) error {
137156
var err error
138157

139-
for _, webhook := range opts.Webhooks {
158+
for _, webhook := range webhooks {
140159
hook := &github.Hook{
141160
Name: github.String(webhook.Type),
142161
Config: webhook.Config,
143162
}
144163
_, _, err = c.GithubClient.Repositories.CreateHook(ctx, org, repo, hook)
164+
if githubError, ok := err.(*github.ErrorResponse); ok {
165+
if githubError.Response.StatusCode == http.StatusUnprocessableEntity {
166+
err = errors.Wrap(ErrWebhookAlreadyExist, "webhook already exists")
167+
}
168+
}
145169
}
146170

147171
return err
148172
}
149173

150-
func (c *GithubRepo) AddBranchProtections(repo string, org string, opts *BranchProtectionsOpts) error {
174+
// AddBranchProtections adds an slice of branch protections to the repository
175+
func (c *GithubRepo) AddBranchProtections(repo string, org string, protections config.BranchProtections) error {
151176
var err error
152177

153-
for branch, contexts := range opts.Protections {
178+
for branch, contexts := range protections {
154179
pr := &github.ProtectionRequest{
155180
RequiredStatusChecks: &github.RequiredStatusChecks{
156181
Contexts: contexts,
@@ -162,10 +187,11 @@ func (c *GithubRepo) AddBranchProtections(repo string, org string, opts *BranchP
162187
return err
163188
}
164189

165-
func (c *GithubRepo) AddCollaborators(repo string, org string, opts *CollaboratorsOpts) error {
190+
// AddCollaborators adds an slice of collaborators and their permissions to the repository
191+
func (c *GithubRepo) AddCollaborators(repo string, org string, collaborators []*config.Collaborator) error {
166192
var err error
167193

168-
for _, collaborator := range opts.Collaborators {
194+
for _, collaborator := range collaborators {
169195
opt := &github.RepositoryAddCollaboratorOptions{
170196
Permission: collaborator.Permission,
171197
}

0 commit comments

Comments
 (0)