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.

update.go 6.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. // Copyright 2014 The Gogs 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 models
  5. import (
  6. "fmt"
  7. "strings"
  8. "time"
  9. "code.gitea.io/gitea/modules/git"
  10. "code.gitea.io/gitea/modules/timeutil"
  11. )
  12. // env keys for git hooks need
  13. const (
  14. EnvRepoName = "GITEA_REPO_NAME"
  15. EnvRepoUsername = "GITEA_REPO_USER_NAME"
  16. EnvRepoIsWiki = "GITEA_REPO_IS_WIKI"
  17. EnvPusherName = "GITEA_PUSHER_NAME"
  18. EnvPusherEmail = "GITEA_PUSHER_EMAIL"
  19. EnvPusherID = "GITEA_PUSHER_ID"
  20. EnvKeyID = "GITEA_KEY_ID"
  21. EnvIsDeployKey = "GITEA_IS_DEPLOY_KEY"
  22. EnvIsInternal = "GITEA_INTERNAL_PUSH"
  23. )
  24. // PushUpdateAddDeleteTags updates a number of added and delete tags
  25. func PushUpdateAddDeleteTags(repo *Repository, gitRepo *git.Repository, addTags, delTags []string) error {
  26. sess := x.NewSession()
  27. defer sess.Close()
  28. if err := sess.Begin(); err != nil {
  29. return fmt.Errorf("Unable to begin sess in PushUpdateDeleteTags: %v", err)
  30. }
  31. if err := pushUpdateDeleteTags(sess, repo, delTags); err != nil {
  32. return err
  33. }
  34. if err := pushUpdateAddTags(sess, repo, gitRepo, addTags); err != nil {
  35. return err
  36. }
  37. return sess.Commit()
  38. }
  39. // PushUpdateDeleteTags updates a number of delete tags
  40. func PushUpdateDeleteTags(repo *Repository, tags []string) error {
  41. sess := x.NewSession()
  42. defer sess.Close()
  43. if err := sess.Begin(); err != nil {
  44. return fmt.Errorf("Unable to begin sess in PushUpdateDeleteTags: %v", err)
  45. }
  46. if err := pushUpdateDeleteTags(sess, repo, tags); err != nil {
  47. return err
  48. }
  49. return sess.Commit()
  50. }
  51. func pushUpdateDeleteTags(e Engine, repo *Repository, tags []string) error {
  52. if len(tags) == 0 {
  53. return nil
  54. }
  55. lowerTags := make([]string, 0, len(tags))
  56. for _, tag := range tags {
  57. lowerTags = append(lowerTags, strings.ToLower(tag))
  58. }
  59. if _, err := e.
  60. Where("repo_id = ? AND is_tag = ?", repo.ID, true).
  61. In("lower_tag_name", lowerTags).
  62. Delete(new(Release)); err != nil {
  63. return fmt.Errorf("Delete: %v", err)
  64. }
  65. if _, err := e.
  66. Where("repo_id = ? AND is_tag = ?", repo.ID, false).
  67. In("lower_tag_name", lowerTags).
  68. Cols("is_draft", "num_commits", "sha1").
  69. Update(&Release{
  70. IsDraft: true,
  71. }); err != nil {
  72. return fmt.Errorf("Update: %v", err)
  73. }
  74. return nil
  75. }
  76. // PushUpdateDeleteTag must be called for any push actions to delete tag
  77. func PushUpdateDeleteTag(repo *Repository, tagName string) error {
  78. rel, err := GetRelease(repo.ID, tagName)
  79. if err != nil {
  80. if IsErrReleaseNotExist(err) {
  81. return nil
  82. }
  83. return fmt.Errorf("GetRelease: %v", err)
  84. }
  85. if rel.IsTag {
  86. if _, err = x.ID(rel.ID).Delete(new(Release)); err != nil {
  87. return fmt.Errorf("Delete: %v", err)
  88. }
  89. } else {
  90. rel.IsDraft = true
  91. rel.NumCommits = 0
  92. rel.Sha1 = ""
  93. if _, err = x.ID(rel.ID).AllCols().Update(rel); err != nil {
  94. return fmt.Errorf("Update: %v", err)
  95. }
  96. }
  97. return nil
  98. }
  99. // PushUpdateAddTags updates a number of add tags
  100. func PushUpdateAddTags(repo *Repository, gitRepo *git.Repository, tags []string) error {
  101. sess := x.NewSession()
  102. defer sess.Close()
  103. if err := sess.Begin(); err != nil {
  104. return fmt.Errorf("Unable to begin sess in PushUpdateAddTags: %v", err)
  105. }
  106. if err := pushUpdateAddTags(sess, repo, gitRepo, tags); err != nil {
  107. return err
  108. }
  109. return sess.Commit()
  110. }
  111. func pushUpdateAddTags(e Engine, repo *Repository, gitRepo *git.Repository, tags []string) error {
  112. if len(tags) == 0 {
  113. return nil
  114. }
  115. lowerTags := make([]string, 0, len(tags))
  116. for _, tag := range tags {
  117. lowerTags = append(lowerTags, strings.ToLower(tag))
  118. }
  119. releases := make([]Release, 0, len(tags))
  120. if err := e.Where("repo_id = ?", repo.ID).
  121. In("lower_tag_name", lowerTags).Find(&releases); err != nil {
  122. return fmt.Errorf("GetRelease: %v", err)
  123. }
  124. relMap := make(map[string]*Release)
  125. for _, rel := range releases {
  126. relMap[rel.LowerTagName] = &rel
  127. }
  128. newReleases := make([]*Release, 0, len(lowerTags)-len(relMap))
  129. emailToUser := make(map[string]*User)
  130. for i, lowerTag := range lowerTags {
  131. tag, err := gitRepo.GetTag(tags[i])
  132. if err != nil {
  133. return fmt.Errorf("GetTag: %v", err)
  134. }
  135. commit, err := tag.Commit()
  136. if err != nil {
  137. return fmt.Errorf("Commit: %v", err)
  138. }
  139. sig := tag.Tagger
  140. if sig == nil {
  141. sig = commit.Author
  142. }
  143. if sig == nil {
  144. sig = commit.Committer
  145. }
  146. var author *User
  147. var createdAt = time.Unix(1, 0)
  148. if sig != nil {
  149. var ok bool
  150. author, ok = emailToUser[sig.Email]
  151. if !ok {
  152. author, err = GetUserByEmail(sig.Email)
  153. if err != nil && !IsErrUserNotExist(err) {
  154. return fmt.Errorf("GetUserByEmail: %v", err)
  155. }
  156. }
  157. createdAt = sig.When
  158. }
  159. commitsCount, err := commit.CommitsCount()
  160. if err != nil {
  161. return fmt.Errorf("CommitsCount: %v", err)
  162. }
  163. rel, has := relMap[lowerTag]
  164. if !has {
  165. rel = &Release{
  166. RepoID: repo.ID,
  167. Title: "",
  168. TagName: tags[i],
  169. LowerTagName: lowerTag,
  170. Target: "",
  171. Sha1: commit.ID.String(),
  172. NumCommits: commitsCount,
  173. Note: "",
  174. IsDraft: false,
  175. IsPrerelease: false,
  176. IsTag: true,
  177. CreatedUnix: timeutil.TimeStamp(createdAt.Unix()),
  178. }
  179. if author != nil {
  180. rel.PublisherID = author.ID
  181. }
  182. newReleases = append(newReleases, rel)
  183. } else {
  184. rel.Sha1 = commit.ID.String()
  185. rel.CreatedUnix = timeutil.TimeStamp(createdAt.Unix())
  186. rel.NumCommits = commitsCount
  187. rel.IsDraft = false
  188. if rel.IsTag && author != nil {
  189. rel.PublisherID = author.ID
  190. }
  191. if _, err = e.ID(rel.ID).AllCols().Update(rel); err != nil {
  192. return fmt.Errorf("Update: %v", err)
  193. }
  194. }
  195. }
  196. if len(newReleases) > 0 {
  197. if _, err := e.Insert(newReleases); err != nil {
  198. return fmt.Errorf("Insert: %v", err)
  199. }
  200. }
  201. return nil
  202. }
  203. // SaveOrUpdateTag must be called for any push actions to add tag
  204. func SaveOrUpdateTag(repo *Repository, newRel *Release) error {
  205. rel, err := GetRelease(repo.ID, newRel.TagName)
  206. if err != nil && !IsErrReleaseNotExist(err) {
  207. return fmt.Errorf("GetRelease: %v", err)
  208. }
  209. if rel == nil {
  210. rel = newRel
  211. if _, err = x.Insert(rel); err != nil {
  212. return fmt.Errorf("InsertOne: %v", err)
  213. }
  214. } else {
  215. rel.Sha1 = newRel.Sha1
  216. rel.CreatedUnix = newRel.CreatedUnix
  217. rel.NumCommits = newRel.NumCommits
  218. rel.IsDraft = false
  219. if rel.IsTag && newRel.PublisherID > 0 {
  220. rel.PublisherID = newRel.PublisherID
  221. }
  222. if _, err = x.ID(rel.ID).AllCols().Update(rel); err != nil {
  223. return fmt.Errorf("Update: %v", err)
  224. }
  225. }
  226. return nil
  227. }