Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

adding properties AutoMergeAllowed, DeleteBranchOnMerge, AllowUpdateB… #77

Merged
merged 1 commit into from
Oct 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ kind: Repository
name: awesome-repository
spec:
public: true
allow_auto_merge: true
delete_branch_on_merge: true
allow_update_branch: true
writers:
- anotherteamA
- anotherteamB
Expand All @@ -76,7 +79,10 @@ spec:
```

In this last example:
- the repository is now publci
- the repository is now public
- the repository allows auto merge
- the repository will delete the branch on merge
- the repository allows to update the branch
- other teams have write (`anotherteamA`, `anotherteamB`) or read (`anotherteamC`, `anotherteamD`) access

### Archive a repository
Expand Down
12 changes: 12 additions & 0 deletions browser/goliac-ui/src/components/RepositoryApp.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,18 @@
<el-text>Archived : </el-text>
<el-text>{{ repository.archived}}</el-text>
</div>
<div class="flex-container">
<el-text>Auto Merge Allowed : </el-text>
<el-text>{{ repository.autoMergeAllowed}}</el-text>
</div>
<div class="flex-container">
<el-text>Delete Branch on Merge : </el-text>
<el-text>{{ repository.deleteBranchOnMerge}}</el-text>
</div>
<div class="flex-container">
<el-text>Allow Update Branch : </el-text>
<el-text>{{ repository.allowUpdateBranch}}</el-text>
</div>
</el-card>
</el-col>
</el-row>
Expand Down
24 changes: 24 additions & 0 deletions docs/api_docs/bundle.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,18 @@ definitions:
type: boolean
x-isnullable: false
x-omitempty: false
autoMergeAllowed:
type: boolean
x-isnullable: false
x-omitempty: false
deleteBranchOnMerge:
type: boolean
x-isnullable: false
x-omitempty: false
allowUpdateBranch:
type: boolean
x-isnullable: false
x-omitempty: false
archived:
type: boolean
x-isnullable: false
Expand All @@ -317,6 +329,18 @@ definitions:
type: boolean
x-isnullable: false
x-omitempty: false
autoMergeAllowed:
type: boolean
x-isnullable: false
x-omitempty: false
deleteBranchOnMerge:
type: boolean
x-isnullable: false
x-omitempty: false
allowUpdateBranch:
type: boolean
x-isnullable: false
x-omitempty: false
teams:
type: array
items:
Expand Down
75 changes: 32 additions & 43 deletions internal/engine/goliac_reconciliator.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,8 +196,7 @@ func (r *GoliacReconciliatorImpl) reconciliateTeams(ctx context.Context, local G
}

type GithubRepoComparable struct {
IsPublic bool
IsArchived bool
BoolProperties map[string]bool
Writers []string
Readers []string
ExternalUserReaders []string // githubids
Expand All @@ -213,13 +212,15 @@ func (r *GoliacReconciliatorImpl) reconciliateRepositories(ctx context.Context,
rRepos := make(map[string]*GithubRepoComparable)
for k, v := range ghRepos {
repo := &GithubRepoComparable{
IsPublic: !v.IsPrivate,
IsArchived: v.IsArchived,
BoolProperties: map[string]bool{},
Writers: []string{},
Readers: []string{},
ExternalUserReaders: []string{},
ExternalUserWriters: []string{},
}
for pk, pv := range v.BoolProperties {
repo.BoolProperties[pk] = pv
}

for cGithubid, cPermission := range v.ExternalUsers {
if cPermission == "WRITE" {
Expand Down Expand Up @@ -288,8 +289,13 @@ func (r *GoliacReconciliatorImpl) reconciliateRepositories(ctx context.Context,
}

lRepos[slug.Make(reponame)] = &GithubRepoComparable{
IsPublic: lRepo.Spec.IsPublic,
IsArchived: lRepo.Archived,
BoolProperties: map[string]bool{
"private": !lRepo.Spec.IsPublic,
"archived": lRepo.Archived,
"allow_auto_merge": lRepo.Spec.AllowAutoMerge,
"delete_branch_on_merge": lRepo.Spec.DeleteBranchOnMerge,
"allow_update_branch": lRepo.Spec.AllowUpdateBranch,
},
Readers: readers,
Writers: writers,
ExternalUserReaders: eReaders,
Expand All @@ -300,11 +306,10 @@ func (r *GoliacReconciliatorImpl) reconciliateRepositories(ctx context.Context,
// now we compare local (slugTeams) and remote (rTeams)

compareRepos := func(lRepo *GithubRepoComparable, rRepo *GithubRepoComparable) bool {
if lRepo.IsArchived != rRepo.IsArchived {
return false
}
if lRepo.IsPublic != rRepo.IsPublic {
return false
for lk, lv := range lRepo.BoolProperties {
if rv, ok := rRepo.BoolProperties[lk]; !ok || rv != lv {
return false
}
}

if res, _, _ := entity.StringArrayEquivalent(lRepo.Readers, rRepo.Readers); !res {
Expand All @@ -327,16 +332,11 @@ func (r *GoliacReconciliatorImpl) reconciliateRepositories(ctx context.Context,
}

onChanged := func(reponame string, lRepo *GithubRepoComparable, rRepo *GithubRepoComparable) {
// reconciliate repositories public/private
if lRepo.IsPublic != rRepo.IsPublic {
// UPDATE private repository
r.UpdateRepositoryUpdatePrivate(ctx, dryrun, remote, reponame, !lRepo.IsPublic)
}

// reconciliate repositories archived
if lRepo.IsArchived != rRepo.IsArchived {
// UPDATE archived repository
r.UpdateRepositoryUpdateArchived(ctx, dryrun, remote, reponame, lRepo.IsArchived)
// reconciliate repositories boolean properties
for lk, lv := range lRepo.BoolProperties {
if rv, ok := rRepo.BoolProperties[lk]; !ok || rv != lv {
r.UpdateRepositoryUpdateBoolProperty(ctx, dryrun, remote, reponame, lk, lv)
}
}

if res, readToRemove, readToAdd := entity.StringArrayEquivalent(lRepo.Readers, rRepo.Readers); !res {
Expand Down Expand Up @@ -406,11 +406,11 @@ func (r *GoliacReconciliatorImpl) reconciliateRepositories(ctx context.Context,
// if the repo was just archived in a previous commit and we "resume it"
if aRepo, ok := toArchive[reponame]; ok {
delete(toArchive, reponame)
r.UpdateRepositoryUpdateArchived(ctx, dryrun, remote, reponame, false)
r.UpdateRepositoryUpdateBoolProperty(ctx, dryrun, remote, reponame, "archived", false)
// calling onChanged to update the repository permissions
onChanged(reponame, aRepo, rRepo)
} else {
r.CreateRepository(ctx, dryrun, remote, reponame, reponame, lRepo.Writers, lRepo.Readers, lRepo.IsPublic)
r.CreateRepository(ctx, dryrun, remote, reponame, reponame, lRepo.Writers, lRepo.Readers, lRepo.BoolProperties)
}
}

Expand All @@ -420,7 +420,7 @@ func (r *GoliacReconciliatorImpl) reconciliateRepositories(ctx context.Context,
// but if we have ArchiveOnDelete...
if r.repoconfig.ArchiveOnDelete {
if r.repoconfig.DestructiveOperations.AllowDestructiveRepositories {
r.UpdateRepositoryUpdateArchived(ctx, dryrun, remote, reponame, true)
r.UpdateRepositoryUpdateBoolProperty(ctx, dryrun, remote, reponame, "archived", true)
toArchive[reponame] = rRepo
}
} else {
Expand Down Expand Up @@ -602,15 +602,15 @@ func (r *GoliacReconciliatorImpl) DeleteTeam(ctx context.Context, dryrun bool, r
}
}
}
func (r *GoliacReconciliatorImpl) CreateRepository(ctx context.Context, dryrun bool, remote *MutableGoliacRemoteImpl, reponame string, descrition string, writers []string, readers []string, public bool) {
func (r *GoliacReconciliatorImpl) CreateRepository(ctx context.Context, dryrun bool, remote *MutableGoliacRemoteImpl, reponame string, descrition string, writers []string, readers []string, boolProperties map[string]bool) {
author := "unknown"
if a := ctx.Value(KeyAuthor); a != nil {
author = a.(string)
}
logrus.WithFields(map[string]interface{}{"dryrun": dryrun, "author": author, "command": "create_repository"}).Infof("repositoryname: %s, readers: %s, writers: %s, public: %v", reponame, strings.Join(readers, ","), strings.Join(writers, ","), public)
remote.CreateRepository(reponame, reponame, writers, readers, public)
logrus.WithFields(map[string]interface{}{"dryrun": dryrun, "author": author, "command": "create_repository"}).Infof("repositoryname: %s, readers: %s, writers: %s, boolProperties: %v", reponame, strings.Join(readers, ","), strings.Join(writers, ","), boolProperties)
remote.CreateRepository(reponame, reponame, writers, readers, boolProperties)
if r.executor != nil {
r.executor.CreateRepository(dryrun, reponame, reponame, writers, readers, public)
r.executor.CreateRepository(dryrun, reponame, reponame, writers, readers, boolProperties)
}
}
func (r *GoliacReconciliatorImpl) UpdateRepositoryAddTeamAccess(ctx context.Context, dryrun bool, remote *MutableGoliacRemoteImpl, reponame string, teamslug string, permission string) {
Expand Down Expand Up @@ -661,26 +661,15 @@ func (r *GoliacReconciliatorImpl) DeleteRepository(ctx context.Context, dryrun b
}
}
}
func (r *GoliacReconciliatorImpl) UpdateRepositoryUpdatePrivate(ctx context.Context, dryrun bool, remote *MutableGoliacRemoteImpl, reponame string, private bool) {
author := "unknown"
if a := ctx.Value(KeyAuthor); a != nil {
author = a.(string)
}
logrus.WithFields(map[string]interface{}{"dryrun": dryrun, "author": author, "command": "update_repository_update_private"}).Infof("repositoryname: %s private:%v", reponame, private)
remote.UpdateRepositoryUpdatePrivate(reponame, private)
if r.executor != nil {
r.executor.UpdateRepositoryUpdatePrivate(dryrun, reponame, private)
}
}
func (r *GoliacReconciliatorImpl) UpdateRepositoryUpdateArchived(ctx context.Context, dryrun bool, remote *MutableGoliacRemoteImpl, reponame string, archived bool) {
func (r *GoliacReconciliatorImpl) UpdateRepositoryUpdateBoolProperty(ctx context.Context, dryrun bool, remote *MutableGoliacRemoteImpl, reponame string, propertyName string, propertyValue bool) {
author := "unknown"
if a := ctx.Value(KeyAuthor); a != nil {
author = a.(string)
}
logrus.WithFields(map[string]interface{}{"dryrun": dryrun, "author": author, "command": "update_repository_update_archived"}).Infof("repositoryname: %s archived:%v", reponame, archived)
remote.UpdateRepositoryUpdateArchived(reponame, archived)
logrus.WithFields(map[string]interface{}{"dryrun": dryrun, "author": author, "command": "update_repository_update_bool_property"}).Infof("repositoryname: %s %s:%v", reponame, propertyName, propertyValue)
remote.UpdateRepositoryUpdateBoolProperty(reponame, propertyName, propertyValue)
if r.executor != nil {
r.executor.UpdateRepositoryUpdateArchived(dryrun, reponame, archived)
r.executor.UpdateRepositoryUpdateBoolProperty(dryrun, reponame, propertyName, propertyValue)
}
}
func (r *GoliacReconciliatorImpl) AddRuleset(ctx context.Context, dryrun bool, ruleset *GithubRuleSet) {
Expand Down
54 changes: 35 additions & 19 deletions internal/engine/goliac_reconciliator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ func (r *ReconciliatorListenerRecorder) UpdateTeamRemoveMember(dryrun bool, team
func (r *ReconciliatorListenerRecorder) DeleteTeam(dryrun bool, teamslug string) {
r.TeamDeleted[teamslug] = true
}
func (r *ReconciliatorListenerRecorder) CreateRepository(dryrun bool, reponame string, descrition string, writers []string, readers []string, public bool) {
func (r *ReconciliatorListenerRecorder) CreateRepository(dryrun bool, reponame string, descrition string, writers []string, readers []string, boolProperties map[string]bool) {
r.RepositoryCreated[reponame] = true
}
func (r *ReconciliatorListenerRecorder) UpdateRepositoryAddTeamAccess(dryrun bool, reponame string, teamslug string, permission string) {
Expand All @@ -202,12 +202,9 @@ func (r *ReconciliatorListenerRecorder) UpdateRepositoryRemoveTeamAccess(dryrun
func (r *ReconciliatorListenerRecorder) DeleteRepository(dryrun bool, reponame string) {
r.RepositoriesDeleted[reponame] = true
}
func (r *ReconciliatorListenerRecorder) UpdateRepositoryUpdatePrivate(dryrun bool, reponame string, private bool) {
func (r *ReconciliatorListenerRecorder) UpdateRepositoryUpdateBoolProperty(dryrun bool, reponame string, propertyName string, propertyValue bool) {
r.RepositoriesUpdatePrivate[reponame] = true
}
func (r *ReconciliatorListenerRecorder) UpdateRepositoryUpdateArchived(dryrun bool, reponame string, archived bool) {
r.RepositoriesUpdateArchived[reponame] = true
}
func (r *ReconciliatorListenerRecorder) UpdateRepositorySetExternalUser(dryrun bool, reponame string, githubid string, permission string) {
r.RepositoriesSetExternalUser[githubid] = permission
}
Expand Down Expand Up @@ -685,7 +682,9 @@ func TestReconciliation(t *testing.T) {
}
remote.teams["existing"] = existing
rRepo := GithubRepository{
Name: "myrepo",
Name: "myrepo",
ExternalUsers: map[string]string{},
BoolProperties: map[string]bool{},
}
remote.repos["myrepo"] = &rRepo

Expand Down Expand Up @@ -749,7 +748,9 @@ func TestReconciliation(t *testing.T) {
}
remote.teams["existing"] = existing
rRepo := GithubRepository{
Name: "myrepo",
Name: "myrepo",
ExternalUsers: map[string]string{},
BoolProperties: map[string]bool{},
}
remote.repos["myrepo"] = &rRepo

Expand Down Expand Up @@ -824,7 +825,9 @@ func TestReconciliation(t *testing.T) {
remote.teams["existing"] = existing
remote.teams["reader"] = reader
rRepo := GithubRepository{
Name: "myrepo",
Name: "myrepo",
ExternalUsers: map[string]string{},
BoolProperties: map[string]bool{},
}
remote.repos["myrepo"] = &rRepo

Expand Down Expand Up @@ -898,7 +901,9 @@ func TestReconciliation(t *testing.T) {
remote.teams["existing"] = existing
remote.teams["reader"] = reader
rRepo := GithubRepository{
Name: "myrepo",
Name: "myrepo",
ExternalUsers: map[string]string{},
BoolProperties: map[string]bool{},
}
remote.repos["myrepo"] = &rRepo

Expand Down Expand Up @@ -965,7 +970,9 @@ func TestReconciliation(t *testing.T) {
}
remote.teams["existing"] = existing
rRepo := GithubRepository{
Name: "myrepo",
Name: "myrepo",
ExternalUsers: map[string]string{},
BoolProperties: map[string]bool{},
}
remote.repos["myrepo"] = &rRepo

Expand Down Expand Up @@ -1033,7 +1040,9 @@ func TestReconciliation(t *testing.T) {
}
remote.teams["existing"] = existing
rRepo := GithubRepository{
Name: "myrepo",
Name: "myrepo",
ExternalUsers: map[string]string{},
BoolProperties: map[string]bool{},
}
remote.repos["myrepo"] = &rRepo

Expand Down Expand Up @@ -1101,8 +1110,9 @@ func TestReconciliation(t *testing.T) {
}
remote.teams["existing"] = existing
rRepo := GithubRepository{
Name: "myrepo",
ExternalUsers: make(map[string]string),
Name: "myrepo",
ExternalUsers: make(map[string]string),
BoolProperties: make(map[string]bool),
}
remote.repos["myrepo"] = &rRepo

Expand Down Expand Up @@ -1169,8 +1179,9 @@ func TestReconciliation(t *testing.T) {
}
remote.teams["existing"] = existing
rRepo := GithubRepository{
Name: "myrepo",
ExternalUsers: make(map[string]string),
Name: "myrepo",
ExternalUsers: make(map[string]string),
BoolProperties: make(map[string]bool),
}
rRepo.ExternalUsers["outside1-githubid"] = "WRITE"
remote.repos["myrepo"] = &rRepo
Expand Down Expand Up @@ -1244,8 +1255,9 @@ func TestReconciliation(t *testing.T) {
}
remote.teams["existing"] = existing
rRepo := GithubRepository{
Name: "myrepo",
ExternalUsers: make(map[string]string),
Name: "myrepo",
ExternalUsers: make(map[string]string),
BoolProperties: make(map[string]bool),
}
rRepo.ExternalUsers["outside1-githubid"] = "WRITE"
remote.repos["myrepo"] = &rRepo
Expand Down Expand Up @@ -1325,7 +1337,9 @@ func TestReconciliation(t *testing.T) {
appids: make(map[string]int),
}
removing := &GithubRepository{
Name: "removing",
Name: "removing",
ExternalUsers: map[string]string{},
BoolProperties: map[string]bool{},
}
remote.repos["removing"] = removing

Expand Down Expand Up @@ -1360,7 +1374,9 @@ func TestReconciliation(t *testing.T) {
appids: make(map[string]int),
}
removing := &GithubRepository{
Name: "removing",
Name: "removing",
ExternalUsers: map[string]string{},
BoolProperties: map[string]bool{},
}
remote.repos["removing"] = removing

Expand Down
Loading
Loading