hooks: added new hooks for comments on pull requests and commits....
dan -
r4305:de8db8da default
Not Reviewed
Show More
Add another comment
TODOs: 0 unresolved 0 Resolved
COMMENTS: 0 General 0 Inline
@@ -0,0 +1,60
1 # Example to trigger a CI call action on specific comment text, e.g chatops and ci
2 # rebuild on mention of ci bot
3
4 @has_kwargs({
5 'repo_name': '',
6 'repo_type': '',
7 'description': '',
8 'private': '',
9 'created_on': '',
10 'enable_downloads': '',
11 'repo_id': '',
12 'user_id': '',
13 'enable_statistics': '',
14 'clone_uri': '',
15 'fork_id': '',
16 'group_id': '',
17 'created_by': '',
18 'repository': '',
19 'comment': '',
20 'commit': ''
21 })
22 def _comment_commit_repo_hook(*args, **kwargs):
23 """
24 POST CREATE REPOSITORY COMMENT ON COMMIT HOOK. This function will be executed after
25 a comment is made on this repository commit.
26
27 """
28 from .helpers import http_call, extra_fields
29 from .utils import UrlTemplate
30 # returns list of dicts with key-val fetched from extra fields
31 repo_extra_fields = extra_fields.run(**kwargs)
32
33 import rhodecode
34 from rc_integrations.jenkins_ci import csrf_call, get_auth, requests_retry_call
35
36 endpoint_url = extra_fields.get_field(
37 repo_extra_fields, key='ci_endpoint_url',
38 default='http://ci.rc.com/job/rc-ce-commits/build?COMMIT_ID=${commit}')
39 mention_text = extra_fields.get_field(
40 repo_extra_fields, key='ci_mention_text',
41 default='@jenkins build')
42
43 endpoint_url = UrlTemplate(endpoint_url).safe_substitute(
44 commit=kwargs['commit']['raw_id'])
45
46 trigger_ci = False
47 comment = kwargs['comment']['comment_text']
48 if mention_text in comment:
49 trigger_ci = True
50
51 if trigger_ci is False:
52 return HookResponse(0, '')
53
54 # call some CI based on the special coment mention marker
55 data = {
56 'project': kwargs['repository'],
57 }
58 response = http_call.run(url=endpoint_url, params=data)
59
60 return HookResponse(0, '') No newline at end of file
@@ -1599,7 +1599,8 def comment_commit(
1599 validate_repo_permissions(apiuser, repoid, repo, _perms)
1599 validate_repo_permissions(apiuser, repoid, repo, _perms)
1600
1600
1601 try:
1601 try:
1602 commit_id = repo.scm_instance().get_commit(commit_id=commit_id).raw_id
1602 commit = repo.scm_instance().get_commit(commit_id=commit_id)
1603 commit_id = commit.raw_id
1603 except Exception as e:
1604 except Exception as e:
1604 log.exception('Failed to fetch commit')
1605 log.exception('Failed to fetch commit')
1605 raise JSONRPCError(safe_str(e))
1606 raise JSONRPCError(safe_str(e))
@@ -1659,6 +1660,10 def comment_commit(
1659 'a closed pull request is not allowed')
1660 'a closed pull request is not allowed')
1660 raise JSONRPCError(msg)
1661 raise JSONRPCError(msg)
1661
1662
1663 CommentsModel().trigger_commit_comment_hook(
1664 repo, apiuser, 'create',
1665 data={'comment': comment, 'commit': commit})
1666
1662 Session().commit()
1667 Session().commit()
1663 return {
1668 return {
1664 'msg': (
1669 'msg': (
@@ -380,6 +380,11 class RepoCommitsView(RepoAppView):
380 'repo_commit', repo_name=self.db_repo_name,
380 'repo_commit', repo_name=self.db_repo_name,
381 commit_id=current_id))
381 commit_id=current_id))
382
382
383 commit = self.db_repo.get_commit(current_id)
384 CommentsModel().trigger_commit_comment_hook(
385 self.db_repo, self._rhodecode_user, 'create',
386 data={'comment': comment, 'commit': commit})
387
383 # finalize, commit and redirect
388 # finalize, commit and redirect
384 Session().commit()
389 Session().commit()
385
390
@@ -25,6 +25,7 from .hooks import (
25 _create_repo_group_hook,
25 _create_repo_group_hook,
26 _pre_create_user_hook,
26 _pre_create_user_hook,
27 _create_user_hook,
27 _create_user_hook,
28 _comment_commit_repo_hook,
28 _delete_repo_hook,
29 _delete_repo_hook,
29 _delete_user_hook,
30 _delete_user_hook,
30 _pre_push_hook,
31 _pre_push_hook,
@@ -33,6 +34,7 from .hooks import (
33 _pull_hook,
34 _pull_hook,
34 _create_pull_request_hook,
35 _create_pull_request_hook,
35 _review_pull_request_hook,
36 _review_pull_request_hook,
37 _comment_pull_request_hook,
36 _update_pull_request_hook,
38 _update_pull_request_hook,
37 _merge_pull_request_hook,
39 _merge_pull_request_hook,
38 _close_pull_request_hook,
40 _close_pull_request_hook,
@@ -40,6 +42,7 from .hooks import (
40
42
41 # set as module attributes, we use those to call hooks. *do not change this*
43 # set as module attributes, we use those to call hooks. *do not change this*
42 CREATE_REPO_HOOK = _create_repo_hook
44 CREATE_REPO_HOOK = _create_repo_hook
45 COMMENT_COMMIT_REPO_HOOK = _comment_commit_repo_hook
43 CREATE_REPO_GROUP_HOOK = _create_repo_group_hook
46 CREATE_REPO_GROUP_HOOK = _create_repo_group_hook
44 PRE_CREATE_USER_HOOK = _pre_create_user_hook
47 PRE_CREATE_USER_HOOK = _pre_create_user_hook
45 CREATE_USER_HOOK = _create_user_hook
48 CREATE_USER_HOOK = _create_user_hook
@@ -51,6 +54,7 PRE_PULL_HOOK = _pre_pull_hook
51 PULL_HOOK = _pull_hook
54 PULL_HOOK = _pull_hook
52 CREATE_PULL_REQUEST = _create_pull_request_hook
55 CREATE_PULL_REQUEST = _create_pull_request_hook
53 REVIEW_PULL_REQUEST = _review_pull_request_hook
56 REVIEW_PULL_REQUEST = _review_pull_request_hook
57 COMMENT_PULL_REQUEST = _comment_pull_request_hook
54 UPDATE_PULL_REQUEST = _update_pull_request_hook
58 UPDATE_PULL_REQUEST = _update_pull_request_hook
55 MERGE_PULL_REQUEST = _merge_pull_request_hook
59 MERGE_PULL_REQUEST = _merge_pull_request_hook
56 CLOSE_PULL_REQUEST = _close_pull_request_hook
60 CLOSE_PULL_REQUEST = _close_pull_request_hook
@@ -24,14 +24,13 def _push_hook(*args, **kwargs):
24 # returns list of dicts with key-val fetched from extra fields
24 # returns list of dicts with key-val fetched from extra fields
25 repo_extra_fields = extra_fields.run(**kwargs)
25 repo_extra_fields = extra_fields.run(**kwargs)
26
26
27 if repo_extra_fields.get('endpoint_url'):
27 endpoint_url = extra_fields.get_field(repo_extra_fields, key='endpoint_url', default='')
28 field_metadata = repo_extra_fields['endpoint_url']
28
29 endpoint = field_metadata['field_value']
29 if endpoint_url:
30 if endpoint:
30 data = {
31 data = {
31 'project': kwargs['repository'],
32 'project': kwargs['repository'],
32 }
33 }
33 response = http_call.run(url=endpoint_url, params=data)
34 response = http_call.run(url=endpoint, params=data)
34 return HookResponse(0, 'Called endpoint {}, with response {}\n'.format(endpoint_url, response))
35 return HookResponse(0, 'Called endpoint {}, with response {}\n'.format(endpoint, response))
36
35
37 return HookResponse(0, '')
36 return HookResponse(0, '')
@@ -24,14 +24,12 def _push_hook(*args, **kwargs):
24 # returns list of dicts with key-val fetched from extra fields
24 # returns list of dicts with key-val fetched from extra fields
25 repo_extra_fields = extra_fields.run(**kwargs)
25 repo_extra_fields = extra_fields.run(**kwargs)
26
26
27 if repo_extra_fields.get('endpoint_url'):
27 endpoint_url = extra_fields.get_field(repo_extra_fields, key='endpoint_url', default='')
28 field_metadata = repo_extra_fields['endpoint_url']
28 if endpoint_url:
29 endpoint = field_metadata['field_value']
29 data = {
30 if endpoint:
30 'some_key': 'val'
31 data = {
31 }
32 'some_key': 'val'
32 response = http_call.run(url=endpoint_url, json_data=data)
33 }
33 return HookResponse(0, 'Called endpoint {}, with response {}'.format(endpoint_url, response))
34 response = http_call.run(url=endpoint, json_data=data)
35 return HookResponse(0, 'Called endpoint {}, with response {}'.format(endpoint, response))
36
34
37 return HookResponse(0, '')
35 return HookResponse(0, '')
@@ -41,11 +41,13 def _pre_push_hook(*args, **kwargs):
41 repo_extra_fields = extra_fields.run(**kwargs)
41 repo_extra_fields = extra_fields.run(**kwargs)
42
42
43 # optionally use 'extra fields' to control the logic per repo
43 # optionally use 'extra fields' to control the logic per repo
44 validate_author = repo_extra_fields.get('validate_author', {}).get('field_value')
44 validate_author = extra_fields.get_field(
45 repo_extra_fields, key='validate_author', default=False)
45 should_validate = str2bool(validate_author)
46 should_validate = str2bool(validate_author)
46
47
47 # optionally store validation regex into extra fields
48 # optionally store validation regex into extra fields
48 validation_regex = repo_extra_fields.get('validation_regex', {}).get('field_value')
49 validation_regex = extra_fields.get_field(
50 repo_extra_fields, key='validation_regex', default='')
49
51
50 def validate_commit_message(commit_message, message_regex=None):
52 def validate_commit_message(commit_message, message_regex=None):
51 """
53 """
@@ -44,13 +44,16 def _pre_push_hook(*args, **kwargs):
44
44
45 # optionally use 'extra fields' to control the logic per repo
45 # optionally use 'extra fields' to control the logic per repo
46 # e.g store a list of patterns to be forbidden e.g `*.exe, *.dump`
46 # e.g store a list of patterns to be forbidden e.g `*.exe, *.dump`
47 forbid_files = repo_extra_fields.get('forbid_files_glob', {}).get('field_value')
47 forbid_files = extra_fields.get_field(repo_extra_fields, key='forbid_files_glob',
48 convert_type=False, default=[])
48 forbid_files = aslist(forbid_files)
49 forbid_files = aslist(forbid_files)
49
50
50 # forbid_files = ['*'] # example pattern
51 # forbid_files = ['*'] # example pattern
51
52
52 # optionally get bytes limit for a single file, e.g 1024 for 1KB
53 # optionally get bytes limit for a single file, e.g 1024 for 1KB
53 forbid_size_over = repo_extra_fields.get('forbid_size_over', {}).get('field_value')
54 forbid_size_over = extra_fields.get_field(repo_extra_fields, key='forbid_size_over',
55 convert_type=False, default=0)
56
54 forbid_size_over = int(forbid_size_over or 0)
57 forbid_size_over = int(forbid_size_over or 0)
55
58
56 # forbid_size_over = 1024 # example 1024
59 # forbid_size_over = 1024 # example 1024
@@ -53,3 +53,36 def run(*args, **kwargs):
53 fields[field.field_key] = field.get_dict()
53 fields[field.field_key] = field.get_dict()
54
54
55 return fields
55 return fields
56
57
58 class _Undefined(object):
59 pass
60
61
62 def get_field(extra_fields_data, key, default=_Undefined(), convert_type=True):
63 """
64 field_value = get_field(extra_fields, key='ci_endpoint_url', default='')
65 """
66 from ..utils import str2bool, aslist
67
68 if key not in extra_fields_data:
69 if isinstance(default, _Undefined):
70 raise ValueError('key {} not present in extra_fields'.format(key))
71 return default
72
73 # NOTE(dan): from metadata we get field_label, field_value, field_desc, field_type
74 field_metadata = extra_fields_data[key]
75
76 field_value = field_metadata['field_value']
77
78 # NOTE(dan): empty value, use default
79 if not field_value and not isinstance(default, _Undefined):
80 return default
81
82 if convert_type:
83 # 'str', 'unicode', 'list', 'tuple'
84 _type = field_metadata['field_type']
85 if _type in ['list', 'tuple']:
86 field_value = aslist(field_value)
87
88 return field_value
@@ -15,11 +15,12
15 # This program is dual-licensed. If you wish to learn more about the
15 # This program is dual-licensed. If you wish to learn more about the
16 # RhodeCode Enterprise Edition, including its added features, Support services,
16 # RhodeCode Enterprise Edition, including its added features, Support services,
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
17 # and proprietary license terms, please see https://rhodecode.com/licenses/
18
18 import logging
19 import logging
19 from .utils import DotDict, HookResponse, has_kwargs
20 from .utils import DotDict, HookResponse, has_kwargs
21
20 log = logging.getLogger('rhodecode.' + __name__)
22 log = logging.getLogger('rhodecode.' + __name__)
21
23
22
23 # Config shortcut to keep, all configuration in one place
24 # Config shortcut to keep, all configuration in one place
24 # Example: api_key = CONFIG.my_config.api_key
25 # Example: api_key = CONFIG.my_config.api_key
25 CONFIG = DotDict(
26 CONFIG = DotDict(
@@ -55,13 +56,40 def _create_repo_hook(*args, **kwargs):
55
56
56
57
57 @has_kwargs({
58 @has_kwargs({
58 'group_name': '',
59 'repo_name': '',
59 'group_parent_id': '',
60 'repo_type': '',
61 'description': '',
62 'private': '',
63 'created_on': '',
64 'enable_downloads': '',
65 'repo_id': '',
66 'user_id': '',
67 'enable_statistics': '',
68 'clone_uri': '',
69 'fork_id': '',
70 'group_id': '',
71 'created_by': '',
72 'repository': '',
73 'comment': '',
74 'commit': ''
75 })
76 def _comment_commit_repo_hook(*args, **kwargs):
77 """
78 POST CREATE REPOSITORY COMMENT ON COMMIT HOOK. This function will be executed after
79 a comment is made on this repository commit.
80
81 """
82 return HookResponse(0, '')
83
84
85 @has_kwargs({
86 'group_name': '',
87 'group_parent_id': '',
60 'group_description': '',
88 'group_description': '',
61 'group_id': '',
89 'group_id': '',
62 'user_id': '',
90 'user_id': '',
63 'created_by': '',
91 'created_by': '',
64 'created_on': '',
92 'created_on': '',
65 'enable_locking': ''
93 'enable_locking': ''
66 })
94 })
67 def _create_repo_group_hook(*args, **kwargs):
95 def _create_repo_group_hook(*args, **kwargs):
@@ -73,13 +101,13 def _create_repo_group_hook(*args, **kwa
73
101
74
102
75 @has_kwargs({
103 @has_kwargs({
76 'username': '',
104 'username': '',
77 'password': '',
105 'password': '',
78 'email': '',
106 'email': '',
79 'firstname': '',
107 'firstname': '',
80 'lastname': '',
108 'lastname': '',
81 'active': '',
109 'active': '',
82 'admin': '',
110 'admin': '',
83 'created_by': '',
111 'created_by': '',
84 })
112 })
85 def _pre_create_user_hook(*args, **kwargs):
113 def _pre_create_user_hook(*args, **kwargs):
@@ -173,7 +201,7 def _delete_repo_hook(*args, **kwargs):
173 'emails': '',
201 'emails': '',
174 'inherit_default_permissions': '',
202 'inherit_default_permissions': '',
175 'deleted_by': '',
203 'deleted_by': '',
176 })
204 })
177 def _delete_user_hook(*args, **kwargs):
205 def _delete_user_hook(*args, **kwargs):
178 """
206 """
179 POST DELETE USER HOOK, this function will be executed after each
207 POST DELETE USER HOOK, this function will be executed after each
@@ -348,6 +376,38 def _review_pull_request_hook(*args, **k
348 'scm': 'type of version control "git", "hg", "svn"',
376 'scm': 'type of version control "git", "hg", "svn"',
349 'username': 'username of actor who triggered this event',
377 'username': 'username of actor who triggered this event',
350 'ip': 'ip address of actor who triggered this hook',
378 'ip': 'ip address of actor who triggered this hook',
379
380 'action': '',
381 'repository': 'repository name',
382 'pull_request_id': '',
383 'url': '',
384 'title': '',
385 'description': '',
386 'status': '',
387 'comment': '',
388 'created_on': '',
389 'updated_on': '',
390 'commit_ids': '',
391 'review_status': '',
392 'mergeable': '',
393 'source': '',
394 'target': '',
395 'author': '',
396 'reviewers': '',
397 })
398 def _comment_pull_request_hook(*args, **kwargs):
399 """
400 This hook will be executed after comment is made on a pull request
401 """
402 return HookResponse(0, '')
403
404
405 @has_kwargs({
406 'server_url': 'url of instance that triggered this hook',
407 'config': 'path to .ini config used',
408 'scm': 'type of version control "git", "hg", "svn"',
409 'username': 'username of actor who triggered this event',
410 'ip': 'ip address of actor who triggered this hook',
351 'action': '',
411 'action': '',
352 'repository': 'repository name',
412 'repository': 'repository name',
353 'pull_request_id': '',
413 'pull_request_id': '',
@@ -18,8 +18,10
18
18
19 import logging
19 import logging
20 import os
20 import os
21 import string
21 import functools
22 import functools
22 import collections
23 import collections
24 import urllib
23
25
24 log = logging.getLogger('rhodecode.' + __name__)
26 log = logging.getLogger('rhodecode.' + __name__)
25
27
@@ -186,4 +188,12 def aslist(obj, sep=None, strip=True):
186 elif obj is None:
188 elif obj is None:
187 return []
189 return []
188 else:
190 else:
189 return [obj] No newline at end of file
191 return [obj]
192
193
194 class UrlTemplate(string.Template):
195
196 def safe_substitute(self, **kws):
197 # url encode the kw for usage in url
198 kws = {k: urllib.quote(str(v)) for k, v in kws.items()}
199 return super(UrlTemplate, self).safe_substitute(**kws)
@@ -53,7 +53,7 from rhodecode.events.user import ( # p
53 )
53 )
54
54
55 from rhodecode.events.repo import ( # pragma: no cover
55 from rhodecode.events.repo import ( # pragma: no cover
56 RepoEvent,
56 RepoEvent, RepoCommitCommentEvent,
57 RepoPreCreateEvent, RepoCreateEvent,
57 RepoPreCreateEvent, RepoCreateEvent,
58 RepoPreDeleteEvent, RepoDeleteEvent,
58 RepoPreDeleteEvent, RepoDeleteEvent,
59 RepoPrePushEvent, RepoPushEvent,
59 RepoPrePushEvent, RepoPushEvent,
@@ -181,6 +181,20 class RepoEvent(RhodeCodeIntegrationEven
181 return data
181 return data
182
182
183
183
184 class RepoCommitCommentEvent(RepoEvent):
185 """
186 An instance of this class is emitted as an :term:`event` after a comment is made
187 on repository commit.
188 """
189 def __init__(self, repo, commit, comment):
190 super(RepoCommitCommentEvent, self).__init__(repo)
191 self.commit = commit
192 self.comment = comment
193
194 name = 'repo-commit-comment'
195 display_name = lazy_ugettext('repository commit comment')
196
197
184 class RepoPreCreateEvent(RepoEvent):
198 class RepoPreCreateEvent(RepoEvent):
185 """
199 """
186 An instance of this class is emitted as an :term:`event` before a repo is
200 An instance of this class is emitted as an :term:`event` before a repo is
@@ -24,7 +24,6 Set of hooks run by RhodeCode Enterprise
24 """
24 """
25
25
26 import os
26 import os
27 import collections
28 import logging
27 import logging
29
28
30 import rhodecode
29 import rhodecode
@@ -349,8 +348,8 class ExtensionCallback(object):
349 try:
348 try:
350 kwargs_to_pass[key] = kwargs[key]
349 kwargs_to_pass[key] = kwargs[key]
351 except KeyError:
350 except KeyError:
352 log.error('Failed to fetch %s key. Expected keys: %s',
351 log.error('Failed to fetch %s key from given kwargs. '
353 key, self._kwargs_keys)
352 'Expected keys: %s', key, self._kwargs_keys)
354 raise
353 raise
355
354
356 # backward compat for removed api_key for old hooks. This was it works
355 # backward compat for removed api_key for old hooks. This was it works
@@ -437,6 +436,15 log_review_pull_request = ExtensionCallb
437 'mergeable', 'source', 'target', 'author', 'reviewers'))
436 'mergeable', 'source', 'target', 'author', 'reviewers'))
438
437
439
438
439 log_comment_pull_request = ExtensionCallback(
440 hook_name='COMMENT_PULL_REQUEST',
441 kwargs_keys=(
442 'server_url', 'config', 'scm', 'username', 'ip', 'action',
443 'repository', 'pull_request_id', 'url', 'title', 'description',
444 'status', 'comment', 'created_on', 'updated_on', 'commit_ids', 'review_status',
445 'mergeable', 'source', 'target', 'author', 'reviewers'))
446
447
440 log_update_pull_request = ExtensionCallback(
448 log_update_pull_request = ExtensionCallback(
441 hook_name='UPDATE_PULL_REQUEST',
449 hook_name='UPDATE_PULL_REQUEST',
442 kwargs_keys=(
450 kwargs_keys=(
@@ -484,6 +492,15 log_delete_repository = ExtensionCallbac
484 'clone_uri', 'fork_id', 'group_id', 'deleted_by', 'deleted_on'))
492 'clone_uri', 'fork_id', 'group_id', 'deleted_by', 'deleted_on'))
485
493
486
494
495 log_comment_commit_repository = ExtensionCallback(
496 hook_name='COMMENT_COMMIT_REPO_HOOK',
497 kwargs_keys=(
498 'repo_name', 'repo_type', 'description', 'private', 'created_on',
499 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics',
500 'clone_uri', 'fork_id', 'group_id',
501 'repository', 'created_by', 'comment', 'commit'))
502
503
487 log_create_repository_group = ExtensionCallback(
504 log_create_repository_group = ExtensionCallback(
488 hook_name='CREATE_REPO_GROUP_HOOK',
505 hook_name='CREATE_REPO_GROUP_HOOK',
489 kwargs_keys=(
506 kwargs_keys=(
@@ -26,144 +26,190 from rhodecode.lib import hooks_base
26 from rhodecode.lib import utils2
26 from rhodecode.lib import utils2
27
27
28
28
29 def _get_rc_scm_extras(username, repo_name, repo_alias, action):
29 def _supports_repo_type(repo_type):
30 # TODO: johbo: Replace by vcs_operation_context and remove fully
30 if repo_type in ('hg', 'git'):
31 return True
32 return False
33
34
35 def _get_vcs_operation_context(username, repo_name, repo_type, action):
36 # NOTE(dan): import loop
31 from rhodecode.lib.base import vcs_operation_context
37 from rhodecode.lib.base import vcs_operation_context
38
32 check_locking = action in ('pull', 'push')
39 check_locking = action in ('pull', 'push')
33
40
34 request = get_current_request()
41 request = get_current_request()
35
42
36 # default
37 dummy_environ = webob.Request.blank('').environ
38 try:
43 try:
39 environ = request.environ or dummy_environ
44 environ = request.environ
40 except TypeError:
45 except TypeError:
41 # we might use this outside of request context
46 # we might use this outside of request context
42 environ = dummy_environ
47 environ = {}
43
48
44 extras = vcs_operation_context(
49 if not environ:
45 environ, repo_name, username, action, repo_alias, check_locking)
50 environ = webob.Request.blank('').environ
51
52 extras = vcs_operation_context(environ, repo_name, username, action, repo_type, check_locking)
46 return utils2.AttributeDict(extras)
53 return utils2.AttributeDict(extras)
47
54
48
55
49 def trigger_post_push_hook(
56 def trigger_post_push_hook(username, action, hook_type, repo_name, repo_type, commit_ids):
50 username, action, hook_type, repo_name, repo_alias, commit_ids):
51 """
57 """
52 Triggers push action hooks
58 Triggers push action hooks
53
59
54 :param username: username who pushes
60 :param username: username who pushes
55 :param action: push/push_local/push_remote
61 :param action: push/push_local/push_remote
62 :param hook_type: type of hook executed
56 :param repo_name: name of repo
63 :param repo_name: name of repo
57 :param repo_alias: the type of SCM repo
64 :param repo_type: the type of SCM repo
58 :param commit_ids: list of commit ids that we pushed
65 :param commit_ids: list of commit ids that we pushed
59 """
66 """
60 extras = _get_rc_scm_extras(username, repo_name, repo_alias, action)
67 extras = _get_vcs_operation_context(username, repo_name, repo_type, action)
61 extras.commit_ids = commit_ids
68 extras.commit_ids = commit_ids
62 extras.hook_type = hook_type
69 extras.hook_type = hook_type
63 hooks_base.post_push(extras)
70 hooks_base.post_push(extras)
64
71
65
72
66 def trigger_log_create_pull_request_hook(username, repo_name, repo_alias,
73 def trigger_comment_commit_hooks(username, repo_name, repo_type, repo, data=None):
67 pull_request, data=None):
74 """
75 Triggers when a comment is made on a commit
76
77 :param username: username who creates the comment
78 :param repo_name: name of target repo
79 :param repo_type: the type of SCM target repo
80 :param repo: the repo object we trigger the event for
81 :param data: extra data for specific events e.g {'comment': comment_obj, 'commit': commit_obj}
82 """
83 if not _supports_repo_type(repo_type):
84 return
85
86 extras = _get_vcs_operation_context(username, repo_name, repo_type, 'comment_commit')
87
88 comment = data['comment']
89 commit = data['commit']
90
91 events.trigger(events.RepoCommitCommentEvent(repo, commit, comment))
92 extras.update(repo.get_dict())
93
94 extras.commit = commit.serialize()
95 extras.comment = comment.get_api_data()
96 extras.created_by = username
97 hooks_base.log_comment_commit_repository(**extras)
98
99
100 def trigger_create_pull_request_hook(username, repo_name, repo_type, pull_request, data=None):
68 """
101 """
69 Triggers create pull request action hooks
102 Triggers create pull request action hooks
70
103
71 :param username: username who creates the pull request
104 :param username: username who creates the pull request
72 :param repo_name: name of target repo
105 :param repo_name: name of target repo
73 :param repo_alias: the type of SCM target repo
106 :param repo_type: the type of SCM target repo
74 :param pull_request: the pull request that was created
107 :param pull_request: the pull request that was created
75 :param data: extra data for specific events e.g {'comment': comment_obj}
108 :param data: extra data for specific events e.g {'comment': comment_obj}
76 """
109 """
77 if repo_alias not in ('hg', 'git'):
110 if not _supports_repo_type(repo_type):
78 return
111 return
79
112
80 extras = _get_rc_scm_extras(username, repo_name, repo_alias,
113 extras = _get_vcs_operation_context(username, repo_name, repo_type, 'create_pull_request')
81 'create_pull_request')
82 events.trigger(events.PullRequestCreateEvent(pull_request))
114 events.trigger(events.PullRequestCreateEvent(pull_request))
83 extras.update(pull_request.get_api_data(with_merge_state=False))
115 extras.update(pull_request.get_api_data(with_merge_state=False))
84 hooks_base.log_create_pull_request(**extras)
116 hooks_base.log_create_pull_request(**extras)
85
117
86
118
87 def trigger_log_merge_pull_request_hook(username, repo_name, repo_alias,
119 def trigger_merge_pull_request_hook(username, repo_name, repo_type, pull_request, data=None):
88 pull_request, data=None):
89 """
120 """
90 Triggers merge pull request action hooks
121 Triggers merge pull request action hooks
91
122
92 :param username: username who creates the pull request
123 :param username: username who creates the pull request
93 :param repo_name: name of target repo
124 :param repo_name: name of target repo
94 :param repo_alias: the type of SCM target repo
125 :param repo_type: the type of SCM target repo
95 :param pull_request: the pull request that was merged
126 :param pull_request: the pull request that was merged
96 :param data: extra data for specific events e.g {'comment': comment_obj}
127 :param data: extra data for specific events e.g {'comment': comment_obj}
97 """
128 """
98 if repo_alias not in ('hg', 'git'):
129 if not _supports_repo_type(repo_type):
99 return
130 return
100
131
101 extras = _get_rc_scm_extras(username, repo_name, repo_alias,
132 extras = _get_vcs_operation_context(username, repo_name, repo_type, 'merge_pull_request')
102 'merge_pull_request')
103 events.trigger(events.PullRequestMergeEvent(pull_request))
133 events.trigger(events.PullRequestMergeEvent(pull_request))
104 extras.update(pull_request.get_api_data())
134 extras.update(pull_request.get_api_data())
105 hooks_base.log_merge_pull_request(**extras)
135 hooks_base.log_merge_pull_request(**extras)
106
136
107
137
108 def trigger_log_close_pull_request_hook(username, repo_name, repo_alias,
138 def trigger_close_pull_request_hook(username, repo_name, repo_type, pull_request, data=None):
109 pull_request, data=None):
110 """
139 """
111 Triggers close pull request action hooks
140 Triggers close pull request action hooks
112
141
113 :param username: username who creates the pull request
142 :param username: username who creates the pull request
114 :param repo_name: name of target repo
143 :param repo_name: name of target repo
115 :param repo_alias: the type of SCM target repo
144 :param repo_type: the type of SCM target repo
116 :param pull_request: the pull request that was closed
145 :param pull_request: the pull request that was closed
117 :param data: extra data for specific events e.g {'comment': comment_obj}
146 :param data: extra data for specific events e.g {'comment': comment_obj}
118 """
147 """
119 if repo_alias not in ('hg', 'git'):
148 if not _supports_repo_type(repo_type):
120 return
149 return
121
150
122 extras = _get_rc_scm_extras(username, repo_name, repo_alias,
151 extras = _get_vcs_operation_context(username, repo_name, repo_type, 'close_pull_request')
123 'close_pull_request')
124 events.trigger(events.PullRequestCloseEvent(pull_request))
152 events.trigger(events.PullRequestCloseEvent(pull_request))
125 extras.update(pull_request.get_api_data())
153 extras.update(pull_request.get_api_data())
126 hooks_base.log_close_pull_request(**extras)
154 hooks_base.log_close_pull_request(**extras)
127
155
128
156
129 def trigger_log_review_pull_request_hook(username, repo_name, repo_alias,
157 def trigger_review_pull_request_hook(username, repo_name, repo_type, pull_request, data=None):
130 pull_request, data=None):
131 """
158