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.
 
 
 

118 lines
3.3 KiB

  1. package migrations
  2. import (
  3. "fmt"
  4. "code.gitea.io/sdk/gitea"
  5. "github.com/google/go-github/github"
  6. )
  7. // Issue migrates a GitHub Issue to a Gitea Issue
  8. func (m *Migratory) Issue(gi *github.Issue) (*gitea.Issue, error) {
  9. if m.migratedMilestones == nil {
  10. m.migratedMilestones = make(map[int64]int64)
  11. }
  12. if m.migratedLabels == nil {
  13. m.migratedLabels = make(map[int64]int64)
  14. }
  15. // Migrate milestone if it is not already migrated
  16. milestone := int64(0)
  17. if gi.Milestone != nil {
  18. // Lookup if milestone is already migrated
  19. if migratedMilestone, ok := m.migratedMilestones[*gi.Milestone.ID]; ok {
  20. milestone = migratedMilestone
  21. } else if ms, err := m.Milestone(gi.Milestone); err != nil {
  22. return nil, err
  23. } else {
  24. milestone = ms.ID
  25. }
  26. }
  27. // Migrate labels
  28. labels, err := m.labels(gi.Labels)
  29. if err != nil {
  30. return nil, err
  31. }
  32. return m.Client.CreateIssue(m.repository.Owner.UserName, m.repository.Name,
  33. gitea.CreateIssueOption{
  34. Title: gi.GetTitle(),
  35. Body: fmt.Sprintf("Author: @%s Posted at: %s\n\n\n%s", *gi.User.Login, gi.GetCreatedAt().Format("02.01.2006 15:04"), gi.GetBody()),
  36. Closed: *gi.State == "closed",
  37. Milestone: milestone,
  38. Labels: labels,
  39. })
  40. }
  41. func (m *Migratory) labels(gls []github.Label) (results []int64, err error) {
  42. for _, gl := range gls {
  43. if migratedLabel, ok := m.migratedLabels[*gl.ID]; ok {
  44. results = append(results, migratedLabel)
  45. } else {
  46. var newLabel *gitea.Label
  47. if newLabel, err = m.Label(&gl); err != nil {
  48. return nil, err
  49. }
  50. m.migratedLabels[*gl.ID] = newLabel.ID
  51. results = append(results, newLabel.ID)
  52. }
  53. }
  54. return
  55. }
  56. // Label migrates a GitHub Label to a Gitea Label without caching its id
  57. func (m *Migratory) Label(gl *github.Label) (*gitea.Label, error) {
  58. return m.Client.CreateLabel(m.repository.Owner.UserName, m.repository.Name,
  59. gitea.CreateLabelOption{
  60. Name: gl.GetName(),
  61. Color: fmt.Sprintf("#%s", gl.GetColor()),
  62. })
  63. }
  64. // Milestone migrates a GitHub Milesteon to a Gitea Milestone and caches its id
  65. func (m *Migratory) Milestone(gm *github.Milestone) (*gitea.Milestone, error) {
  66. ms, err := m.Client.CreateMilestone(m.repository.Owner.UserName, m.repository.Name,
  67. gitea.CreateMilestoneOption{
  68. Title: gm.GetTitle(),
  69. Description: gm.GetDescription(),
  70. Deadline: gm.DueOn,
  71. })
  72. if err != nil {
  73. return nil, err
  74. }
  75. m.migratedMilestones[*gm.ID] = ms.ID
  76. if gm.State != nil && *gm.State != "open" {
  77. return m.Client.EditMilestone(m.repository.Owner.UserName, m.repository.Name,
  78. ms.ID, gitea.EditMilestoneOption{
  79. State: githubStateToGiteaState(gm.State),
  80. })
  81. }
  82. return ms, err
  83. }
  84. func githubStateToGiteaState(ghstate *string) *string {
  85. if ghstate == nil {
  86. return ghstate
  87. }
  88. switch *ghstate {
  89. case "open":
  90. fallthrough
  91. case "closed":
  92. return ghstate
  93. case "all":
  94. open := "open"
  95. return &open
  96. }
  97. return nil
  98. }
  99. // IssueComment migrates a GitHub IssueComment to a Gitea Comment
  100. func (m *Migratory) IssueComment(issue *gitea.Issue, gic *github.IssueComment) (*gitea.Comment, error) {
  101. return m.Client.CreateIssueComment(m.repository.Owner.UserName,
  102. m.repository.Name,
  103. issue.Index,
  104. gitea.CreateIssueCommentOption{
  105. Body: fmt.Sprintf("Author: @%s Posted at: %s\n\n\n%s", *gic.User.Login, gic.GetCreatedAt().Format("02.01.2006 15:04"), gic.GetBody()),
  106. })
  107. }