@@ -208,6 +208,168 @@ func GetPullReviewComments(ctx *context.APIContext) {
208208 ctx .JSON (http .StatusOK , apiComments )
209209}
210210
211+ // ResolvePullReviewComment resolves a review comment in a pull request
212+ func ResolvePullReviewComment (ctx * context.APIContext ) {
213+ // swagger:operation POST /repos/{owner}/{repo}/pulls/{index}/comments/{id}/resolve repository repoResolvePullReviewComment
214+ // ---
215+ // summary: Resolve a pull review comment
216+ // produces:
217+ // - application/json
218+ // parameters:
219+ // - name: owner
220+ // in: path
221+ // description: owner of the repo
222+ // type: string
223+ // required: true
224+ // - name: repo
225+ // in: path
226+ // description: name of the repo
227+ // type: string
228+ // required: true
229+ // - name: index
230+ // in: path
231+ // description: index of the pull request
232+ // type: integer
233+ // format: int64
234+ // required: true
235+ // - name: id
236+ // in: path
237+ // description: id of the review comment
238+ // type: integer
239+ // format: int64
240+ // required: true
241+ // responses:
242+ // "200":
243+ // "$ref": "#/responses/PullReviewComment"
244+ // "400":
245+ // "$ref": "#/responses/validationError"
246+ // "403":
247+ // "$ref": "#/responses/forbidden"
248+ // "404":
249+ // "$ref": "#/responses/notFound"
250+ updatePullReviewCommentResolve (ctx , true )
251+ }
252+
253+ // UnresolvePullReviewComment unresolves a review comment in a pull request
254+ func UnresolvePullReviewComment (ctx * context.APIContext ) {
255+ // swagger:operation POST /repos/{owner}/{repo}/pulls/{index}/comments/{id}/unresolve repository repoUnresolvePullReviewComment
256+ // ---
257+ // summary: Unresolve a pull review comment
258+ // produces:
259+ // - application/json
260+ // parameters:
261+ // - name: owner
262+ // in: path
263+ // description: owner of the repo
264+ // type: string
265+ // required: true
266+ // - name: repo
267+ // in: path
268+ // description: name of the repo
269+ // type: string
270+ // required: true
271+ // - name: index
272+ // in: path
273+ // description: index of the pull request
274+ // type: integer
275+ // format: int64
276+ // required: true
277+ // - name: id
278+ // in: path
279+ // description: id of the review comment
280+ // type: integer
281+ // format: int64
282+ // required: true
283+ // responses:
284+ // "200":
285+ // "$ref": "#/responses/PullReviewComment"
286+ // "400":
287+ // "$ref": "#/responses/validationError"
288+ // "403":
289+ // "$ref": "#/responses/forbidden"
290+ // "404":
291+ // "$ref": "#/responses/notFound"
292+ updatePullReviewCommentResolve (ctx , false )
293+ }
294+
295+ func updatePullReviewCommentResolve (ctx * context.APIContext , isResolve bool ) {
296+ commentID := ctx .PathParamInt64 ("id" )
297+ comment , err := issues_model .GetCommentByID (ctx , commentID )
298+ if err != nil {
299+ if issues_model .IsErrCommentNotExist (err ) {
300+ ctx .APIErrorNotFound ("GetCommentByID" , err )
301+ } else {
302+ ctx .APIErrorInternal (err )
303+ }
304+ return
305+ }
306+
307+ if err = comment .LoadIssue (ctx ); err != nil {
308+ ctx .APIErrorInternal (err )
309+ return
310+ }
311+
312+ if comment .Issue .RepoID != ctx .Repo .Repository .ID {
313+ ctx .APIErrorNotFound ("CommentNotInRepo" )
314+ return
315+ }
316+
317+ if ! comment .Issue .IsPull {
318+ ctx .APIError (http .StatusBadRequest , "comment does not belong to a pull request" )
319+ return
320+ }
321+
322+ if comment .Issue .Index != ctx .PathParamInt64 ("index" ) {
323+ ctx .APIErrorNotFound ("CommentNotInPullRequest" )
324+ return
325+ }
326+
327+ if comment .Type != issues_model .CommentTypeCode {
328+ ctx .APIError (http .StatusBadRequest , "comment is not a review comment" )
329+ return
330+ }
331+
332+ permResult , err := issues_model .CanMarkConversation (ctx , comment .Issue , ctx .Doer )
333+ if err != nil {
334+ ctx .APIErrorInternal (err )
335+ return
336+ }
337+ if ! permResult {
338+ ctx .APIError (http .StatusForbidden , "user should have permission to resolve comment" )
339+ return
340+ }
341+
342+ wasResolved := comment .ResolveDoerID != 0
343+ if err = issues_model .MarkConversation (ctx , comment , ctx .Doer , isResolve ); err != nil {
344+ ctx .APIErrorInternal (err )
345+ return
346+ }
347+
348+ if isResolve {
349+ if ! wasResolved {
350+ comment .ResolveDoerID = ctx .Doer .ID
351+ }
352+ } else {
353+ if wasResolved {
354+ comment .ResolveDoerID = 0
355+ }
356+ comment .ResolveDoer = nil
357+ }
358+
359+ if err = comment .LoadPoster (ctx ); err != nil {
360+ ctx .APIErrorInternal (err )
361+ return
362+ }
363+
364+ if err = comment .LoadResolveDoer (ctx ); err != nil {
365+ ctx .APIErrorInternal (err )
366+ return
367+ }
368+
369+ comment .Issue .Repo = ctx .Repo .Repository
370+ ctx .JSON (http .StatusOK , convert .ToPullReviewComment (ctx , comment , comment .Issue , ctx .Doer ))
371+ }
372+
211373// DeletePullReview delete a specific review from a pull request
212374func DeletePullReview (ctx * context.APIContext ) {
213375 // swagger:operation DELETE /repos/{owner}/{repo}/pulls/{index}/reviews/{id} repository repoDeletePullReview
0 commit comments