Skip to content

Commit

Permalink
archive on delete
Browse files Browse the repository at this point in the history
  • Loading branch information
nzin committed Oct 9, 2024
1 parent cd0e8ec commit ecaa015
Show file tree
Hide file tree
Showing 7 changed files with 221 additions and 42 deletions.
1 change: 1 addition & 0 deletions docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ rulesets:
ruleset: default
max_changesets: 50 # protection measure: how many changes Goliac can do at once before considering that suspicious
archive_on_delete: true # dont delete directly repository, but archive them first
destructive_operations:
repositories: false # can Goliac remove repositories not listed in this repository
Expand Down
2 changes: 2 additions & 0 deletions internal/config/repo_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type RepositoryConfig struct {
Plugin string `yaml:"plugin"`
Path string `yaml:"path"`
}
ArchiveOnDelete bool `yaml:"archive_on_delete"`
DestructiveOperations struct {
AllowDestructiveRepositories bool `yaml:"repositories"`
AllowDestructiveTeams bool `yaml:"teams"`
Expand All @@ -34,6 +35,7 @@ func (rc *RepositoryConfig) UnmarshalYAML(value *yaml.Node) error {
x.MaxChangesets = 50
x.GithubConcurrentThreads = 4
x.UserSync.Plugin = "noop"
x.ArchiveOnDelete = true

if err := value.Decode(x); err != nil {
return err
Expand Down
43 changes: 30 additions & 13 deletions internal/engine/goliac_reconciliator.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const (
* GoliacReconciliator is here to sync the local state to the remote state
*/
type GoliacReconciliator interface {
Reconciliate(ctx context.Context, local GoliacLocal, remote GoliacRemote, teamreponame string, dryrun bool) error
Reconciliate(ctx context.Context, local GoliacLocal, remote GoliacRemote, teamreponame string, dryrun bool, reposToArchive map[string]*GithubRepoComparable) error
}

type GoliacReconciliatorImpl struct {
Expand All @@ -37,7 +37,7 @@ func NewGoliacReconciliatorImpl(executor ReconciliatorExecutor, repoconfig *conf
}
}

func (r *GoliacReconciliatorImpl) Reconciliate(ctx context.Context, local GoliacLocal, remote GoliacRemote, teamsreponame string, dryrun bool) error {
func (r *GoliacReconciliatorImpl) Reconciliate(ctx context.Context, local GoliacLocal, remote GoliacRemote, teamsreponame string, dryrun bool, reposToArchive map[string]*GithubRepoComparable) error {
rremote := NewMutableGoliacRemoteImpl(remote)
r.Begin(ctx, dryrun)
err := r.reconciliateUsers(ctx, local, rremote, dryrun)
Expand All @@ -52,7 +52,7 @@ func (r *GoliacReconciliatorImpl) Reconciliate(ctx context.Context, local Goliac
return err
}

err = r.reconciliateRepositories(ctx, local, rremote, teamsreponame, dryrun)
err = r.reconciliateRepositories(ctx, local, rremote, teamsreponame, dryrun, reposToArchive)
if err != nil {
r.Rollback(ctx, dryrun, err)
return err
Expand Down Expand Up @@ -208,8 +208,9 @@ type GithubRepoComparable struct {

/*
* This function sync repositories and team's repositories permissions
* It returns the list of deleted repos that must not be deleted but archived
*/
func (r *GoliacReconciliatorImpl) reconciliateRepositories(ctx context.Context, local GoliacLocal, remote *MutableGoliacRemoteImpl, teamsreponame string, dryrun bool) error {
func (r *GoliacReconciliatorImpl) reconciliateRepositories(ctx context.Context, local GoliacLocal, remote *MutableGoliacRemoteImpl, teamsreponame string, dryrun bool, toArchive map[string]*GithubRepoComparable) error {
ghRepos := remote.Repositories()
rRepos := make(map[string]*GithubRepoComparable)
for k, v := range ghRepos {
Expand Down Expand Up @@ -327,15 +328,6 @@ func (r *GoliacReconciliatorImpl) reconciliateRepositories(ctx context.Context,
return true
}

onAdded := func(reponame string, lRepo *GithubRepoComparable, rRepo *GithubRepoComparable) {
// CREATE repository
r.CreateRepository(ctx, dryrun, remote, reponame, reponame, lRepo.Writers, lRepo.Readers, lRepo.IsPublic)
}

onRemoved := func(reponame string, lRepo *GithubRepoComparable, rRepo *GithubRepoComparable) {
r.DeleteRepository(ctx, dryrun, remote, reponame)
}

onChanged := func(reponame string, lRepo *GithubRepoComparable, rRepo *GithubRepoComparable) {
// reconciliate repositories public/private
if lRepo.IsPublic != rRepo.IsPublic {
Expand Down Expand Up @@ -410,6 +402,31 @@ func (r *GoliacReconciliatorImpl) reconciliateRepositories(ctx context.Context,

}

onAdded := func(reponame string, lRepo *GithubRepoComparable, rRepo *GithubRepoComparable) {
// CREATE repository

// 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)
onChanged(reponame, aRepo, rRepo)
} else {
r.CreateRepository(ctx, dryrun, remote, reponame, reponame, lRepo.Writers, lRepo.Readers, lRepo.IsPublic)
}
}

onRemoved := func(reponame string, lRepo *GithubRepoComparable, rRepo *GithubRepoComparable) {
// if the repository is not archived and we want to archive on delete...
if !rRepo.IsArchived && r.repoconfig.ArchiveOnDelete {
r.UpdateRepositoryUpdateArchived(ctx, dryrun, remote, reponame, true)
toArchive[reponame] = rRepo
} else {
if _, ok := toArchive[reponame]; !ok {
r.DeleteRepository(ctx, dryrun, remote, reponame)
}
}
}

CompareEntities(lRepos, rRepos, compareRepos, onAdded, onRemoved, onChanged)

return nil
Expand Down
Loading

0 comments on commit ecaa015

Please sign in to comment.