mirror of
https://github.com/harness/drone.git
synced 2025-05-10 12:20:40 +08:00
feat: support codewoners usrgrp (#826)
This commit is contained in:
parent
5cdbde8100
commit
04566e1cf9
@ -67,17 +67,34 @@ func mapCodeOwnerEvaluation(ownerEvaluation *codeowners.Evaluation) []types.Code
|
|||||||
codeOwnerEvaluationEntries := make([]types.CodeOwnerEvaluationEntry, len(ownerEvaluation.EvaluationEntries))
|
codeOwnerEvaluationEntries := make([]types.CodeOwnerEvaluationEntry, len(ownerEvaluation.EvaluationEntries))
|
||||||
for i, entry := range ownerEvaluation.EvaluationEntries {
|
for i, entry := range ownerEvaluation.EvaluationEntries {
|
||||||
ownerEvaluations := make([]types.OwnerEvaluation, len(entry.OwnerEvaluations))
|
ownerEvaluations := make([]types.OwnerEvaluation, len(entry.OwnerEvaluations))
|
||||||
|
userGroupOwnerEvaluations := make([]types.UserGroupOwnerEvaluation, len(entry.UserGroupOwnerEvaluations))
|
||||||
for j, owner := range entry.OwnerEvaluations {
|
for j, owner := range entry.OwnerEvaluations {
|
||||||
ownerEvaluations[j] = types.OwnerEvaluation{
|
ownerEvaluations[j] = mapOwner(owner)
|
||||||
Owner: owner.Owner,
|
}
|
||||||
ReviewDecision: owner.ReviewDecision,
|
for j, userGroupOwnerEvaluation := range entry.UserGroupOwnerEvaluations {
|
||||||
ReviewSHA: owner.ReviewSHA,
|
userGroupEvaluations := make([]types.OwnerEvaluation, len(userGroupOwnerEvaluation.Evaluations))
|
||||||
|
for k, userGroupOwner := range userGroupOwnerEvaluation.Evaluations {
|
||||||
|
userGroupEvaluations[k] = mapOwner(userGroupOwner)
|
||||||
|
}
|
||||||
|
userGroupOwnerEvaluations[j] = types.UserGroupOwnerEvaluation{
|
||||||
|
ID: userGroupOwnerEvaluation.ID,
|
||||||
|
Name: userGroupOwnerEvaluation.Name,
|
||||||
|
Evaluations: userGroupEvaluations,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
codeOwnerEvaluationEntries[i] = types.CodeOwnerEvaluationEntry{
|
codeOwnerEvaluationEntries[i] = types.CodeOwnerEvaluationEntry{
|
||||||
Pattern: entry.Pattern,
|
Pattern: entry.Pattern,
|
||||||
OwnerEvaluations: ownerEvaluations,
|
OwnerEvaluations: ownerEvaluations,
|
||||||
|
UserGroupOwnerEvaluations: userGroupOwnerEvaluations,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return codeOwnerEvaluationEntries
|
return codeOwnerEvaluationEntries
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func mapOwner(owner codeowners.OwnerEvaluation) types.OwnerEvaluation {
|
||||||
|
return types.OwnerEvaluation{
|
||||||
|
Owner: owner.Owner,
|
||||||
|
ReviewDecision: owner.ReviewDecision,
|
||||||
|
ReviewSHA: owner.ReviewSHA,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"github.com/harness/gitness/app/services/usergroup"
|
||||||
"github.com/harness/gitness/app/store"
|
"github.com/harness/gitness/app/store"
|
||||||
"github.com/harness/gitness/errors"
|
"github.com/harness/gitness/errors"
|
||||||
"github.com/harness/gitness/git"
|
"github.com/harness/gitness/git"
|
||||||
@ -37,6 +38,8 @@ const (
|
|||||||
// maxGetContentFileSize specifies the maximum number of bytes a file content response contains.
|
// maxGetContentFileSize specifies the maximum number of bytes a file content response contains.
|
||||||
// If a file is any larger, the content is truncated.
|
// If a file is any larger, the content is truncated.
|
||||||
maxGetContentFileSize = oneMegabyte * 4 // 4 MB
|
maxGetContentFileSize = oneMegabyte * 4 // 4 MB
|
||||||
|
// userGroupPrefixMarker is a prefix which will be used to identify if a given codeowner is usergroup.
|
||||||
|
userGroupPrefixMarker = "@"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -75,6 +78,7 @@ type Service struct {
|
|||||||
git git.Interface
|
git git.Interface
|
||||||
principalStore store.PrincipalStore
|
principalStore store.PrincipalStore
|
||||||
config Config
|
config Config
|
||||||
|
userGroupResolver usergroup.Resolver
|
||||||
}
|
}
|
||||||
|
|
||||||
type File struct {
|
type File struct {
|
||||||
@ -101,6 +105,13 @@ type Evaluation struct {
|
|||||||
type EvaluationEntry struct {
|
type EvaluationEntry struct {
|
||||||
Pattern string
|
Pattern string
|
||||||
OwnerEvaluations []OwnerEvaluation
|
OwnerEvaluations []OwnerEvaluation
|
||||||
|
UserGroupOwnerEvaluations []UserGroupOwnerEvaluation
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserGroupOwnerEvaluation struct {
|
||||||
|
ID string
|
||||||
|
Name string
|
||||||
|
Evaluations []OwnerEvaluation
|
||||||
}
|
}
|
||||||
|
|
||||||
type OwnerEvaluation struct {
|
type OwnerEvaluation struct {
|
||||||
@ -114,12 +125,14 @@ func New(
|
|||||||
git git.Interface,
|
git git.Interface,
|
||||||
config Config,
|
config Config,
|
||||||
principalStore store.PrincipalStore,
|
principalStore store.PrincipalStore,
|
||||||
|
userGroupResolver usergroup.Resolver,
|
||||||
) *Service {
|
) *Service {
|
||||||
service := &Service{
|
service := &Service{
|
||||||
repoStore: repoStore,
|
repoStore: repoStore,
|
||||||
git: git,
|
git: git,
|
||||||
config: config,
|
config: config,
|
||||||
principalStore: principalStore,
|
principalStore: principalStore,
|
||||||
|
userGroupResolver: userGroupResolver,
|
||||||
}
|
}
|
||||||
return service
|
return service
|
||||||
}
|
}
|
||||||
@ -284,11 +297,12 @@ func (s *Service) getApplicableCodeOwnersForPR(
|
|||||||
}, err
|
}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//nolint:gocognit
|
||||||
func (s *Service) Evaluate(
|
func (s *Service) Evaluate(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
repo *types.Repository,
|
repo *types.Repository,
|
||||||
pr *types.PullReq,
|
pr *types.PullReq,
|
||||||
reviewer []*types.PullReqReviewer,
|
reviewers []*types.PullReqReviewer,
|
||||||
) (*Evaluation, error) {
|
) (*Evaluation, error) {
|
||||||
owners, err := s.getApplicableCodeOwnersForPR(ctx, repo, pr)
|
owners, err := s.getApplicableCodeOwnersForPR(ctx, repo, pr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -299,36 +313,41 @@ func (s *Service) Evaluate(
|
|||||||
return &Evaluation{}, nil
|
return &Evaluation{}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
flattenedReviewers := flattenReviewers(reviewer)
|
|
||||||
evaluationEntries := make([]EvaluationEntry, len(owners.Entries))
|
evaluationEntries := make([]EvaluationEntry, len(owners.Entries))
|
||||||
|
|
||||||
for i, entry := range owners.Entries {
|
for i, entry := range owners.Entries {
|
||||||
ownerEvaluations := make([]OwnerEvaluation, 0, len(owners.Entries))
|
ownerEvaluations := make([]OwnerEvaluation, 0, len(owners.Entries))
|
||||||
|
userGroupOwnerEvaluations := make([]UserGroupOwnerEvaluation, 0, len(owners.Entries))
|
||||||
for _, owner := range entry.Owners {
|
for _, owner := range entry.Owners {
|
||||||
if pullreqReviewer, ok := flattenedReviewers[owner]; ok {
|
// check for usrgrp
|
||||||
ownerEvaluations = append(ownerEvaluations, OwnerEvaluation{
|
if strings.HasPrefix(owner, userGroupPrefixMarker) {
|
||||||
Owner: pullreqReviewer.Reviewer,
|
userGroupCodeOwner, err := s.resolveUserGroupCodeOwner(ctx, owner[1:], reviewers)
|
||||||
ReviewDecision: pullreqReviewer.ReviewDecision,
|
if errors.Is(err, usergroup.ErrNotFound) {
|
||||||
ReviewSHA: pullreqReviewer.SHA,
|
log.Ctx(ctx).Debug().Msgf("usergroup %q not found hence skipping for code owner", owner)
|
||||||
})
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
principal, err := s.principalStore.FindByEmail(ctx, owner)
|
|
||||||
if errors.Is(err, gitness_store.ErrResourceNotFound) {
|
|
||||||
log.Ctx(ctx).Info().Msgf("user %s not found in database hence skipping for code owner: %v",
|
|
||||||
owner, err)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &Evaluation{}, fmt.Errorf("error finding user by email: %w", err)
|
return nil, fmt.Errorf("error resolving usergroup :%w", err)
|
||||||
}
|
}
|
||||||
ownerEvaluations = append(ownerEvaluations, OwnerEvaluation{
|
userGroupOwnerEvaluations = append(userGroupOwnerEvaluations, *userGroupCodeOwner)
|
||||||
Owner: *principal.ToPrincipalInfo(),
|
continue
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
// user email based codeowner
|
||||||
|
userCodeOwner, err := s.resolveUserCodeOwnerByEmail(ctx, owner, reviewers)
|
||||||
|
if errors.Is(err, gitness_store.ErrResourceNotFound) {
|
||||||
|
log.Ctx(ctx).Debug().Msgf("user %q not found in database hence skipping for code owner", owner)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error resolving user by email : %w", err)
|
||||||
|
}
|
||||||
|
ownerEvaluations = append(ownerEvaluations, *userCodeOwner)
|
||||||
|
}
|
||||||
|
|
||||||
evaluationEntries[i] = EvaluationEntry{
|
evaluationEntries[i] = EvaluationEntry{
|
||||||
Pattern: entry.Pattern,
|
Pattern: entry.Pattern,
|
||||||
OwnerEvaluations: ownerEvaluations,
|
OwnerEvaluations: ownerEvaluations,
|
||||||
|
UserGroupOwnerEvaluations: userGroupOwnerEvaluations,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -338,6 +357,62 @@ func (s *Service) Evaluate(
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Service) resolveUserGroupCodeOwner(
|
||||||
|
ctx context.Context,
|
||||||
|
owner string,
|
||||||
|
reviewers []*types.PullReqReviewer,
|
||||||
|
) (*UserGroupOwnerEvaluation, error) {
|
||||||
|
usrgrp, err := s.userGroupResolver.Resolve(ctx, owner)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("not able to resolve usergroup : %w", err)
|
||||||
|
}
|
||||||
|
userGroupEvaluation := &UserGroupOwnerEvaluation{
|
||||||
|
ID: usrgrp.ID,
|
||||||
|
Name: usrgrp.Name,
|
||||||
|
}
|
||||||
|
ownersEvaluations := make([]OwnerEvaluation, 0, len(usrgrp.Users))
|
||||||
|
for _, uid := range usrgrp.Users {
|
||||||
|
pullreqReviewer := findReviewerInList("", uid, reviewers)
|
||||||
|
// we don't append all the user of the user group in the owner evaluations and
|
||||||
|
// append it only if it is reviewed by a user.
|
||||||
|
if pullreqReviewer != nil {
|
||||||
|
ownersEvaluations = append(ownersEvaluations,
|
||||||
|
OwnerEvaluation{
|
||||||
|
Owner: pullreqReviewer.Reviewer,
|
||||||
|
ReviewDecision: pullreqReviewer.ReviewDecision,
|
||||||
|
ReviewSHA: pullreqReviewer.SHA,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
userGroupEvaluation.Evaluations = ownersEvaluations
|
||||||
|
|
||||||
|
return userGroupEvaluation, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) resolveUserCodeOwnerByEmail(
|
||||||
|
ctx context.Context,
|
||||||
|
owner string,
|
||||||
|
reviewers []*types.PullReqReviewer,
|
||||||
|
) (*OwnerEvaluation, error) {
|
||||||
|
pullreqReviewer := findReviewerInList(owner, "", reviewers)
|
||||||
|
if pullreqReviewer != nil {
|
||||||
|
return &OwnerEvaluation{
|
||||||
|
Owner: pullreqReviewer.Reviewer,
|
||||||
|
ReviewDecision: pullreqReviewer.ReviewDecision,
|
||||||
|
ReviewSHA: pullreqReviewer.SHA,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
principal, err := s.principalStore.FindByEmail(ctx, owner)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("error finding user by email: %w", err)
|
||||||
|
}
|
||||||
|
return &OwnerEvaluation{
|
||||||
|
Owner: *principal.ToPrincipalInfo(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Service) Validate(
|
func (s *Service) Validate(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
repo *types.Repository,
|
repo *types.Repository,
|
||||||
@ -353,6 +428,10 @@ func (s *Service) Validate(
|
|||||||
for _, entry := range codeowners.Entries {
|
for _, entry := range codeowners.Entries {
|
||||||
// check for users in file
|
// check for users in file
|
||||||
for _, owner := range entry.Owners {
|
for _, owner := range entry.Owners {
|
||||||
|
// todo: handle usergroup better
|
||||||
|
if strings.HasPrefix(owner, userGroupPrefixMarker) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
_, err := s.principalStore.FindByEmail(ctx, owner)
|
_, err := s.principalStore.FindByEmail(ctx, owner)
|
||||||
if errors.Is(err, gitness_store.ErrResourceNotFound) {
|
if errors.Is(err, gitness_store.ErrResourceNotFound) {
|
||||||
codeOwnerValidation.Addf(enum.CodeOwnerViolationCodeUserNotFound,
|
codeOwnerValidation.Addf(enum.CodeOwnerViolationCodeUserNotFound,
|
||||||
@ -381,12 +460,14 @@ func (s *Service) Validate(
|
|||||||
return &codeOwnerValidation, nil
|
return &codeOwnerValidation, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func flattenReviewers(reviewers []*types.PullReqReviewer) map[string]*types.PullReqReviewer {
|
func findReviewerInList(email string, uid string, reviewers []*types.PullReqReviewer) *types.PullReqReviewer {
|
||||||
r := make(map[string]*types.PullReqReviewer)
|
|
||||||
for _, reviewer := range reviewers {
|
for _, reviewer := range reviewers {
|
||||||
r[reviewer.Reviewer.Email] = reviewer
|
if uid == reviewer.Reviewer.UID || email == reviewer.Reviewer.Email {
|
||||||
|
return reviewer
|
||||||
}
|
}
|
||||||
return r
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// We match a pattern list against a target
|
// We match a pattern list against a target
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
package codeowners
|
package codeowners
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/harness/gitness/app/services/usergroup"
|
||||||
"github.com/harness/gitness/app/store"
|
"github.com/harness/gitness/app/store"
|
||||||
"github.com/harness/gitness/git"
|
"github.com/harness/gitness/git"
|
||||||
|
|
||||||
@ -30,6 +31,7 @@ func ProvideCodeOwners(
|
|||||||
repoStore store.RepoStore,
|
repoStore store.RepoStore,
|
||||||
config Config,
|
config Config,
|
||||||
principalStore store.PrincipalStore,
|
principalStore store.PrincipalStore,
|
||||||
|
userGroupResolver usergroup.Resolver,
|
||||||
) *Service {
|
) *Service {
|
||||||
return New(repoStore, git, config, principalStore)
|
return New(repoStore, git, config, principalStore, userGroupResolver)
|
||||||
}
|
}
|
||||||
|
@ -108,7 +108,7 @@ func (v *DefPullReq) MergeVerify(
|
|||||||
|
|
||||||
if v.Approvals.RequireCodeOwners {
|
if v.Approvals.RequireCodeOwners {
|
||||||
for _, entry := range in.CodeOwners.EvaluationEntries {
|
for _, entry := range in.CodeOwners.EvaluationEntries {
|
||||||
reviewDecision, approvers := getCodeOwnerApprovalStatus(entry.OwnerEvaluations)
|
reviewDecision, approvers := getCodeOwnerApprovalStatus(entry)
|
||||||
|
|
||||||
if reviewDecision == enum.PullReqReviewDecisionPending {
|
if reviewDecision == enum.PullReqReviewDecisionPending {
|
||||||
violations.Addf(codePullReqApprovalReqCodeOwnersNoApproval,
|
violations.Addf(codePullReqApprovalReqCodeOwnersNoApproval,
|
||||||
@ -295,10 +295,12 @@ func (v *DefPullReq) Sanitize() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func getCodeOwnerApprovalStatus(
|
func getCodeOwnerApprovalStatus(
|
||||||
ownerStatus []codeowners.OwnerEvaluation,
|
entry codeowners.EvaluationEntry,
|
||||||
) (enum.PullReqReviewDecision, []codeowners.OwnerEvaluation) {
|
) (enum.PullReqReviewDecision, []codeowners.OwnerEvaluation) {
|
||||||
approvers := make([]codeowners.OwnerEvaluation, 0)
|
approvers := make([]codeowners.OwnerEvaluation, 0)
|
||||||
for _, o := range ownerStatus {
|
|
||||||
|
// users
|
||||||
|
for _, o := range entry.OwnerEvaluations {
|
||||||
if o.ReviewDecision == enum.PullReqReviewDecisionChangeReq {
|
if o.ReviewDecision == enum.PullReqReviewDecisionChangeReq {
|
||||||
return enum.PullReqReviewDecisionChangeReq, nil
|
return enum.PullReqReviewDecisionChangeReq, nil
|
||||||
}
|
}
|
||||||
@ -306,6 +308,19 @@ func getCodeOwnerApprovalStatus(
|
|||||||
approvers = append(approvers, o)
|
approvers = append(approvers, o)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// usergroups
|
||||||
|
for _, u := range entry.UserGroupOwnerEvaluations {
|
||||||
|
for _, o := range u.Evaluations {
|
||||||
|
if o.ReviewDecision == enum.PullReqReviewDecisionChangeReq {
|
||||||
|
return enum.PullReqReviewDecisionChangeReq, nil
|
||||||
|
}
|
||||||
|
if o.ReviewDecision == enum.PullReqReviewDecisionApproved {
|
||||||
|
approvers = append(approvers, o)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if len(approvers) > 0 {
|
if len(approvers) > 0 {
|
||||||
return enum.PullReqReviewDecisionApproved, approvers
|
return enum.PullReqReviewDecisionApproved, approvers
|
||||||
}
|
}
|
||||||
|
@ -17,14 +17,19 @@ package usergroup
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"github.com/harness/gitness/store"
|
|
||||||
"github.com/harness/gitness/types"
|
"github.com/harness/gitness/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Service struct {
|
var _ Resolver = (*GitnessResolver)(nil)
|
||||||
|
|
||||||
|
type GitnessResolver struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) Resolve(context.Context, string) (*types.UserGroup, error) {
|
func NewGitnessResolver() *GitnessResolver {
|
||||||
// todo: implement once usergroup is supported
|
return &GitnessResolver{}
|
||||||
return nil, store.ErrResourceNotFound
|
}
|
||||||
|
|
||||||
|
func (s *GitnessResolver) Resolve(context.Context, string) (*types.UserGroup, error) {
|
||||||
|
// todo: implement once usergroup is supported
|
||||||
|
return nil, ErrNotFound
|
||||||
}
|
}
|
@ -16,10 +16,13 @@ package usergroup
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
"github.com/harness/gitness/types"
|
"github.com/harness/gitness/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrNotFound = errors.New("usergroup not found")
|
||||||
|
|
||||||
type Resolver interface {
|
type Resolver interface {
|
||||||
Resolve(ctx context.Context, scopedID string) (*types.UserGroup, error)
|
Resolve(ctx context.Context, scopedID string) (*types.UserGroup, error)
|
||||||
}
|
}
|
||||||
|
28
app/services/usergroup/wire.go
Normal file
28
app/services/usergroup/wire.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2023 Harness, Inc.
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
|
||||||
|
package usergroup
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/google/wire"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WireSet provides a wire set for this package.
|
||||||
|
var WireSet = wire.NewSet(
|
||||||
|
ProvideUserGroupResolver,
|
||||||
|
)
|
||||||
|
|
||||||
|
func ProvideUserGroupResolver() Resolver {
|
||||||
|
return NewGitnessResolver()
|
||||||
|
}
|
@ -59,6 +59,7 @@ import (
|
|||||||
"github.com/harness/gitness/app/services/protection"
|
"github.com/harness/gitness/app/services/protection"
|
||||||
pullreqservice "github.com/harness/gitness/app/services/pullreq"
|
pullreqservice "github.com/harness/gitness/app/services/pullreq"
|
||||||
"github.com/harness/gitness/app/services/trigger"
|
"github.com/harness/gitness/app/services/trigger"
|
||||||
|
"github.com/harness/gitness/app/services/usergroup"
|
||||||
"github.com/harness/gitness/app/services/webhook"
|
"github.com/harness/gitness/app/services/webhook"
|
||||||
"github.com/harness/gitness/app/sse"
|
"github.com/harness/gitness/app/sse"
|
||||||
"github.com/harness/gitness/app/store"
|
"github.com/harness/gitness/app/store"
|
||||||
@ -164,6 +165,7 @@ func initSystem(ctx context.Context, config *types.Config) (*cliserver.System, e
|
|||||||
cliserver.ProvideKeywordSearchConfig,
|
cliserver.ProvideKeywordSearchConfig,
|
||||||
keywordsearch.WireSet,
|
keywordsearch.WireSet,
|
||||||
controllerkeywordsearch.WireSet,
|
controllerkeywordsearch.WireSet,
|
||||||
|
usergroup.WireSet,
|
||||||
)
|
)
|
||||||
return &cliserver.System{}, nil
|
return &cliserver.System{}, nil
|
||||||
}
|
}
|
||||||
|
@ -58,6 +58,7 @@ import (
|
|||||||
"github.com/harness/gitness/app/services/protection"
|
"github.com/harness/gitness/app/services/protection"
|
||||||
"github.com/harness/gitness/app/services/pullreq"
|
"github.com/harness/gitness/app/services/pullreq"
|
||||||
trigger2 "github.com/harness/gitness/app/services/trigger"
|
trigger2 "github.com/harness/gitness/app/services/trigger"
|
||||||
|
"github.com/harness/gitness/app/services/usergroup"
|
||||||
"github.com/harness/gitness/app/services/webhook"
|
"github.com/harness/gitness/app/services/webhook"
|
||||||
"github.com/harness/gitness/app/sse"
|
"github.com/harness/gitness/app/sse"
|
||||||
"github.com/harness/gitness/app/store"
|
"github.com/harness/gitness/app/store"
|
||||||
@ -161,7 +162,8 @@ func initSystem(ctx context.Context, config *types.Config) (*server.System, erro
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
codeownersConfig := server.ProvideCodeOwnerConfig(config)
|
codeownersConfig := server.ProvideCodeOwnerConfig(config)
|
||||||
codeownersService := codeowners.ProvideCodeOwners(gitInterface, repoStore, codeownersConfig, principalStore)
|
resolver := usergroup.ProvideUserGroupResolver()
|
||||||
|
codeownersService := codeowners.ProvideCodeOwners(gitInterface, repoStore, codeownersConfig, principalStore, resolver)
|
||||||
eventsConfig := server.ProvideEventsConfig(config)
|
eventsConfig := server.ProvideEventsConfig(config)
|
||||||
eventsSystem, err := events.ProvideSystem(eventsConfig, universalClient)
|
eventsSystem, err := events.ProvideSystem(eventsConfig, universalClient)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -28,6 +28,13 @@ type CodeOwnerEvaluation struct {
|
|||||||
type CodeOwnerEvaluationEntry struct {
|
type CodeOwnerEvaluationEntry struct {
|
||||||
Pattern string `json:"pattern"`
|
Pattern string `json:"pattern"`
|
||||||
OwnerEvaluations []OwnerEvaluation `json:"owner_evaluations"`
|
OwnerEvaluations []OwnerEvaluation `json:"owner_evaluations"`
|
||||||
|
UserGroupOwnerEvaluations []UserGroupOwnerEvaluation `json:"user_group_owner_evaluations"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type UserGroupOwnerEvaluation struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
Evaluations []OwnerEvaluation `json:"evaluations"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type OwnerEvaluation struct {
|
type OwnerEvaluation struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user