Skip to content

Commit

Permalink
Merge pull request #751 from traPtitech/impr/app-owners
Browse files Browse the repository at this point in the history
γ‚’γƒ—γƒͺδ½œζˆζ™‚γ«ζ‰€ζœ‰θ€…γ‚’γ‚³γƒ”γƒΌ / Gitea syncγ§ζ‰€ζœ‰θ€…γ‚’θΏ½εŠ 
  • Loading branch information
motoki317 authored Oct 16, 2023
2 parents 03e05e6 + 188ef81 commit 6636de7
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 16 deletions.
3 changes: 2 additions & 1 deletion cmd/wire_gen.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 8 additions & 1 deletion pkg/usecase/apiserver/app_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,15 @@ func (s *Service) validateApp(ctx context.Context, app *domain.Application) erro
}

func (s *Service) CreateApplication(ctx context.Context, app *domain.Application) (*domain.Application, error) {
// Fill owners field
repo, err := s.gitRepo.GetRepository(ctx, app.RepositoryID)
if err != nil {
return nil, errors.Wrap(err, "failed to get repository metadata")
}
app.OwnerIDs = repo.OwnerIDs

// Validate
err := s.validateApp(ctx, app)
err = s.validateApp(ctx, app)
if err != nil {
return nil, err
}
Expand Down
3 changes: 3 additions & 0 deletions pkg/usecase/gitea-integration/integration.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ type Integration struct {
cancel func()

gitRepo domain.GitRepositoryRepository
appRepo domain.ApplicationRepository
userRepo domain.UserRepository
}

func NewIntegration(
c Config,
gitRepo domain.GitRepositoryRepository,
appRepo domain.ApplicationRepository,
userRepo domain.UserRepository,
) (*Integration, error) {
if err := c.Validate(); err != nil {
Expand All @@ -65,6 +67,7 @@ func NewIntegration(
listInterval: time.Duration(c.ListIntervalMs) * time.Millisecond,

gitRepo: gitRepo,
appRepo: appRepo,
userRepo: userRepo,
}, nil
}
Expand Down
55 changes: 41 additions & 14 deletions pkg/usecase/gitea-integration/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,38 +134,65 @@ func (i *Integration) _sync(ctx context.Context) error {
return nil
}

func (i *Integration) syncRepository(ctx context.Context, username string, ownerIDs []string, giteaRepo *gitea.Repository) error {
func (i *Integration) syncRepository(ctx context.Context, username string, giteaOwnerIDs []string, giteaRepo *gitea.Repository) error {
// NOTE: no transaction, creating repository is assumed rare
repos, err := i.gitRepo.GetRepositories(ctx, domain.GetRepositoryCondition{URLs: optional.From([]string{giteaRepo.SSHURL})})
if err != nil {
return err
}

if len(repos) == 0 {
// Does not exist, sync repository metadata
repo := domain.NewRepository(
fmt.Sprintf("%v/%v", username, giteaRepo.Name),
giteaRepo.SSHURL,
optional.From(domain.RepositoryAuth{Method: domain.RepositoryAuthMethodSSH}),
ownerIDs,
giteaOwnerIDs,
)
log.Infof("Syncing repository %v -> id: %v", repo.Name, repo.ID)
err = i.gitRepo.CreateRepository(ctx, repo)
return i.gitRepo.CreateRepository(ctx, repo)
}

// Already exists
repo := repos[0]

// Sync owners
// Are all repository owners on Gitea also an owner of the repository on NeoShowcase?
allOwnersAdded := lo.EveryBy(giteaOwnerIDs, func(ownerID string) bool { return slices.Contains(repo.OwnerIDs, ownerID) })
if !allOwnersAdded {
newOwners := ds.UniqMergeSlice(repo.OwnerIDs, giteaOwnerIDs)
log.Infof("Syncing repository %v (id: %v) owners, %v users -> %v users", repo.Name, repo.ID, len(repo.OwnerIDs), len(newOwners))
err = i.gitRepo.UpdateRepository(ctx, repo.ID, &domain.UpdateRepositoryArgs{OwnerIDs: optional.From(newOwners)})
if err != nil {
return err
}
} else {
// Already exists, sync owners
repo := repos[0]
slices.Sort(repo.OwnerIDs)
slices.Sort(ownerIDs)
if !ds.Equals(repo.OwnerIDs, ownerIDs) {
log.Infof("Syncing repository %v (id: %v) owners, %v users -> %v users", repo.Name, repo.ID, len(repo.OwnerIDs), len(ownerIDs))
err = i.gitRepo.UpdateRepository(ctx, repo.ID, &domain.UpdateRepositoryArgs{OwnerIDs: optional.From(ownerIDs)})
if err != nil {
return err
}
}

// Sync owners of generated applications
apps, err := i.appRepo.GetApplications(ctx, domain.GetApplicationCondition{RepositoryID: optional.From(repo.ID)})
if err != nil {
return err
}
for _, app := range apps {
err = i.syncApplication(ctx, app, giteaOwnerIDs)
if err != nil {
return err
}
}

return nil
}

func (i *Integration) syncApplication(ctx context.Context, app *domain.Application, giteaOwnerIDs []string) error {
// Are all repository owners on Gitea also an owner of generated application on NeoShowcase?
allOwnersAdded := lo.EveryBy(giteaOwnerIDs, func(ownerID string) bool { return slices.Contains(app.OwnerIDs, ownerID) })
if !allOwnersAdded {
newOwners := ds.UniqMergeSlice(app.OwnerIDs, giteaOwnerIDs)
log.Infof("Syncing application %v (id: %v) owners, %v users -> %v users", app.Name, app.ID, len(app.OwnerIDs), newOwners)
err := i.appRepo.UpdateApplication(ctx, app.ID, &domain.UpdateApplicationArgs{OwnerIDs: optional.From(newOwners)})
if err != nil {
return err
}
}
return nil
}
13 changes: 13 additions & 0 deletions pkg/util/ds/slice.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ds

import (
"github.com/samber/lo"
"golang.org/x/exp/constraints"
)

Expand Down Expand Up @@ -64,3 +65,15 @@ func FirstN[T any](s []T, n int) []T {
}
return s[:n]
}

func UniqMergeSlice[T comparable](s1, s2 []T) []T {
s := make([]T, 0, len(s1)+len(s2))
for _, elt := range s1 {
s = append(s, elt)
}
for _, elt := range s2 {
s = append(s, elt)
}
lo.Uniq(s)
return s
}

0 comments on commit 6636de7

Please sign in to comment.