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.

134 lines
3.3 KiB

  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 repository
  5. import (
  6. "fmt"
  7. "strings"
  8. "time"
  9. "code.gitea.io/gitea/models"
  10. "code.gitea.io/gitea/modules/git"
  11. "code.gitea.io/gitea/modules/timeutil"
  12. )
  13. // PushUpdateAddDeleteTags updates a number of added and delete tags
  14. func PushUpdateAddDeleteTags(repo *models.Repository, gitRepo *git.Repository, addTags, delTags []string) error {
  15. return models.WithTx(func(ctx models.DBContext) error {
  16. if err := models.PushUpdateDeleteTagsContext(ctx, repo, delTags); err != nil {
  17. return err
  18. }
  19. return pushUpdateAddTags(ctx, repo, gitRepo, addTags)
  20. })
  21. }
  22. // pushUpdateAddTags updates a number of add tags
  23. func pushUpdateAddTags(ctx models.DBContext, repo *models.Repository, gitRepo *git.Repository, tags []string) error {
  24. if len(tags) == 0 {
  25. return nil
  26. }
  27. lowerTags := make([]string, 0, len(tags))
  28. for _, tag := range tags {
  29. lowerTags = append(lowerTags, strings.ToLower(tag))
  30. }
  31. releases, err := models.GetReleasesByRepoIDAndNames(ctx, repo.ID, lowerTags)
  32. if err != nil {
  33. return fmt.Errorf("GetReleasesByRepoIDAndNames: %v", err)
  34. }
  35. relMap := make(map[string]*models.Release)
  36. for _, rel := range releases {
  37. relMap[rel.LowerTagName] = rel
  38. }
  39. newReleases := make([]*models.Release, 0, len(lowerTags)-len(relMap))
  40. emailToUser := make(map[string]*models.User)
  41. for i, lowerTag := range lowerTags {
  42. tag, err := gitRepo.GetTag(tags[i])
  43. if err != nil {
  44. return fmt.Errorf("GetTag: %v", err)
  45. }
  46. commit, err := tag.Commit()
  47. if err != nil {
  48. return fmt.Errorf("Commit: %v", err)
  49. }
  50. sig := tag.Tagger
  51. if sig == nil {
  52. sig = commit.Author
  53. }
  54. if sig == nil {
  55. sig = commit.Committer
  56. }
  57. var author *models.User
  58. var createdAt = time.Unix(1, 0)
  59. if sig != nil {
  60. var ok bool
  61. author, ok = emailToUser[sig.Email]
  62. if !ok {
  63. author, err = models.GetUserByEmailContext(ctx, sig.Email)
  64. if err != nil && !models.IsErrUserNotExist(err) {
  65. return fmt.Errorf("GetUserByEmail: %v", err)
  66. }
  67. if author != nil {
  68. emailToUser[sig.Email] = author
  69. }
  70. }
  71. createdAt = sig.When
  72. }
  73. commitsCount, err := commit.CommitsCount()
  74. if err != nil {
  75. return fmt.Errorf("CommitsCount: %v", err)
  76. }
  77. rel, has := relMap[lowerTag]
  78. if !has {
  79. rel = &models.Release{
  80. RepoID: repo.ID,
  81. Title: "",
  82. TagName: tags[i],
  83. LowerTagName: lowerTag,
  84. Target: "",
  85. Sha1: commit.ID.String(),
  86. NumCommits: commitsCount,
  87. Note: "",
  88. IsDraft: false,
  89. IsPrerelease: false,
  90. IsTag: true,
  91. CreatedUnix: timeutil.TimeStamp(createdAt.Unix()),
  92. }
  93. if author != nil {
  94. rel.PublisherID = author.ID
  95. }
  96. newReleases = append(newReleases, rel)
  97. } else {
  98. rel.Sha1 = commit.ID.String()
  99. rel.CreatedUnix = timeutil.TimeStamp(createdAt.Unix())
  100. rel.NumCommits = commitsCount
  101. rel.IsDraft = false
  102. if rel.IsTag && author != nil {
  103. rel.PublisherID = author.ID
  104. }
  105. if err = models.UpdateRelease(ctx, rel); err != nil {
  106. return fmt.Errorf("Update: %v", err)
  107. }
  108. }
  109. }
  110. if len(newReleases) > 0 {
  111. if err = models.InsertReleasesContext(ctx, newReleases); err != nil {
  112. return fmt.Errorf("Insert: %v", err)
  113. }
  114. }
  115. return nil
  116. }