Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

status.go 7.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. // Copyright 2017 Gitea. 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 repo
  5. import (
  6. "fmt"
  7. "code.gitea.io/gitea/models"
  8. "code.gitea.io/gitea/modules/context"
  9. "code.gitea.io/gitea/modules/repofiles"
  10. api "code.gitea.io/gitea/modules/structs"
  11. )
  12. // NewCommitStatus creates a new CommitStatus
  13. func NewCommitStatus(ctx *context.APIContext, form api.CreateStatusOption) {
  14. // swagger:operation POST /repos/{owner}/{repo}/statuses/{sha} repository repoCreateStatus
  15. // ---
  16. // summary: Create a commit status
  17. // produces:
  18. // - application/json
  19. // parameters:
  20. // - name: owner
  21. // in: path
  22. // description: owner of the repo
  23. // type: string
  24. // required: true
  25. // - name: repo
  26. // in: path
  27. // description: name of the repo
  28. // type: string
  29. // required: true
  30. // - name: sha
  31. // in: path
  32. // description: sha of the commit
  33. // type: string
  34. // required: true
  35. // - name: body
  36. // in: body
  37. // schema:
  38. // "$ref": "#/definitions/CreateStatusOption"
  39. // responses:
  40. // "200":
  41. // "$ref": "#/responses/StatusList"
  42. sha := ctx.Params("sha")
  43. if len(sha) == 0 {
  44. ctx.Error(400, "sha not given", nil)
  45. return
  46. }
  47. status := &models.CommitStatus{
  48. State: models.CommitStatusState(form.State),
  49. TargetURL: form.TargetURL,
  50. Description: form.Description,
  51. Context: form.Context,
  52. }
  53. if err := repofiles.CreateCommitStatus(ctx.Repo.Repository, ctx.User, sha, status); err != nil {
  54. ctx.Error(500, "CreateCommitStatus", err)
  55. return
  56. }
  57. ctx.JSON(201, status.APIFormat())
  58. }
  59. // GetCommitStatuses returns all statuses for any given commit hash
  60. func GetCommitStatuses(ctx *context.APIContext) {
  61. // swagger:operation GET /repos/{owner}/{repo}/statuses/{sha} repository repoListStatuses
  62. // ---
  63. // summary: Get a commit's statuses
  64. // produces:
  65. // - application/json
  66. // parameters:
  67. // - name: owner
  68. // in: path
  69. // description: owner of the repo
  70. // type: string
  71. // required: true
  72. // - name: repo
  73. // in: path
  74. // description: name of the repo
  75. // type: string
  76. // required: true
  77. // - name: sha
  78. // in: path
  79. // description: sha of the commit
  80. // type: string
  81. // required: true
  82. // - name: page
  83. // in: query
  84. // description: page number of results
  85. // type: integer
  86. // required: false
  87. // - name: sort
  88. // in: query
  89. // description: type of sort
  90. // type: string
  91. // enum: [oldest, recentupdate, leastupdate, leastindex, highestindex]
  92. // required: false
  93. // - name: state
  94. // in: query
  95. // description: type of state
  96. // type: string
  97. // enum: [pending, success, error, failure, warning]
  98. // required: false
  99. // responses:
  100. // "200":
  101. // "$ref": "#/responses/StatusList"
  102. getCommitStatuses(ctx, ctx.Params("sha"))
  103. }
  104. // GetCommitStatusesByRef returns all statuses for any given commit ref
  105. func GetCommitStatusesByRef(ctx *context.APIContext) {
  106. // swagger:operation GET /repos/{owner}/{repo}/commits/{ref}/statuses repository repoListStatusesByRef
  107. // ---
  108. // summary: Get a commit's statuses, by branch/tag/commit reference
  109. // produces:
  110. // - application/json
  111. // parameters:
  112. // - name: owner
  113. // in: path
  114. // description: owner of the repo
  115. // type: string
  116. // required: true
  117. // - name: repo
  118. // in: path
  119. // description: name of the repo
  120. // type: string
  121. // required: true
  122. // - name: ref
  123. // in: path
  124. // description: name of branch/tag/commit
  125. // type: string
  126. // required: true
  127. // - name: page
  128. // in: query
  129. // description: page number of results
  130. // type: integer
  131. // required: false
  132. // - name: sort
  133. // in: query
  134. // description: type of sort
  135. // type: string
  136. // enum: [oldest, recentupdate, leastupdate, leastindex, highestindex]
  137. // required: false
  138. // - name: state
  139. // in: query
  140. // description: type of state
  141. // type: string
  142. // enum: [pending, success, error, failure, warning]
  143. // required: false
  144. // responses:
  145. // "200":
  146. // "$ref": "#/responses/StatusList"
  147. filter := ctx.Params("ref")
  148. if len(filter) == 0 {
  149. ctx.Error(400, "ref not given", nil)
  150. return
  151. }
  152. for _, reftype := range []string{"heads", "tags"} { //Search branches and tags
  153. refSHA, lastMethodName, err := searchRefCommitByType(ctx, reftype, filter)
  154. if err != nil {
  155. ctx.Error(500, lastMethodName, err)
  156. return
  157. }
  158. if refSHA != "" {
  159. filter = refSHA
  160. break
  161. }
  162. }
  163. getCommitStatuses(ctx, filter) //By default filter is maybe the raw SHA
  164. }
  165. func searchRefCommitByType(ctx *context.APIContext, refType, filter string) (string, string, error) {
  166. refs, lastMethodName, err := getGitRefs(ctx, refType+"/"+filter) //Search by type
  167. if err != nil {
  168. return "", lastMethodName, err
  169. }
  170. if len(refs) > 0 {
  171. return refs[0].Object.String(), "", nil //Return found SHA
  172. }
  173. return "", "", nil
  174. }
  175. func getCommitStatuses(ctx *context.APIContext, sha string) {
  176. if len(sha) == 0 {
  177. ctx.Error(400, "ref/sha not given", nil)
  178. return
  179. }
  180. repo := ctx.Repo.Repository
  181. statuses, _, err := models.GetCommitStatuses(repo, sha, &models.CommitStatusOptions{
  182. Page: ctx.QueryInt("page"),
  183. SortType: ctx.QueryTrim("sort"),
  184. State: ctx.QueryTrim("state"),
  185. })
  186. if err != nil {
  187. ctx.Error(500, "GetCommitStatuses", fmt.Errorf("GetCommitStatuses[%s, %s, %d]: %v", repo.FullName(), sha, ctx.QueryInt("page"), err))
  188. return
  189. }
  190. apiStatuses := make([]*api.Status, 0, len(statuses))
  191. for _, status := range statuses {
  192. apiStatuses = append(apiStatuses, status.APIFormat())
  193. }
  194. ctx.JSON(200, apiStatuses)
  195. }
  196. type combinedCommitStatus struct {
  197. State models.CommitStatusState `json:"state"`
  198. SHA string `json:"sha"`
  199. TotalCount int `json:"total_count"`
  200. Statuses []*api.Status `json:"statuses"`
  201. Repo *api.Repository `json:"repository"`
  202. CommitURL string `json:"commit_url"`
  203. URL string `json:"url"`
  204. }
  205. // GetCombinedCommitStatusByRef returns the combined status for any given commit hash
  206. func GetCombinedCommitStatusByRef(ctx *context.APIContext) {
  207. // swagger:operation GET /repos/{owner}/{repo}/commits/{ref}/statuses repository repoGetCombinedStatusByRef
  208. // ---
  209. // summary: Get a commit's combined status, by branch/tag/commit reference
  210. // produces:
  211. // - application/json
  212. // parameters:
  213. // - name: owner
  214. // in: path
  215. // description: owner of the repo
  216. // type: string
  217. // required: true
  218. // - name: repo
  219. // in: path
  220. // description: name of the repo
  221. // type: string
  222. // required: true
  223. // - name: ref
  224. // in: path
  225. // description: name of branch/tag/commit
  226. // type: string
  227. // required: true
  228. // - name: page
  229. // in: query
  230. // description: page number of results
  231. // type: integer
  232. // required: false
  233. // responses:
  234. // "200":
  235. // "$ref": "#/responses/Status"
  236. sha := ctx.Params("ref")
  237. if len(sha) == 0 {
  238. ctx.Error(400, "ref/sha not given", nil)
  239. return
  240. }
  241. repo := ctx.Repo.Repository
  242. page := ctx.QueryInt("page")
  243. statuses, err := models.GetLatestCommitStatus(repo, sha, page)
  244. if err != nil {
  245. ctx.Error(500, "GetLatestCommitStatus", fmt.Errorf("GetLatestCommitStatus[%s, %s, %d]: %v", repo.FullName(), sha, page, err))
  246. return
  247. }
  248. if len(statuses) == 0 {
  249. ctx.Status(200)
  250. return
  251. }
  252. retStatus := &combinedCommitStatus{
  253. SHA: sha,
  254. TotalCount: len(statuses),
  255. Repo: repo.APIFormat(ctx.Repo.AccessMode),
  256. URL: "",
  257. }
  258. retStatus.Statuses = make([]*api.Status, 0, len(statuses))
  259. for _, status := range statuses {
  260. retStatus.Statuses = append(retStatus.Statuses, status.APIFormat())
  261. if status.State.IsWorseThan(retStatus.State) {
  262. retStatus.State = status.State
  263. }
  264. }
  265. ctx.JSON(200, retStatus)
  266. }