From 77024fb0a5bf972663a02dca4e525960af9930f6 Mon Sep 17 00:00:00 2001 From: Andreas Wachter Date: Fri, 29 Sep 2023 12:26:03 +0200 Subject: [PATCH] implemented backup to organization (#169) * implemented backup to organization * go mod tidy * update lint --- .github/workflows/validate-lint.yml | 2 +- conf.example.yml | 2 ++ github/github.go | 38 ++++++++++++++++++++----- go.sum | 2 -- onedev/onedev.go | 20 +++++++++---- types/types.go | 44 +++++++++++++++++------------ 6 files changed, 74 insertions(+), 34 deletions(-) diff --git a/.github/workflows/validate-lint.yml b/.github/workflows/validate-lint.yml index f95431b..a2aa9d1 100644 --- a/.github/workflows/validate-lint.yml +++ b/.github/workflows/validate-lint.yml @@ -7,7 +7,7 @@ on: env: GO_VERSION: 1.17 - GOLANGCI_LINT_VERSION: v1.48.0 + GOLANGCI_LINT_VERSION: v1.54.2 jobs: diff --git a/conf.example.yml b/conf.example.yml index 6fed981..002ca13 100644 --- a/conf.example.yml +++ b/conf.example.yml @@ -217,12 +217,14 @@ destination: github: - token: some-token # token_file: token.txt # alternatively, specify token in a file + organization: whatever # name of the organization to want to backup to visibility: repositories: private # private, public, default: private onedev: - token: some-token # token_file: token.txt # alternatively, specify token in a file url: http(s)://url-to-onedev + organization: whatever # name of the parent project you want to backup to sourcehut: - token: some-token # as of now only the legacy api works, use the legacy token # token_file: token.txt # alternatively, specify token in a file diff --git a/github/github.go b/github/github.go index 5ea652b..7d3813d 100644 --- a/github/github.go +++ b/github/github.go @@ -336,18 +336,42 @@ func GetOrCreate(destination types.GenRepo, repo types.Repo) (string, error) { client := github.NewClient(tc) - user, _, err := client.Users.Get(context.TODO(), "") - if err != nil { - return "", err + dest := types.GithubDestination{} + login := "" + if destination.Organization == "" { + user, _, err := client.Users.Get(context.TODO(), "") + if err != nil { + return "", err + } + dest.User = user + login = *user.Login + } else { + organization, _, err := client.Organizations.Get(context.TODO(), destination.Organization) + if err != nil { + return "", err + } + dest.Organization = organization + login = *organization.Login } - r, _, err := client.Repositories.Get(context.TODO(), *user.Login, repo.Name) + + r, _, err := client.Repositories.Get(context.TODO(), login, repo.Name) if err != nil { if !strings.Contains(err.Error(), "404 Not Found") { return "", err } - r, _, err = client.Repositories.Create(context.TODO(), "", &github.Repository{Name: github.String(repo.Name), Private: github.Bool(destination.Visibility.Repositories == "private"), Visibility: github.String(destination.Visibility.Repositories), Owner: user}) - if err != nil { - return "", err + if destination.Organization == "" { + r, _, err = client.Repositories.Create(context.TODO(), "", &github.Repository{Name: github.String(repo.Name), Private: github.Bool(destination.Visibility.Repositories == "private"), Visibility: github.String(destination.Visibility.Repositories), Owner: dest.User}) + if err != nil { + return "", err + } + } else { + if destination.Visibility.Repositories == "" { + destination.Visibility.Repositories = "private" + } + r, _, err = client.Repositories.Create(context.TODO(), *dest.Organization.Login, &github.Repository{Name: github.String(repo.Name), Private: github.Bool(destination.Visibility.Repositories == "private"), Visibility: github.String(destination.Visibility.Repositories), Organization: dest.Organization}) + if err != nil { + return "", err + } } } diff --git a/go.sum b/go.sum index 0ae20ff..2c6b926 100644 --- a/go.sum +++ b/go.sum @@ -79,8 +79,6 @@ github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtM github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cooperspencer/onedev v0.0.0-20230220110259-c2789266f8ed h1:WKEYtw1Qy6Idi0Cy0jMWdWghd8wyYrrTkS0fTkD0ZuI= -github.com/cooperspencer/onedev v0.0.0-20230220110259-c2789266f8ed/go.mod h1:6xF8ZlcuNkJoGf2VnyZZBkQAOGLu2zKOxKqEzPR2DJs= github.com/cooperspencer/onedev v0.0.0-20230615161456-95860e5aae3e h1:8ajPtPxbNEwLP9hyDb190ojgc2ZUm29k9JxZzoiyf3Q= github.com/cooperspencer/onedev v0.0.0-20230615161456-95860e5aae3e/go.mod h1:6xF8ZlcuNkJoGf2VnyZZBkQAOGLu2zKOxKqEzPR2DJs= github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= diff --git a/onedev/onedev.go b/onedev/onedev.go index ac8b79f..27161c9 100644 --- a/onedev/onedev.go +++ b/onedev/onedev.go @@ -240,13 +240,20 @@ func GetOrCreate(destination types.GenRepo, repo types.Repo) (string, error) { } } - user, _, err := client.GetMe() - if err != nil { - return "", err + dest := "" + + if destination.Organization == "" { + user, _, err := client.GetMe() + if err != nil { + return "", err + } + dest = user.Name + } else { + dest = destination.Organization } query := onedev.ProjectQueryOptions{ - Query: fmt.Sprintf("\"Name\" is \"%s\" and children of \"%s\"", repo.Name, user.Name), + Query: fmt.Sprintf("\"Name\" is \"%s\" and children of \"%s\"", repo.Name, dest), Offset: 0, Count: 100, } @@ -266,7 +273,7 @@ func GetOrCreate(destination types.GenRepo, repo types.Repo) (string, error) { } } - query.Query = fmt.Sprintf("\"Name\" is \"%s\"", user.Name) + query.Query = fmt.Sprintf("\"Name\" is \"%s\"", dest) parentid := 0 parents, _, err := client.GetProjects(&query) @@ -274,8 +281,9 @@ func GetOrCreate(destination types.GenRepo, repo types.Repo) (string, error) { return "", err } for _, parent := range parents { - if parent.Name == user.Name { + if parent.Name == dest { parentid = parent.ID + break } } diff --git a/types/types.go b/types/types.go index cf15b69..90684bb 100644 --- a/types/types.go +++ b/types/types.go @@ -14,6 +14,7 @@ import ( "github.com/go-git/go-git/v5/plumbing/transport" "github.com/go-git/go-git/v5/plumbing/transport/http" "github.com/go-git/go-git/v5/plumbing/transport/ssh" + "github.com/google/go-github/v41/github" "github.com/gookit/color" "github.com/robfig/cron/v3" "github.com/rs/zerolog/log" @@ -227,24 +228,25 @@ func (source Source) Count() int { // GenRepo Generell Repo. type GenRepo struct { - Token string `yaml:"token"` - TokenFile string `yaml:"token_file"` - User string `yaml:"user"` - SSH bool `yaml:"ssh"` - SSHKey string `yaml:"sshkey"` - Username string `yaml:"username"` - Password string `yaml:"password"` - URL string `yaml:"url"` - Exclude []string `yaml:"exclude"` - ExcludeOrgs []string `yaml:"excludeorgs"` - Include []string `yaml:"include"` - IncludeOrgs []string `yaml:"includeorgs"` - Wiki bool `yaml:"wiki"` - Starred bool `yaml:"starred"` - CreateOrg bool `yaml:"createorg"` - Visibility Visibility `yaml:"visibility"` - Filter Filter `yaml:"filter"` - Contributed bool `yaml:"contributed"` + Token string `yaml:"token"` + TokenFile string `yaml:"token_file"` + User string `yaml:"user"` + Organization string `yaml:"organization"` + SSH bool `yaml:"ssh"` + SSHKey string `yaml:"sshkey"` + Username string `yaml:"username"` + Password string `yaml:"password"` + URL string `yaml:"url"` + Exclude []string `yaml:"exclude"` + ExcludeOrgs []string `yaml:"excludeorgs"` + Include []string `yaml:"include"` + IncludeOrgs []string `yaml:"includeorgs"` + Wiki bool `yaml:"wiki"` + Starred bool `yaml:"starred"` + CreateOrg bool `yaml:"createorg"` + Visibility Visibility `yaml:"visibility"` + Filter Filter `yaml:"filter"` + Contributed bool `yaml:"contributed"` } // Visibility struct @@ -389,6 +391,12 @@ type Site struct { Port int } +// GithubDestination TODO +type GithubDestination struct { + User *github.User + Organization *github.Organization +} + // GetHost TODO. func GetHost(url string) string { if strings.Contains(url, "http://") {