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

Commit 75c5af4

Browse files
committed
feat: adding CODEOWNERS file using maintainers
1 parent 3b51263 commit 75c5af4

File tree

5 files changed

+174
-13
lines changed

5 files changed

+174
-13
lines changed

apis/mpas/v1alpha1/repository_types.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,21 @@ var (
2828
ExistingRepositoryPolicyFail ExistingRepositoryPolicy = "fail"
2929
)
3030

31+
// CommitTemplate defines information that is needed to create the CODEOWNERS file.
32+
type CommitTemplate struct {
33+
Email string `json:"email"`
34+
Name string `json:"name"`
35+
36+
//+optional
37+
Message string `json:"message,omitempty"`
38+
}
39+
40+
// Maintainers defines information needed
41+
type Maintainers struct {
42+
Users []string `json:"users"`
43+
CommitTemplate CommitTemplate `json:"commitTemplate"`
44+
}
45+
3146
// RepositorySpec defines the desired state of Repository
3247
type RepositorySpec struct {
3348
//+required
@@ -49,7 +64,7 @@ type RepositorySpec struct {
4964
//+optional
5065
Domain string `json:"domain,omitempty"`
5166
//+optional
52-
Maintainers []string `json:"maintainers,omitempty"`
67+
Maintainers Maintainers `json:"maintainers,omitempty"`
5368
//+optional
5469
//+kubebuilder:default:=adopt
5570
//+kubebuilder:validation:Enum=adopt;fail

apis/mpas/v1alpha1/zz_generated.deepcopy.go

Lines changed: 37 additions & 5 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/mpas.ocm.software_repositories.yaml

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,30 @@ spec:
6868
default: true
6969
type: boolean
7070
maintainers:
71-
items:
72-
type: string
73-
type: array
71+
description: Maintainers defines information needed
72+
properties:
73+
commitTemplate:
74+
description: CommitTemplate defines information that is needed
75+
to create the CODEOWNERS file.
76+
properties:
77+
email:
78+
type: string
79+
message:
80+
type: string
81+
name:
82+
type: string
83+
required:
84+
- email
85+
- name
86+
type: object
87+
users:
88+
items:
89+
type: string
90+
type: array
91+
required:
92+
- commitTemplate
93+
- users
94+
type: object
7495
owner:
7596
type: string
7697
provider:

pkg/providers/gitea/gitea.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package gitea
77
import (
88
"context"
99
"fmt"
10+
"strings"
1011

1112
"code.gitea.io/sdk/gitea"
1213
v1 "k8s.io/api/core/v1"
@@ -88,6 +89,34 @@ func (c *Client) CreateRepository(ctx context.Context, obj mpasv1alpha1.Reposito
8889
return fmt.Errorf("failed to create repositroy: %w", err)
8990
}
9091

92+
if len(obj.Spec.Maintainers.Users) != 0 {
93+
content := strings.Builder{}
94+
95+
for _, m := range obj.Spec.Maintainers.Users {
96+
_, _ = content.WriteString(fmt.Sprintf("%s\n", m))
97+
}
98+
99+
_, _, err := client.CreateFile(obj.Spec.Owner, obj.Spec.RepositoryName, ".", gitea.CreateFileOptions{
100+
FileOptions: gitea.FileOptions{
101+
Message: obj.Spec.Maintainers.CommitTemplate.Message,
102+
BranchName: "main",
103+
Author: gitea.Identity{
104+
Name: obj.Spec.Maintainers.CommitTemplate.Name,
105+
Email: obj.Spec.Maintainers.CommitTemplate.Email,
106+
},
107+
Committer: gitea.Identity{
108+
Name: obj.Spec.Maintainers.CommitTemplate.Name,
109+
Email: obj.Spec.Maintainers.CommitTemplate.Email,
110+
},
111+
},
112+
Content: content.String(),
113+
})
114+
115+
if err != nil {
116+
return fmt.Errorf("failed to add CODEOWNERS file: %w", err)
117+
}
118+
}
119+
91120
return nil
92121
}
93122

pkg/providers/gogit/gogit.go

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package gogit
77
import (
88
"context"
99
"fmt"
10+
"strings"
1011

1112
"github.com/fluxcd/go-git-providers/gitprovider"
1213
deliveryv1alpha1 "github.com/open-component-model/git-controller/apis/delivery/v1alpha1"
@@ -37,22 +38,36 @@ func CreateOrganizationRepository(ctx context.Context, gc gitprovider.Client, do
3738
Visibility: &visibility,
3839
}
3940

41+
createOpts, err := gitprovider.MakeRepositoryCreateOptions(&gitprovider.RepositoryCreateOptions{AutoInit: gitprovider.BoolVar(true)})
42+
if err != nil {
43+
return fmt.Errorf("failed to create _create_ options for repository: %w", err)
44+
}
45+
4046
switch spec.ExistingRepositoryPolicy {
4147
case mpasv1alpha1.ExistingRepositoryPolicyFail:
42-
if _, err := gc.OrgRepositories().Create(ctx, ref, info); err != nil {
48+
repo, err := gc.OrgRepositories().Create(ctx, ref, info, &createOpts)
49+
if err != nil {
4350
return fmt.Errorf("failed to create repository: %w", err)
4451
}
4552

53+
if err := createCodeownersFile(ctx, repo, spec.Maintainers); err != nil {
54+
return fmt.Errorf("failed to add CODEOWNERS file: %w", err)
55+
}
56+
4657
logger.Info("successfully created organization repository", "domain", domain, "repository", spec.RepositoryName)
4758
case mpasv1alpha1.ExistingRepositoryPolicyAdopt:
48-
_, created, err := gc.OrgRepositories().Reconcile(ctx, ref, info)
59+
repo, created, err := gc.OrgRepositories().Reconcile(ctx, ref, info, &createOpts)
4960
if err != nil {
5061
return fmt.Errorf("failed to reconcile repository: %w", err)
5162
}
5263

5364
if !created {
5465
logger.Info("using existing repository", "domain", domain, "repository", spec.RepositoryName)
5566
} else {
67+
if err := createCodeownersFile(ctx, repo, spec.Maintainers); err != nil {
68+
return fmt.Errorf("failed to add CODEOWNERS file: %w", err)
69+
}
70+
5671
logger.Info("successfully created organization repository", "domain", domain, "repository", spec.RepositoryName)
5772
}
5873
default:
@@ -84,22 +99,36 @@ func CreateUserRepository(ctx context.Context, gc gitprovider.Client, domain str
8499
Visibility: &visibility,
85100
}
86101

102+
createOpts, err := gitprovider.MakeRepositoryCreateOptions(&gitprovider.RepositoryCreateOptions{AutoInit: gitprovider.BoolVar(true)})
103+
if err != nil {
104+
return fmt.Errorf("failed to create _create_ options for repository: %w", err)
105+
}
106+
87107
switch spec.ExistingRepositoryPolicy {
88108
case mpasv1alpha1.ExistingRepositoryPolicyFail:
89-
if _, err := gc.UserRepositories().Create(ctx, ref, info); err != nil {
109+
repo, err := gc.UserRepositories().Create(ctx, ref, info, &createOpts)
110+
if err != nil {
90111
return fmt.Errorf("failed to create repository: %w", err)
91112
}
92113

114+
if err := createCodeownersFile(ctx, repo, spec.Maintainers); err != nil {
115+
return fmt.Errorf("failed to add CODEOWNERS file: %w", err)
116+
}
117+
93118
logger.Info("successfully created user repository", "domain", domain, "repository", spec.RepositoryName)
94119
case mpasv1alpha1.ExistingRepositoryPolicyAdopt:
95-
_, created, err := gc.UserRepositories().Reconcile(ctx, ref, info)
120+
repo, created, err := gc.UserRepositories().Reconcile(ctx, ref, info, &createOpts)
96121
if err != nil {
97122
return fmt.Errorf("failed to reconcile repository: %w", err)
98123
}
99124

100125
if !created {
101126
logger.Info("using existing repository", "domain", domain, "repository", spec.RepositoryName)
102127
} else {
128+
if err := createCodeownersFile(ctx, repo, spec.Maintainers); err != nil {
129+
return fmt.Errorf("failed to add CODEOWNERS file: %w", err)
130+
}
131+
103132
logger.Info("successfully created user repository", "domain", domain, "repository", spec.RepositoryName)
104133
}
105134
default:
@@ -194,3 +223,38 @@ func CreateUserPullRequest(ctx context.Context, gc gitprovider.Client, domain, b
194223

195224
return nil
196225
}
226+
227+
// Repositories groups together a common functionality of both repository types.
228+
type Repositories interface {
229+
Commits() gitprovider.CommitClient
230+
}
231+
232+
func createCodeownersFile(ctx context.Context, repo Repositories, maintainers mpasv1alpha1.Maintainers) error {
233+
if len(maintainers.Users) == 0 {
234+
return nil
235+
}
236+
237+
logger := log.FromContext(ctx)
238+
239+
content := strings.Builder{}
240+
241+
for _, m := range maintainers.Users {
242+
_, _ = content.WriteString(fmt.Sprintf("%s\n", m))
243+
}
244+
245+
files := []gitprovider.CommitFile{
246+
{
247+
Path: gitprovider.StringVar("."),
248+
Content: gitprovider.StringVar(content.String()),
249+
},
250+
}
251+
252+
commit, err := repo.Commits().Create(ctx, "main", "adding CODEOWNERS", files)
253+
if err != nil {
254+
return fmt.Errorf("failed to create CODEOWNERS file: %w", err)
255+
}
256+
257+
logger.Info("successfully added CODEOWNERS", "url", commit.Get().URL)
258+
259+
return nil
260+
}

0 commit comments

Comments
 (0)