You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

v156.go 3.3 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // Copyright 2020 The Gitea Authors. All rights reserved.
  2. // Use of this source code is governed by a MIT-style
  3. // license that can be found in the LICENSE file.
  4. package migrations
  5. import (
  6. "fmt"
  7. "path/filepath"
  8. "strings"
  9. "code.gitea.io/gitea/modules/git"
  10. "code.gitea.io/gitea/modules/log"
  11. "code.gitea.io/gitea/modules/setting"
  12. "xorm.io/xorm"
  13. )
  14. // Copy paste from models/repo.go because we cannot import models package
  15. func repoPath(userName, repoName string) string {
  16. return filepath.Join(userPath(userName), strings.ToLower(repoName)+".git")
  17. }
  18. func userPath(userName string) string {
  19. return filepath.Join(setting.RepoRootPath, strings.ToLower(userName))
  20. }
  21. func fixPublisherIDforTagReleases(x *xorm.Engine) error {
  22. type Release struct {
  23. ID int64
  24. RepoID int64
  25. Sha1 string
  26. TagName string
  27. PublisherID int64
  28. }
  29. type Repository struct {
  30. ID int64
  31. OwnerID int64
  32. OwnerName string
  33. Name string
  34. }
  35. type User struct {
  36. ID int64
  37. Name string
  38. Email string
  39. }
  40. const batchSize = 100
  41. sess := x.NewSession()
  42. defer sess.Close()
  43. var (
  44. repo *Repository
  45. gitRepo *git.Repository
  46. user *User
  47. )
  48. defer func() {
  49. if gitRepo != nil {
  50. gitRepo.Close()
  51. }
  52. }()
  53. for start := 0; ; start += batchSize {
  54. releases := make([]*Release, 0, batchSize)
  55. if err := sess.Begin(); err != nil {
  56. return err
  57. }
  58. if err := sess.Limit(batchSize, start).
  59. Where("publisher_id = 0 OR publisher_id is null").
  60. Asc("repo_id", "id").Where("is_tag=?", true).
  61. Find(&releases); err != nil {
  62. return err
  63. }
  64. if len(releases) == 0 {
  65. break
  66. }
  67. for _, release := range releases {
  68. if repo == nil || repo.ID != release.RepoID {
  69. if gitRepo != nil {
  70. gitRepo.Close()
  71. gitRepo = nil
  72. }
  73. repo = new(Repository)
  74. has, err := sess.ID(release.RepoID).Get(repo)
  75. if err != nil {
  76. return err
  77. } else if !has {
  78. log.Warn("Release[%d] is orphaned and refers to non-existing repository %d", release.ID, release.RepoID)
  79. log.Warn("This release should be deleted")
  80. continue
  81. }
  82. if repo.OwnerName == "" {
  83. // v120.go migration may not have been run correctly - we'll just replicate it here
  84. // because this appears to be a common-ish problem.
  85. if _, err := sess.Exec("UPDATE repository SET owner_name = (SELECT name FROM `user` WHERE `user`.id = repository.owner_id)"); err != nil {
  86. return err
  87. }
  88. if _, err := sess.ID(release.RepoID).Get(repo); err != nil {
  89. return err
  90. }
  91. }
  92. gitRepo, err = git.OpenRepository(repoPath(repo.OwnerName, repo.Name))
  93. if err != nil {
  94. return err
  95. }
  96. }
  97. commit, err := gitRepo.GetTagCommit(release.TagName)
  98. if err != nil {
  99. return fmt.Errorf("GetTagCommit: %v", err)
  100. }
  101. if user == nil || !strings.EqualFold(user.Email, commit.Author.Email) {
  102. user = new(User)
  103. _, err = sess.Where("email=?", commit.Author.Email).Get(user)
  104. if err != nil {
  105. return err
  106. }
  107. user.Email = commit.Author.Email
  108. }
  109. if user.ID <= 0 {
  110. continue
  111. }
  112. release.PublisherID = user.ID
  113. if _, err := sess.ID(release.ID).Cols("publisher_id").Update(release); err != nil {
  114. return err
  115. }
  116. }
  117. if err := sess.Commit(); err != nil {
  118. return err
  119. }
  120. }
  121. return nil
  122. }