##// END OF EJS Templates
events: add an event for pull request comments with review status
dan -
r443:c2778156 default
parent child Browse files
Show More
@@ -32,6 +32,7 b' from pylons.i18n.translation import _'
32 from sqlalchemy.sql import func
32 from sqlalchemy.sql import func
33 from sqlalchemy.sql.expression import or_
33 from sqlalchemy.sql.expression import or_
34
34
35 from rhodecode import events
35 from rhodecode.lib import auth, diffs, helpers as h
36 from rhodecode.lib import auth, diffs, helpers as h
36 from rhodecode.lib.ext_json import json
37 from rhodecode.lib.ext_json import json
37 from rhodecode.lib.base import (
38 from rhodecode.lib.base import (
@@ -764,6 +765,8 b' class PullrequestsController(BaseRepoCon'
764 closing_pr=close_pr
765 closing_pr=close_pr
765 )
766 )
766
767
768
769
767 if allowed_to_change_status:
770 if allowed_to_change_status:
768 old_calculated_status = pull_request.calculated_review_status()
771 old_calculated_status = pull_request.calculated_review_status()
769 # get status if set !
772 # get status if set !
@@ -777,6 +780,7 b' class PullrequestsController(BaseRepoCon'
777 )
780 )
778
781
779 Session().flush()
782 Session().flush()
783 events.trigger(events.PullRequestCommentEvent(pull_request, comm))
780 # we now calculate the status of pull request, and based on that
784 # we now calculate the status of pull request, and based on that
781 # calculation we set the commits status
785 # calculation we set the commits status
782 calculated_status = pull_request.calculated_review_status()
786 calculated_status = pull_request.calculated_review_status()
@@ -64,6 +64,7 b' from rhodecode.events.pullrequest import'
64 PullRequestEvent,
64 PullRequestEvent,
65 PullRequestCreateEvent,
65 PullRequestCreateEvent,
66 PullRequestUpdateEvent,
66 PullRequestUpdateEvent,
67 PullRequestCommentEvent,
67 PullRequestReviewEvent,
68 PullRequestReviewEvent,
68 PullRequestMergeEvent,
69 PullRequestMergeEvent,
69 PullRequestCloseEvent,
70 PullRequestCloseEvent,
@@ -44,7 +44,8 b' class PullRequestEvent(RepoEvent):'
44 'title': self.pullrequest.title,
44 'title': self.pullrequest.title,
45 'issues': issues,
45 'issues': issues,
46 'pull_request_id': self.pullrequest.pull_request_id,
46 'pull_request_id': self.pullrequest.pull_request_id,
47 'url': PullRequestModel().get_url(self.pullrequest)
47 'url': PullRequestModel().get_url(self.pullrequest),
48 'status': self.pullrequest.calculated_review_status(),
48 }
49 }
49 })
50 })
50 return data
51 return data
@@ -71,10 +72,19 b' class PullRequestCloseEvent(PullRequestE'
71 class PullRequestUpdateEvent(PullRequestEvent):
72 class PullRequestUpdateEvent(PullRequestEvent):
72 """
73 """
73 An instance of this class is emitted as an :term:`event` after a pull
74 An instance of this class is emitted as an :term:`event` after a pull
74 request is updated.
75 request's commits have been updated.
75 """
76 """
76 name = 'pullrequest-update'
77 name = 'pullrequest-update'
77 display_name = lazy_ugettext('pullrequest updated')
78 display_name = lazy_ugettext('pullrequest commits updated')
79
80
81 class PullRequestReviewEvent(PullRequestEvent):
82 """
83 An instance of this class is emitted as an :term:`event` after a pull
84 request review has changed.
85 """
86 name = 'pullrequest-review'
87 display_name = lazy_ugettext('pullrequest review changed')
78
88
79
89
80 class PullRequestMergeEvent(PullRequestEvent):
90 class PullRequestMergeEvent(PullRequestEvent):
@@ -86,12 +96,31 b' class PullRequestMergeEvent(PullRequestE'
86 display_name = lazy_ugettext('pullrequest merged')
96 display_name = lazy_ugettext('pullrequest merged')
87
97
88
98
89 class PullRequestReviewEvent(PullRequestEvent):
99 class PullRequestCommentEvent(PullRequestEvent):
90 """
100 """
91 An instance of this class is emitted as an :term:`event` after a pull
101 An instance of this class is emitted as an :term:`event` after a pull
92 request is reviewed.
102 request comment is created.
93 """
103 """
94 name = 'pullrequest-review'
104 name = 'pullrequest-comment'
95 display_name = lazy_ugettext('pullrequest reviewed')
105 display_name = lazy_ugettext('pullrequest commented')
106
107 def __init__(self, pullrequest, comment):
108 super(PullRequestCommentEvent, self).__init__(pullrequest)
109 self.comment = comment
110
111 def as_dict(self):
112 from rhodecode.model.comment import ChangesetCommentsModel
113 data = super(PullRequestCommentEvent, self).as_dict()
96
114
115 status = None
116 if self.comment.status_change:
117 status = self.comment.status_change[0].status
97
118
119 data.update({
120 'comment': {
121 'status': status,
122 'text': self.comment.text,
123 'url': ChangesetCommentsModel().get_url(self.comment)
124 }
125 })
126 return data
@@ -24,6 +24,7 b' import re'
24 import logging
24 import logging
25 import requests
25 import requests
26 import colander
26 import colander
27 import textwrap
27 from celery.task import task
28 from celery.task import task
28 from mako.template import Template
29 from mako.template import Template
29
30
@@ -105,6 +106,7 b' class SlackIntegrationType(IntegrationTy'
105 events.PullRequestCloseEvent,
106 events.PullRequestCloseEvent,
106 events.PullRequestMergeEvent,
107 events.PullRequestMergeEvent,
107 events.PullRequestUpdateEvent,
108 events.PullRequestUpdateEvent,
109 events.PullRequestCommentEvent,
108 events.PullRequestReviewEvent,
110 events.PullRequestReviewEvent,
109 events.PullRequestCreateEvent,
111 events.PullRequestCreateEvent,
110 events.RepoPushEvent,
112 events.RepoPushEvent,
@@ -127,7 +129,11 b' class SlackIntegrationType(IntegrationTy'
127
129
128 log.debug('handling slack event for %s' % event.name)
130 log.debug('handling slack event for %s' % event.name)
129
131
130 if isinstance(event, events.PullRequestEvent):
132 if isinstance(event, events.PullRequestCommentEvent):
133 text = self.format_pull_request_comment_event(event, data)
134 elif isinstance(event, events.PullRequestReviewEvent):
135 text = self.format_pull_request_review_event(event, data)
136 elif isinstance(event, events.PullRequestEvent):
131 text = self.format_pull_request_event(event, data)
137 text = self.format_pull_request_event(event, data)
132 elif isinstance(event, events.RepoPushEvent):
138 elif isinstance(event, events.RepoPushEvent):
133 text = self.format_repo_push_event(data)
139 text = self.format_repo_push_event(data)
@@ -150,16 +156,55 b' class SlackIntegrationType(IntegrationTy'
150 ))
156 ))
151 return schema
157 return schema
152
158
159 def format_pull_request_comment_event(self, event, data):
160 comment_text = data['comment']['text']
161 if len(comment_text) > 200:
162 comment_text = '<{comment_url}|{comment_text}...>'.format(
163 comment_text=comment_text[:200],
164 comment_url=data['comment']['url'],
165 )
166
167 comment_status = ''
168 if data['comment']['status']:
169 comment_status = '[{}]: '.format(data['comment']['status'])
170
171 return (textwrap.dedent(
172 '''
173 {user} commented on pull request <{pr_url}|#{number}> - {pr_title}:
174 >>> {comment_status}{comment_text}
175 ''').format(
176 comment_status=comment_status,
177 user=data['actor']['username'],
178 number=data['pullrequest']['pull_request_id'],
179 pr_url=data['pullrequest']['url'],
180 pr_status=data['pullrequest']['status'],
181 pr_title=data['pullrequest']['title'],
182 comment_text=comment_text
183 )
184 )
185
186 def format_pull_request_review_event(self, event, data):
187 return (textwrap.dedent(
188 '''
189 Status changed to {pr_status} for pull request <{pr_url}|#{number}> - {pr_title}
190 ''').format(
191 user=data['actor']['username'],
192 number=data['pullrequest']['pull_request_id'],
193 pr_url=data['pullrequest']['url'],
194 pr_status=data['pullrequest']['status'],
195 pr_title=data['pullrequest']['title'],
196 )
197 )
198
153 def format_pull_request_event(self, event, data):
199 def format_pull_request_event(self, event, data):
154 action = {
200 action = {
155 events.PullRequestCloseEvent: 'closed',
201 events.PullRequestCloseEvent: 'closed',
156 events.PullRequestMergeEvent: 'merged',
202 events.PullRequestMergeEvent: 'merged',
157 events.PullRequestUpdateEvent: 'updated',
203 events.PullRequestUpdateEvent: 'updated',
158 events.PullRequestReviewEvent: 'reviewed',
159 events.PullRequestCreateEvent: 'created',
204 events.PullRequestCreateEvent: 'created',
160 }.get(event.__class__, '<unknown action>')
205 }.get(event.__class__, str(event.__class__))
161
206
162 return ('Pull request <{url}|#{number}> ({title}) '
207 return ('Pull request <{url}|#{number}> - {title} '
163 '{action} by {user}').format(
208 '{action} by {user}').format(
164 user=data['actor']['username'],
209 user=data['actor']['username'],
165 number=data['pullrequest']['pull_request_id'],
210 number=data['pullrequest']['pull_request_id'],
@@ -156,12 +156,7 b' class ChangesetCommentsModel(BaseModel):'
156 cs_author = repo.user
156 cs_author = repo.user
157 recipients += [cs_author]
157 recipients += [cs_author]
158
158
159 commit_comment_url = h.url(
159 commit_comment_url = self.get_url(comment)
160 'changeset_home',
161 repo_name=repo.repo_name,
162 revision=commit_obj.raw_id,
163 anchor='comment-%s' % comment.comment_id,
164 qualified=True,)
165
160
166 target_repo_url = h.link_to(
161 target_repo_url = h.link_to(
167 repo.repo_name,
162 repo.repo_name,
@@ -271,6 +266,23 b' class ChangesetCommentsModel(BaseModel):'
271 q = q.order_by(ChangesetComment.created_on)
266 q = q.order_by(ChangesetComment.created_on)
272 return q.all()
267 return q.all()
273
268
269 def get_url(self, comment):
270 comment = self.__get_commit_comment(comment)
271 if comment.pull_request:
272 return h.url(
273 'pullrequest_show',
274 repo_name=comment.pull_request.target_repo.repo_name,
275 pull_request_id=comment.pull_request.pull_request_id,
276 anchor='comment-%s' % comment.comment_id,
277 qualified=True,)
278 else:
279 return h.url(
280 'changeset_home',
281 repo_name=comment.repo.repo_name,
282 revision=comment.revision,
283 anchor='comment-%s' % comment.comment_id,
284 qualified=True,)
285
274 def get_comments(self, repo_id, revision=None, pull_request=None):
286 def get_comments(self, repo_id, revision=None, pull_request=None):
275 """
287 """
276 Gets main comments based on revision or pull_request_id
288 Gets main comments based on revision or pull_request_id
@@ -22,10 +22,12 b' import pytest'
22
22
23 from rhodecode.tests.events.conftest import EventCatcher
23 from rhodecode.tests.events.conftest import EventCatcher
24
24
25 from rhodecode.model.comment import ChangesetCommentsModel
25 from rhodecode.model.pull_request import PullRequestModel
26 from rhodecode.model.pull_request import PullRequestModel
26 from rhodecode.events import (
27 from rhodecode.events import (
27 PullRequestCreateEvent,
28 PullRequestCreateEvent,
28 PullRequestUpdateEvent,
29 PullRequestUpdateEvent,
30 PullRequestCommentEvent,
29 PullRequestReviewEvent,
31 PullRequestReviewEvent,
30 PullRequestMergeEvent,
32 PullRequestMergeEvent,
31 PullRequestCloseEvent,
33 PullRequestCloseEvent,
@@ -56,6 +58,19 b' def test_create_pull_request_events(pr_u'
56
58
57 assert PullRequestCreateEvent in event_catcher.events_types
59 assert PullRequestCreateEvent in event_catcher.events_types
58
60
61 @pytest.mark.backends("git", "hg")
62 def test_pullrequest_comment_events_serialized(pr_util):
63 pr = pr_util.create_pull_request()
64 comment = ChangesetCommentsModel().get_comments(
65 pr.target_repo.repo_id, pull_request=pr)[0]
66 event = PullRequestCommentEvent(pr, comment)
67 data = event.as_dict()
68 assert data['name'] == PullRequestCommentEvent.name
69 assert data['repo']['repo_name'] == pr.target_repo.repo_name
70 assert data['pullrequest']['pull_request_id'] == pr.pull_request_id
71 assert data['pullrequest']['url']
72 assert data['comment']['text'] == comment.text
73
59
74
60 @pytest.mark.backends("git", "hg")
75 @pytest.mark.backends("git", "hg")
61 def test_close_pull_request_events(pr_util, user_admin):
76 def test_close_pull_request_events(pr_util, user_admin):
General Comments 0
You need to be logged in to leave comments. Login now