@@ -2,6 +2,7 @@ package repo
22
33import (
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
5956func NewGithub (githubClient * github.Client ) * GithubRepo {
@@ -62,6 +59,7 @@ func NewGithub(githubClient *github.Client) *GithubRepo {
6259 }
6360}
6461
62+ // CreateRepo creates a github repository
6563func (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
7782func (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
114127func (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