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.

release.go 7.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. // Copyright 2016 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 repo
  5. import (
  6. "code.gitea.io/gitea/models"
  7. "code.gitea.io/gitea/modules/context"
  8. api "code.gitea.io/sdk/gitea"
  9. )
  10. // GetRelease get a single release of a repository
  11. func GetRelease(ctx *context.APIContext) {
  12. // swagger:operation GET /repos/{owner}/{repo}/releases/{id} repository repoGetRelease
  13. // ---
  14. // summary: Get a release
  15. // produces:
  16. // - application/json
  17. // parameters:
  18. // - name: owner
  19. // in: path
  20. // description: owner of the repo
  21. // type: string
  22. // required: true
  23. // - name: repo
  24. // in: path
  25. // description: name of the repo
  26. // type: string
  27. // required: true
  28. // - name: id
  29. // in: path
  30. // description: id of the release to get
  31. // type: integer
  32. // required: true
  33. // responses:
  34. // "200":
  35. // "$ref": "#/responses/Release"
  36. id := ctx.ParamsInt64(":id")
  37. release, err := models.GetReleaseByID(id)
  38. if err != nil {
  39. ctx.Error(500, "GetReleaseByID", err)
  40. return
  41. }
  42. if release.RepoID != ctx.Repo.Repository.ID {
  43. ctx.Status(404)
  44. return
  45. }
  46. if err := release.LoadAttributes(); err != nil {
  47. ctx.Error(500, "LoadAttributes", err)
  48. return
  49. }
  50. ctx.JSON(200, release.APIFormat())
  51. }
  52. // ListReleases list a repository's releases
  53. func ListReleases(ctx *context.APIContext) {
  54. // swagger:operation GET /repos/{owner}/{repo}/releases repository repoListReleases
  55. // ---
  56. // summary: List a repo's releases
  57. // produces:
  58. // - application/json
  59. // parameters:
  60. // - name: owner
  61. // in: path
  62. // description: owner of the repo
  63. // type: string
  64. // required: true
  65. // - name: repo
  66. // in: path
  67. // description: name of the repo
  68. // type: string
  69. // required: true
  70. // responses:
  71. // "200":
  72. // "$ref": "#/responses/ReleaseList"
  73. releases, err := models.GetReleasesByRepoID(ctx.Repo.Repository.ID, models.FindReleasesOptions{
  74. IncludeDrafts: ctx.Repo.AccessMode >= models.AccessModeWrite,
  75. IncludeTags: false,
  76. }, 1, 2147483647)
  77. if err != nil {
  78. ctx.Error(500, "GetReleasesByRepoID", err)
  79. return
  80. }
  81. rels := make([]*api.Release, len(releases))
  82. for i, release := range releases {
  83. if err := release.LoadAttributes(); err != nil {
  84. ctx.Error(500, "LoadAttributes", err)
  85. return
  86. }
  87. rels[i] = release.APIFormat()
  88. }
  89. ctx.JSON(200, rels)
  90. }
  91. // CreateRelease create a release
  92. func CreateRelease(ctx *context.APIContext, form api.CreateReleaseOption) {
  93. // swagger:operation POST /repos/{owner}/{repo}/releases repository repoCreateRelease
  94. // ---
  95. // summary: Create a release
  96. // consumes:
  97. // - application/json
  98. // produces:
  99. // - application/json
  100. // parameters:
  101. // - name: owner
  102. // in: path
  103. // description: owner of the repo
  104. // type: string
  105. // required: true
  106. // - name: repo
  107. // in: path
  108. // description: name of the repo
  109. // type: string
  110. // required: true
  111. // - name: body
  112. // in: body
  113. // schema:
  114. // "$ref": "#/definitions/CreateReleaseOption"
  115. // responses:
  116. // "201":
  117. // "$ref": "#/responses/Release"
  118. if ctx.Repo.AccessMode < models.AccessModeWrite {
  119. ctx.Status(403)
  120. return
  121. }
  122. if !ctx.Repo.GitRepo.IsTagExist(form.TagName) {
  123. ctx.Status(404)
  124. return
  125. }
  126. rel, err := models.GetRelease(ctx.Repo.Repository.ID, form.TagName)
  127. if err != nil {
  128. if !models.IsErrReleaseNotExist(err) {
  129. ctx.ServerError("GetRelease", err)
  130. return
  131. }
  132. rel = &models.Release{
  133. RepoID: ctx.Repo.Repository.ID,
  134. PublisherID: ctx.User.ID,
  135. Publisher: ctx.User,
  136. TagName: form.TagName,
  137. Target: form.Target,
  138. Title: form.Title,
  139. Note: form.Note,
  140. IsDraft: form.IsDraft,
  141. IsPrerelease: form.IsPrerelease,
  142. IsTag: false,
  143. Repo: ctx.Repo.Repository,
  144. }
  145. if err := models.CreateRelease(ctx.Repo.GitRepo, rel, nil); err != nil {
  146. if models.IsErrReleaseAlreadyExist(err) {
  147. ctx.Status(409)
  148. } else {
  149. ctx.Error(500, "CreateRelease", err)
  150. }
  151. return
  152. }
  153. } else {
  154. if !rel.IsTag {
  155. ctx.Status(409)
  156. return
  157. }
  158. rel.Title = form.Title
  159. rel.Note = form.Note
  160. rel.IsDraft = form.IsDraft
  161. rel.IsPrerelease = form.IsPrerelease
  162. rel.PublisherID = ctx.User.ID
  163. rel.IsTag = false
  164. rel.Repo = ctx.Repo.Repository
  165. rel.Publisher = ctx.User
  166. if err = models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
  167. ctx.ServerError("UpdateRelease", err)
  168. return
  169. }
  170. }
  171. ctx.JSON(201, rel.APIFormat())
  172. }
  173. // EditRelease edit a release
  174. func EditRelease(ctx *context.APIContext, form api.EditReleaseOption) {
  175. // swagger:operation PATCH /repos/{owner}/{repo}/releases/{id} repository repoEditRelease
  176. // ---
  177. // summary: Update a release
  178. // consumes:
  179. // - application/json
  180. // produces:
  181. // - application/json
  182. // parameters:
  183. // - name: owner
  184. // in: path
  185. // description: owner of the repo
  186. // type: string
  187. // required: true
  188. // - name: repo
  189. // in: path
  190. // description: name of the repo
  191. // type: string
  192. // required: true
  193. // - name: id
  194. // in: path
  195. // description: id of the release to edit
  196. // type: integer
  197. // required: true
  198. // - name: body
  199. // in: body
  200. // schema:
  201. // "$ref": "#/definitions/EditReleaseOption"
  202. // responses:
  203. // "200":
  204. // "$ref": "#/responses/Release"
  205. if ctx.Repo.AccessMode < models.AccessModeWrite {
  206. ctx.Status(403)
  207. return
  208. }
  209. id := ctx.ParamsInt64(":id")
  210. rel, err := models.GetReleaseByID(id)
  211. if err != nil && !models.IsErrReleaseNotExist(err) {
  212. ctx.Error(500, "GetReleaseByID", err)
  213. return
  214. }
  215. if err != nil && models.IsErrReleaseNotExist(err) ||
  216. rel.IsTag || rel.RepoID != ctx.Repo.Repository.ID {
  217. ctx.Status(404)
  218. return
  219. }
  220. if len(form.TagName) > 0 {
  221. rel.TagName = form.TagName
  222. }
  223. if len(form.Target) > 0 {
  224. rel.Target = form.Target
  225. }
  226. if len(form.Title) > 0 {
  227. rel.Title = form.Title
  228. }
  229. if len(form.Note) > 0 {
  230. rel.Note = form.Note
  231. }
  232. if form.IsDraft != nil {
  233. rel.IsDraft = *form.IsDraft
  234. }
  235. if form.IsPrerelease != nil {
  236. rel.IsPrerelease = *form.IsPrerelease
  237. }
  238. if err := models.UpdateRelease(ctx.User, ctx.Repo.GitRepo, rel, nil); err != nil {
  239. ctx.Error(500, "UpdateRelease", err)
  240. return
  241. }
  242. rel, err = models.GetReleaseByID(id)
  243. if err != nil {
  244. ctx.Error(500, "GetReleaseByID", err)
  245. return
  246. }
  247. if err := rel.LoadAttributes(); err != nil {
  248. ctx.Error(500, "LoadAttributes", err)
  249. return
  250. }
  251. ctx.JSON(200, rel.APIFormat())
  252. }
  253. // DeleteRelease delete a release from a repository
  254. func DeleteRelease(ctx *context.APIContext) {
  255. // swagger:operation DELETE /repos/{owner}/{repo}/releases/{id} repository repoDeleteRelease
  256. // ---
  257. // summary: Delete a release
  258. // parameters:
  259. // - name: owner
  260. // in: path
  261. // description: owner of the repo
  262. // type: string
  263. // required: true
  264. // - name: repo
  265. // in: path
  266. // description: name of the repo
  267. // type: string
  268. // required: true
  269. // - name: id
  270. // in: path
  271. // description: id of the release to delete
  272. // type: integer
  273. // required: true
  274. // responses:
  275. // "204":
  276. // "$ref": "#/responses/empty"
  277. if ctx.Repo.AccessMode < models.AccessModeWrite {
  278. ctx.Status(403)
  279. return
  280. }
  281. id := ctx.ParamsInt64(":id")
  282. rel, err := models.GetReleaseByID(id)
  283. if err != nil && !models.IsErrReleaseNotExist(err) {
  284. ctx.Error(500, "GetReleaseByID", err)
  285. return
  286. }
  287. if err != nil && models.IsErrReleaseNotExist(err) ||
  288. rel.IsTag || rel.RepoID != ctx.Repo.Repository.ID {
  289. ctx.Status(404)
  290. return
  291. }
  292. if err := models.DeleteReleaseByID(id, ctx.User, false); err != nil {
  293. ctx.Error(500, "DeleteReleaseByID", err)
  294. return
  295. }
  296. ctx.Status(204)
  297. }