A tool to migrate GitHub Repositories to Gitea including all issues
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
gitea-github-migrator/cmd/migrate.go

147 lines
3.5 KiB

package cmd
import (
"code.gitea.io/sdk/gitea"
"context"
"fmt"
"git.jonasfranz.software/JonasFranzDEV/gitea-github-migrator/migrations"
"github.com/google/go-github/github"
"github.com/urfave/cli"
"golang.org/x/oauth2"
"strings"
)
var migrateFlags = []cli.Flag{
cli.IntFlag{
Name: "owner",
Usage: "Owner ID",
EnvVar: "OWNER_ID",
Value: 0,
},
cli.StringFlag{
Name: "token",
Usage: "Gitea Token",
EnvVar: "GITEA_TOKEN",
},
cli.StringFlag{
Name: "gh-token",
Usage: "GitHub Token (optional)",
EnvVar: "GITHUB_TOKEN",
},
cli.StringFlag{
Name: "url",
Usage: "Gitea URL",
EnvVar: "GITEA_URL",
},
cli.BoolFlag{
Name: "private",
Usage: "should new repository be private",
EnvVar: "GITEA_PRIVATE",
},
cli.BoolFlag{
Name: "only-repo",
Usage: "skip issues etc. and only migrate repo",
EnvVar: "ONLY_REPO",
},
}
var CmdMigrate = cli.Command{
Name: "migrate",
Usage: "migrates a github to a gitea repository",
Action: runMigrate,
Flags: append(migrateFlags,
cli.StringFlag{
Name: "gh-repo",
Usage: "GitHub Repository",
Value: "username/reponame",
EnvVar: "GH_REPOSITORY",
},
),
}
func runMigrate(ctx *cli.Context) error {
m := &migrations.Migratory{
Client: gitea.NewClient(ctx.String("url"), ctx.String("token")),
Private: ctx.Bool("private"),
NewOwnerID: ctx.Int("owner"),
}
c := context.Background()
var gc *github.Client
if ctx.IsSet("gh-token") {
ts := oauth2.StaticTokenSource(
&oauth2.Token{AccessToken: ctx.String("gh-token")},
)
tc := oauth2.NewClient(c, ts)
gc = github.NewClient(tc)
} else {
gc = github.NewClient(nil)
}
username := strings.Split(ctx.String("gh-repo"), "/")[0]
repo := strings.Split(ctx.String("gh-repo"), "/")[1]
return migrate(gc, c, m, username, repo, ctx.Bool("only-repo"))
}
func migrate(gc *github.Client, c context.Context, m *migrations.Migratory, username, repo string, onlyRepo bool) error {
fmt.Printf("Fetching repository %s/%s...\n", username, repo)
gr, _, err := gc.Repositories.Get(c, username, repo)
if err != nil {
return err
}
fmt.Printf("Migrating repository %s/%s...\n", username, repo)
if mr, err := m.Repository(gr); err != nil {
return err
} else {
fmt.Printf("Repository migrated to %s/%s\n", mr.Owner.UserName, mr.Name)
}
if onlyRepo {
return nil
}
fmt.Println("Fetching issues...")
opt := &github.IssueListByRepoOptions{
Sort: "created",
Direction: "asc",
State: "all",
ListOptions: github.ListOptions{
PerPage: 100,
},
}
var allIssues = make([]*github.Issue, 0)
for {
issues, resp, err := gc.Issues.ListByRepo(c, username, repo, opt)
if err != nil {
return err
}
allIssues = append(allIssues, issues...)
if resp.NextPage == 0 {
break
}
opt.Page = resp.NextPage
}
fmt.Println("Migrating issues...")
//bar := p.AddBar(int64(len(issues)))
for _, gi := range allIssues {
fmt.Printf("Migrating #%d...\n", *gi.Number)
issue, err := m.Issue(gi)
if err != nil {
return fmt.Errorf("migrating issue[id: %d]: %v", *gi.ID, err)
}
comments, _, err := gc.Issues.ListComments(c, username, repo, gi.GetNumber(), nil)
if err != nil {
return fmt.Errorf("fetching issue[id: %d] comments: %v", *gi.ID, err)
}
for _, gc := range comments {
fmt.Printf("-> %d...", gc.ID)
if _, err := m.IssueComment(issue, gc); err != nil {
return fmt.Errorf("migrating issue comment [issue: %d, comment: %d]: %v", *gi.ID, gc.ID, err)
}
fmt.Print("Done!\n")
}
fmt.Printf("Migrated #%d...\n", *gi.Number)
//bar.Increment()
}
return nil
}