178 lines
4.3 KiB
Go
178 lines
4.3 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
"code.gitea.io/sdk/gitea"
|
|
"github.com/google/go-github/github"
|
|
"github.com/sethvargo/go-envconfig"
|
|
"golang.org/x/oauth2"
|
|
)
|
|
|
|
const (
|
|
DefaultGiteaUrl = "https://git.ishanjain.me"
|
|
)
|
|
|
|
// Sync every 1 hour 01 minutes
|
|
const DefaultMirrorInterval = "1h01m0s"
|
|
|
|
type Config struct {
|
|
GithubUser string `env:"GITHUB_USER,required"`
|
|
GithubToken string `env:"GITHUB_TOKEN,required"`
|
|
GiteaToken string `env:"GITEA_TOKEN,required"`
|
|
GiteaUser string `env:"GITEA_USER,required"`
|
|
GiteaUrl string `env:"GITEA_URL"`
|
|
}
|
|
|
|
func readConfig() Config {
|
|
ctx := context.Background()
|
|
config := Config{}
|
|
|
|
err := envconfig.Process(ctx, &config)
|
|
if err != nil {
|
|
log.Panicf("error in reading env var: %v", err.Error())
|
|
}
|
|
|
|
if config.GiteaUrl == "" {
|
|
config.GiteaUrl = DefaultGiteaUrl
|
|
}
|
|
return config
|
|
}
|
|
|
|
func main() {
|
|
config := readConfig()
|
|
|
|
// Github API
|
|
ctx := context.Background()
|
|
ts := oauth2.StaticTokenSource(&oauth2.Token{AccessToken: config.GithubToken})
|
|
oclient := oauth2.NewClient(ctx, ts)
|
|
ghClient := github.NewClient(oclient)
|
|
|
|
giteaClient, err := gitea.NewClient(config.GiteaUrl, gitea.SetBasicAuth(config.GiteaUser, config.GiteaToken))
|
|
if err != nil {
|
|
log.Errorf("error in creating client: %v", err.Error())
|
|
}
|
|
|
|
log.Infoln("fetching a list of repositories on Gitea")
|
|
giteaRepos := listGiteaRepositories(config, giteaClient)
|
|
|
|
log.WithFields(log.Fields{
|
|
"gitea_repo_count": len(giteaRepos),
|
|
}).Infoln("fetched a list of repositories on gitea")
|
|
|
|
// For each repo, Create a a repository on Github with the same visiblity settings
|
|
// Setup synchronisation operation with the github repo
|
|
|
|
for _, repo := range giteaRepos {
|
|
log.WithFields(log.Fields{
|
|
"name": repo.Name,
|
|
"org": repo.Owner.UserName,
|
|
"private": repo.Private,
|
|
}).Infoln("configuring repo")
|
|
|
|
repoCreated := setupRepo(config, repo, ghClient)
|
|
|
|
if repoCreated {
|
|
setupMirror(config, repo, giteaClient)
|
|
}
|
|
}
|
|
}
|
|
|
|
func setupMirror(config Config, repo *gitea.Repository, client *gitea.Client) {
|
|
|
|
client.PushMirrors(repo.Owner.UserName, repo.Name, gitea.CreatePushMirrorOption{
|
|
Interval: DefaultMirrorInterval,
|
|
RemoteAddress: fmt.Sprintf("https://github.com/%s/%s", config.GithubUser, repo.Name),
|
|
RemotePassword: config.GithubToken,
|
|
RemoteUsername: config.GithubUser,
|
|
SyncONCommit: true,
|
|
})
|
|
|
|
}
|
|
|
|
func setupRepo(config Config, repo *gitea.Repository, client *github.Client) bool {
|
|
if repo.OriginalURL != "" {
|
|
return false
|
|
}
|
|
|
|
if githubExists(client, config.GithubUser, repo.Name) {
|
|
// Create repository if it doesn't exist already
|
|
_, _, err := client.Repositories.Create(context.Background(), "", &github.Repository{
|
|
Name: &repo.Name,
|
|
Private: &repo.Private,
|
|
Description: &repo.Description,
|
|
HasWiki: &repo.HasWiki,
|
|
HasProjects: &repo.HasProjects,
|
|
})
|
|
if err != nil {
|
|
log.WithFields(log.Fields{
|
|
"name": repo.Name,
|
|
"org": repo.Owner.UserName,
|
|
"private": repo.Private,
|
|
"error": err.Error(),
|
|
}).Errorln("error in creating repository")
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
// Copy description, private state and other parameters if it exists
|
|
_, _, err := client.Repositories.Edit(context.Background(), config.GithubUser, repo.Name, &github.Repository{
|
|
Private: &repo.Private,
|
|
Description: &repo.Description,
|
|
HasWiki: &repo.HasWiki,
|
|
HasProjects: &repo.HasProjects,
|
|
})
|
|
if err != nil {
|
|
log.WithFields(log.Fields{
|
|
"name": repo.Name,
|
|
"org": repo.Owner.UserName,
|
|
"private": repo.Private,
|
|
"error": err.Error(),
|
|
}).Errorln("error in updating repository")
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
func githubExists(client *github.Client, owner, repo string) bool {
|
|
|
|
_, _, err := client.Repositories.Get(context.Background(), owner, repo)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
return true
|
|
}
|
|
|
|
func listGiteaRepositories(config Config, client *gitea.Client) []*gitea.Repository {
|
|
page := 1
|
|
output := []*gitea.Repository{}
|
|
|
|
for {
|
|
|
|
repos, _, err := client.ListUserRepos(config.GiteaUser, gitea.ListReposOptions{
|
|
ListOptions: gitea.ListOptions{
|
|
Page: page,
|
|
PageSize: 20,
|
|
},
|
|
})
|
|
if err != nil {
|
|
log.Errorf("error in listing repositories: %v", err.Error())
|
|
break
|
|
}
|
|
|
|
if len(repos) == 0 {
|
|
break
|
|
}
|
|
|
|
output = append(output, repos...)
|
|
page += 1
|
|
}
|
|
|
|
return output
|
|
}
|