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

archive on delete #64

Merged
merged 1 commit into from
Oct 9, 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
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
Loading