hooks: added new hooks for comments on pull requests and commits.

- allows writing custom actions on top of comments
- new rcextension hooks
- organized and renamed some hooks
- new helpers for rcextensions
- fixes #5583
This commit is contained in:
Daniel Dourvaris 2020-04-15 18:00:59 +02:00
parent 1e8d393f02
commit 466826a84a
19 changed files with 386 additions and 110 deletions

View file

@ -1599,7 +1599,8 @@ def comment_commit(
validate_repo_permissions(apiuser, repoid, repo, _perms)
try:
commit_id = repo.scm_instance().get_commit(commit_id=commit_id).raw_id
commit = repo.scm_instance().get_commit(commit_id=commit_id)
commit_id = commit.raw_id
except Exception as e:
log.exception('Failed to fetch commit')
raise JSONRPCError(safe_str(e))
@ -1659,6 +1660,10 @@ def comment_commit(
'a closed pull request is not allowed')
raise JSONRPCError(msg)
CommentsModel().trigger_commit_comment_hook(
repo, apiuser, 'create',
data={'comment': comment, 'commit': commit})
Session().commit()
return {
'msg': (

View file

@ -380,6 +380,11 @@ class RepoCommitsView(RepoAppView):
'repo_commit', repo_name=self.db_repo_name,
commit_id=current_id))
commit = self.db_repo.get_commit(current_id)
CommentsModel().trigger_commit_comment_hook(
self.db_repo, self._rhodecode_user, 'create',
data={'comment': comment, 'commit': commit})
# finalize, commit and redirect
Session().commit()

View file

@ -25,6 +25,7 @@ from .hooks import (
_create_repo_group_hook,
_pre_create_user_hook,
_create_user_hook,
_comment_commit_repo_hook,
_delete_repo_hook,
_delete_user_hook,
_pre_push_hook,
@ -33,6 +34,7 @@ from .hooks import (
_pull_hook,
_create_pull_request_hook,
_review_pull_request_hook,
_comment_pull_request_hook,
_update_pull_request_hook,
_merge_pull_request_hook,
_close_pull_request_hook,
@ -40,6 +42,7 @@ from .hooks import (
# set as module attributes, we use those to call hooks. *do not change this*
CREATE_REPO_HOOK = _create_repo_hook
COMMENT_COMMIT_REPO_HOOK = _comment_commit_repo_hook
CREATE_REPO_GROUP_HOOK = _create_repo_group_hook
PRE_CREATE_USER_HOOK = _pre_create_user_hook
CREATE_USER_HOOK = _create_user_hook
@ -51,6 +54,7 @@ PRE_PULL_HOOK = _pre_pull_hook
PULL_HOOK = _pull_hook
CREATE_PULL_REQUEST = _create_pull_request_hook
REVIEW_PULL_REQUEST = _review_pull_request_hook
COMMENT_PULL_REQUEST = _comment_pull_request_hook
UPDATE_PULL_REQUEST = _update_pull_request_hook
MERGE_PULL_REQUEST = _merge_pull_request_hook
CLOSE_PULL_REQUEST = _close_pull_request_hook

View file

@ -24,14 +24,13 @@ def _push_hook(*args, **kwargs):
# returns list of dicts with key-val fetched from extra fields
repo_extra_fields = extra_fields.run(**kwargs)
if repo_extra_fields.get('endpoint_url'):
field_metadata = repo_extra_fields['endpoint_url']
endpoint = field_metadata['field_value']
if endpoint:
data = {
'project': kwargs['repository'],
}
response = http_call.run(url=endpoint, params=data)
return HookResponse(0, 'Called endpoint {}, with response {}\n'.format(endpoint, response))
endpoint_url = extra_fields.get_field(repo_extra_fields, key='endpoint_url', default='')
if endpoint_url:
data = {
'project': kwargs['repository'],
}
response = http_call.run(url=endpoint_url, params=data)
return HookResponse(0, 'Called endpoint {}, with response {}\n'.format(endpoint_url, response))
return HookResponse(0, '')

View file

@ -24,14 +24,12 @@ def _push_hook(*args, **kwargs):
# returns list of dicts with key-val fetched from extra fields
repo_extra_fields = extra_fields.run(**kwargs)
if repo_extra_fields.get('endpoint_url'):
field_metadata = repo_extra_fields['endpoint_url']
endpoint = field_metadata['field_value']
if endpoint:
data = {
'some_key': 'val'
}
response = http_call.run(url=endpoint, json_data=data)
return HookResponse(0, 'Called endpoint {}, with response {}'.format(endpoint, response))
endpoint_url = extra_fields.get_field(repo_extra_fields, key='endpoint_url', default='')
if endpoint_url:
data = {
'some_key': 'val'
}
response = http_call.run(url=endpoint_url, json_data=data)
return HookResponse(0, 'Called endpoint {}, with response {}'.format(endpoint_url, response))
return HookResponse(0, '')

View file

@ -0,0 +1,60 @@
# Example to trigger a CI call action on specific comment text, e.g chatops and ci
# rebuild on mention of ci bot
@has_kwargs({
'repo_name': '',
'repo_type': '',
'description': '',
'private': '',
'created_on': '',
'enable_downloads': '',
'repo_id': '',
'user_id': '',
'enable_statistics': '',
'clone_uri': '',
'fork_id': '',
'group_id': '',
'created_by': '',
'repository': '',
'comment': '',
'commit': ''
})
def _comment_commit_repo_hook(*args, **kwargs):
"""
POST CREATE REPOSITORY COMMENT ON COMMIT HOOK. This function will be executed after
a comment is made on this repository commit.
"""
from .helpers import http_call, extra_fields
from .utils import UrlTemplate
# returns list of dicts with key-val fetched from extra fields
repo_extra_fields = extra_fields.run(**kwargs)
import rhodecode
from rc_integrations.jenkins_ci import csrf_call, get_auth, requests_retry_call
endpoint_url = extra_fields.get_field(
repo_extra_fields, key='ci_endpoint_url',
default='http://ci.rc.com/job/rc-ce-commits/build?COMMIT_ID=${commit}')
mention_text = extra_fields.get_field(
repo_extra_fields, key='ci_mention_text',
default='@jenkins build')
endpoint_url = UrlTemplate(endpoint_url).safe_substitute(
commit=kwargs['commit']['raw_id'])
trigger_ci = False
comment = kwargs['comment']['comment_text']
if mention_text in comment:
trigger_ci = True
if trigger_ci is False:
return HookResponse(0, '')
# call some CI based on the special coment mention marker
data = {
'project': kwargs['repository'],
}
response = http_call.run(url=endpoint_url, params=data)
return HookResponse(0, '')

View file

@ -41,11 +41,13 @@ def _pre_push_hook(*args, **kwargs):
repo_extra_fields = extra_fields.run(**kwargs)
# optionally use 'extra fields' to control the logic per repo
validate_author = repo_extra_fields.get('validate_author', {}).get('field_value')
validate_author = extra_fields.get_field(
repo_extra_fields, key='validate_author', default=False)
should_validate = str2bool(validate_author)
# optionally store validation regex into extra fields
validation_regex = repo_extra_fields.get('validation_regex', {}).get('field_value')
validation_regex = extra_fields.get_field(
repo_extra_fields, key='validation_regex', default='')
def validate_commit_message(commit_message, message_regex=None):
"""

View file

@ -44,13 +44,16 @@ def _pre_push_hook(*args, **kwargs):
# optionally use 'extra fields' to control the logic per repo
# e.g store a list of patterns to be forbidden e.g `*.exe, *.dump`
forbid_files = repo_extra_fields.get('forbid_files_glob', {}).get('field_value')
forbid_files = extra_fields.get_field(repo_extra_fields, key='forbid_files_glob',
convert_type=False, default=[])
forbid_files = aslist(forbid_files)
# forbid_files = ['*'] # example pattern
# optionally get bytes limit for a single file, e.g 1024 for 1KB
forbid_size_over = repo_extra_fields.get('forbid_size_over', {}).get('field_value')
forbid_size_over = extra_fields.get_field(repo_extra_fields, key='forbid_size_over',
convert_type=False, default=0)
forbid_size_over = int(forbid_size_over or 0)
# forbid_size_over = 1024 # example 1024

View file

@ -53,3 +53,36 @@ def run(*args, **kwargs):
fields[field.field_key] = field.get_dict()
return fields
class _Undefined(object):
pass
def get_field(extra_fields_data, key, default=_Undefined(), convert_type=True):
"""
field_value = get_field(extra_fields, key='ci_endpoint_url', default='')
"""
from ..utils import str2bool, aslist
if key not in extra_fields_data:
if isinstance(default, _Undefined):
raise ValueError('key {} not present in extra_fields'.format(key))
return default
# NOTE(dan): from metadata we get field_label, field_value, field_desc, field_type
field_metadata = extra_fields_data[key]
field_value = field_metadata['field_value']
# NOTE(dan): empty value, use default
if not field_value and not isinstance(default, _Undefined):
return default
if convert_type:
# 'str', 'unicode', 'list', 'tuple'
_type = field_metadata['field_type']
if _type in ['list', 'tuple']:
field_value = aslist(field_value)
return field_value

View file

@ -15,10 +15,11 @@
# This program is dual-licensed. If you wish to learn more about the
# RhodeCode Enterprise Edition, including its added features, Support services,
# and proprietary license terms, please see https://rhodecode.com/licenses/
import logging
from .utils import DotDict, HookResponse, has_kwargs
log = logging.getLogger('rhodecode.' + __name__)
log = logging.getLogger('rhodecode.' + __name__)
# Config shortcut to keep, all configuration in one place
# Example: api_key = CONFIG.my_config.api_key
@ -55,13 +56,40 @@ def _create_repo_hook(*args, **kwargs):
@has_kwargs({
'group_name': '',
'group_parent_id': '',
'repo_name': '',
'repo_type': '',
'description': '',
'private': '',
'created_on': '',
'enable_downloads': '',
'repo_id': '',
'user_id': '',
'enable_statistics': '',
'clone_uri': '',
'fork_id': '',
'group_id': '',
'created_by': '',
'repository': '',
'comment': '',
'commit': ''
})
def _comment_commit_repo_hook(*args, **kwargs):
"""
POST CREATE REPOSITORY COMMENT ON COMMIT HOOK. This function will be executed after
a comment is made on this repository commit.
"""
return HookResponse(0, '')
@has_kwargs({
'group_name': '',
'group_parent_id': '',
'group_description': '',
'group_id': '',
'user_id': '',
'created_by': '',
'created_on': '',
'group_id': '',
'user_id': '',
'created_by': '',
'created_on': '',
'enable_locking': ''
})
def _create_repo_group_hook(*args, **kwargs):
@ -73,13 +101,13 @@ def _create_repo_group_hook(*args, **kwargs):
@has_kwargs({
'username': '',
'password': '',
'email': '',
'username': '',
'password': '',
'email': '',
'firstname': '',
'lastname': '',
'active': '',
'admin': '',
'lastname': '',
'active': '',
'admin': '',
'created_by': '',
})
def _pre_create_user_hook(*args, **kwargs):
@ -173,7 +201,7 @@ def _delete_repo_hook(*args, **kwargs):
'emails': '',
'inherit_default_permissions': '',
'deleted_by': '',
})
})
def _delete_user_hook(*args, **kwargs):
"""
POST DELETE USER HOOK, this function will be executed after each
@ -342,6 +370,38 @@ def _review_pull_request_hook(*args, **kwargs):
return HookResponse(0, '')
@has_kwargs({
'server_url': 'url of instance that triggered this hook',
'config': 'path to .ini config used',
'scm': 'type of version control "git", "hg", "svn"',
'username': 'username of actor who triggered this event',
'ip': 'ip address of actor who triggered this hook',
'action': '',
'repository': 'repository name',
'pull_request_id': '',
'url': '',
'title': '',
'description': '',
'status': '',
'comment': '',
'created_on': '',
'updated_on': '',
'commit_ids': '',
'review_status': '',
'mergeable': '',
'source': '',
'target': '',
'author': '',
'reviewers': '',
})
def _comment_pull_request_hook(*args, **kwargs):
"""
This hook will be executed after comment is made on a pull request
"""
return HookResponse(0, '')
@has_kwargs({
'server_url': 'url of instance that triggered this hook',
'config': 'path to .ini config used',

View file

@ -18,8 +18,10 @@
import logging
import os
import string
import functools
import collections
import urllib
log = logging.getLogger('rhodecode.' + __name__)
@ -186,4 +188,12 @@ def aslist(obj, sep=None, strip=True):
elif obj is None:
return []
else:
return [obj]
return [obj]
class UrlTemplate(string.Template):
def safe_substitute(self, **kws):
# url encode the kw for usage in url
kws = {k: urllib.quote(str(v)) for k, v in kws.items()}
return super(UrlTemplate, self).safe_substitute(**kws)

View file

@ -53,7 +53,7 @@ from rhodecode.events.user import ( # pragma: no cover
)
from rhodecode.events.repo import ( # pragma: no cover
RepoEvent,
RepoEvent, RepoCommitCommentEvent,
RepoPreCreateEvent, RepoCreateEvent,
RepoPreDeleteEvent, RepoDeleteEvent,
RepoPrePushEvent, RepoPushEvent,

View file

@ -181,6 +181,20 @@ class RepoEvent(RhodeCodeIntegrationEvent):
return data
class RepoCommitCommentEvent(RepoEvent):
"""
An instance of this class is emitted as an :term:`event` after a comment is made
on repository commit.
"""
def __init__(self, repo, commit, comment):
super(RepoCommitCommentEvent, self).__init__(repo)
self.commit = commit
self.comment = comment
name = 'repo-commit-comment'
display_name = lazy_ugettext('repository commit comment')
class RepoPreCreateEvent(RepoEvent):
"""
An instance of this class is emitted as an :term:`event` before a repo is

View file

@ -24,7 +24,6 @@ Set of hooks run by RhodeCode Enterprise
"""
import os
import collections
import logging
import rhodecode
@ -349,8 +348,8 @@ class ExtensionCallback(object):
try:
kwargs_to_pass[key] = kwargs[key]
except KeyError:
log.error('Failed to fetch %s key. Expected keys: %s',
key, self._kwargs_keys)
log.error('Failed to fetch %s key from given kwargs. '
'Expected keys: %s', key, self._kwargs_keys)
raise
# backward compat for removed api_key for old hooks. This was it works
@ -437,6 +436,15 @@ log_review_pull_request = ExtensionCallback(
'mergeable', 'source', 'target', 'author', 'reviewers'))
log_comment_pull_request = ExtensionCallback(
hook_name='COMMENT_PULL_REQUEST',
kwargs_keys=(
'server_url', 'config', 'scm', 'username', 'ip', 'action',
'repository', 'pull_request_id', 'url', 'title', 'description',
'status', 'comment', 'created_on', 'updated_on', 'commit_ids', 'review_status',
'mergeable', 'source', 'target', 'author', 'reviewers'))
log_update_pull_request = ExtensionCallback(
hook_name='UPDATE_PULL_REQUEST',
kwargs_keys=(
@ -484,6 +492,15 @@ log_delete_repository = ExtensionCallback(
'clone_uri', 'fork_id', 'group_id', 'deleted_by', 'deleted_on'))
log_comment_commit_repository = ExtensionCallback(
hook_name='COMMENT_COMMIT_REPO_HOOK',
kwargs_keys=(
'repo_name', 'repo_type', 'description', 'private', 'created_on',
'enable_downloads', 'repo_id', 'user_id', 'enable_statistics',
'clone_uri', 'fork_id', 'group_id',
'repository', 'created_by', 'comment', 'commit'))
log_create_repository_group = ExtensionCallback(
hook_name='CREATE_REPO_GROUP_HOOK',
kwargs_keys=(

View file

@ -26,144 +26,190 @@ from rhodecode.lib import hooks_base
from rhodecode.lib import utils2
def _get_rc_scm_extras(username, repo_name, repo_alias, action):
# TODO: johbo: Replace by vcs_operation_context and remove fully
def _supports_repo_type(repo_type):
if repo_type in ('hg', 'git'):
return True
return False
def _get_vcs_operation_context(username, repo_name, repo_type, action):
# NOTE(dan): import loop
from rhodecode.lib.base import vcs_operation_context
check_locking = action in ('pull', 'push')
request = get_current_request()
# default
dummy_environ = webob.Request.blank('').environ
try:
environ = request.environ or dummy_environ
environ = request.environ
except TypeError:
# we might use this outside of request context
environ = dummy_environ
environ = {}
extras = vcs_operation_context(
environ, repo_name, username, action, repo_alias, check_locking)
if not environ:
environ = webob.Request.blank('').environ
extras = vcs_operation_context(environ, repo_name, username, action, repo_type, check_locking)
return utils2.AttributeDict(extras)
def trigger_post_push_hook(
username, action, hook_type, repo_name, repo_alias, commit_ids):
def trigger_post_push_hook(username, action, hook_type, repo_name, repo_type, commit_ids):
"""
Triggers push action hooks
:param username: username who pushes
:param action: push/push_local/push_remote
:param hook_type: type of hook executed
:param repo_name: name of repo
:param repo_alias: the type of SCM repo
:param repo_type: the type of SCM repo
:param commit_ids: list of commit ids that we pushed
"""
extras = _get_rc_scm_extras(username, repo_name, repo_alias, action)
extras = _get_vcs_operation_context(username, repo_name, repo_type, action)
extras.commit_ids = commit_ids
extras.hook_type = hook_type
hooks_base.post_push(extras)
def trigger_log_create_pull_request_hook(username, repo_name, repo_alias,
pull_request, data=None):
def trigger_comment_commit_hooks(username, repo_name, repo_type, repo, data=None):
"""
Triggers when a comment is made on a commit
:param username: username who creates the comment
:param repo_name: name of target repo
:param repo_type: the type of SCM target repo
:param repo: the repo object we trigger the event for
:param data: extra data for specific events e.g {'comment': comment_obj, 'commit': commit_obj}
"""
if not _supports_repo_type(repo_type):
return
extras = _get_vcs_operation_context(username, repo_name, repo_type, 'comment_commit')
comment = data['comment']
commit = data['commit']
events.trigger(events.RepoCommitCommentEvent(repo, commit, comment))
extras.update(repo.get_dict())
extras.commit = commit.serialize()
extras.comment = comment.get_api_data()
extras.created_by = username
hooks_base.log_comment_commit_repository(**extras)
def trigger_create_pull_request_hook(username, repo_name, repo_type, pull_request, data=None):
"""
Triggers create pull request action hooks
:param username: username who creates the pull request
:param repo_name: name of target repo
:param repo_alias: the type of SCM target repo
:param repo_type: the type of SCM target repo
:param pull_request: the pull request that was created
:param data: extra data for specific events e.g {'comment': comment_obj}
"""
if repo_alias not in ('hg', 'git'):
if not _supports_repo_type(repo_type):
return
extras = _get_rc_scm_extras(username, repo_name, repo_alias,
'create_pull_request')
extras = _get_vcs_operation_context(username, repo_name, repo_type, 'create_pull_request')
events.trigger(events.PullRequestCreateEvent(pull_request))
extras.update(pull_request.get_api_data(with_merge_state=False))
hooks_base.log_create_pull_request(**extras)
def trigger_log_merge_pull_request_hook(username, repo_name, repo_alias,
pull_request, data=None):
def trigger_merge_pull_request_hook(username, repo_name, repo_type, pull_request, data=None):
"""
Triggers merge pull request action hooks
:param username: username who creates the pull request
:param repo_name: name of target repo
:param repo_alias: the type of SCM target repo
:param repo_type: the type of SCM target repo
:param pull_request: the pull request that was merged
:param data: extra data for specific events e.g {'comment': comment_obj}
"""
if repo_alias not in ('hg', 'git'):
if not _supports_repo_type(repo_type):
return
extras = _get_rc_scm_extras(username, repo_name, repo_alias,
'merge_pull_request')
extras = _get_vcs_operation_context(username, repo_name, repo_type, 'merge_pull_request')
events.trigger(events.PullRequestMergeEvent(pull_request))
extras.update(pull_request.get_api_data())
hooks_base.log_merge_pull_request(**extras)
def trigger_log_close_pull_request_hook(username, repo_name, repo_alias,
pull_request, data=None):
def trigger_close_pull_request_hook(username, repo_name, repo_type, pull_request, data=None):
"""
Triggers close pull request action hooks
:param username: username who creates the pull request
:param repo_name: name of target repo
:param repo_alias: the type of SCM target repo
:param repo_type: the type of SCM target repo
:param pull_request: the pull request that was closed
:param data: extra data for specific events e.g {'comment': comment_obj}
"""
if repo_alias not in ('hg', 'git'):
if not _supports_repo_type(repo_type):
return
extras = _get_rc_scm_extras(username, repo_name, repo_alias,
'close_pull_request')
extras = _get_vcs_operation_context(username, repo_name, repo_type, 'close_pull_request')
events.trigger(events.PullRequestCloseEvent(pull_request))
extras.update(pull_request.get_api_data())
hooks_base.log_close_pull_request(**extras)
def trigger_log_review_pull_request_hook(username, repo_name, repo_alias,
pull_request, data=None):
def trigger_review_pull_request_hook(username, repo_name, repo_type, pull_request, data=None):
"""
Triggers review status change pull request action hooks
:param username: username who creates the pull request
:param repo_name: name of target repo
:param repo_alias: the type of SCM target repo
:param repo_type: the type of SCM target repo
:param pull_request: the pull request that review status changed
:param data: extra data for specific events e.g {'comment': comment_obj}
"""
if repo_alias not in ('hg', 'git'):
if not _supports_repo_type(repo_type):
return
extras = _get_rc_scm_extras(username, repo_name, repo_alias,
'review_pull_request')
extras = _get_vcs_operation_context(username, repo_name, repo_type, 'review_pull_request')
status = data.get('status')
events.trigger(events.PullRequestReviewEvent(pull_request, status))
extras.update(pull_request.get_api_data())
hooks_base.log_review_pull_request(**extras)
def trigger_log_update_pull_request_hook(username, repo_name, repo_alias,
pull_request, data=None):
def trigger_comment_pull_request_hook(username, repo_name, repo_type, pull_request, data=None):
"""
Triggers when a comment is made on a pull request
:param username: username who creates the pull request
:param repo_name: name of target repo
:param repo_type: the type of SCM target repo
:param pull_request: the pull request that comment was made on
:param data: extra data for specific events e.g {'comment': comment_obj}
"""
if not _supports_repo_type(repo_type):
return
extras = _get_vcs_operation_context(username, repo_name, repo_type, 'comment_pull_request')
comment = data['comment']
events.trigger(events.PullRequestCommentEvent(pull_request, comment))
extras.update(pull_request.get_api_data())
extras.comment = comment.get_api_data()
hooks_base.log_comment_pull_request(**extras)
def trigger_update_pull_request_hook(username, repo_name, repo_type, pull_request, data=None):
"""
Triggers update pull request action hooks
:param username: username who creates the pull request
:param repo_name: name of target repo
:param repo_alias: the type of SCM target repo
:param repo_type: the type of SCM target repo
:param pull_request: the pull request that was updated
:param data: extra data for specific events e.g {'comment': comment_obj}
"""
if repo_alias not in ('hg', 'git'):
if not _supports_repo_type(repo_type):
return
extras = _get_rc_scm_extras(username, repo_name, repo_alias,
'update_pull_request')
extras = _get_vcs_operation_context(username, repo_name, repo_type, 'update_pull_request')
events.trigger(events.PullRequestUpdateEvent(pull_request))
extras.update(pull_request.get_api_data())
hooks_base.log_update_pull_request(**extras)

View file

@ -925,6 +925,9 @@ class BaseCommit(object):
d.pop('repository', None)
return d
def serialize(self):
return self.__json__()
def _get_refs(self):
return {
'branches': [self.branch] if self.branch else [],

View file

@ -30,7 +30,7 @@ from pyramid.threadlocal import get_current_registry, get_current_request
from sqlalchemy.sql.expression import null
from sqlalchemy.sql.functions import coalesce
from rhodecode.lib import helpers as h, diffs, channelstream
from rhodecode.lib import helpers as h, diffs, channelstream, hooks_utils
from rhodecode.lib import audit_logger
from rhodecode.lib.utils2 import extract_mentioned_users, safe_str
from rhodecode.model import BaseModel
@ -720,6 +720,26 @@ class CommentsModel(BaseModel):
settings = settings_model.get_general_settings()
return settings.get('rhodecode_use_outdated_comments', False)
def trigger_commit_comment_hook(self, repo, user, action, data=None):
repo = self._get_repo(repo)
target_scm = repo.scm_instance()
if action == 'create':
trigger_hook = hooks_utils.trigger_comment_commit_hooks
elif action == 'edit':
# TODO(dan): when this is supported we trigger edit hook too
return
else:
return
log.debug('Handling repo %s trigger_commit_comment_hook with action %s: %s',
repo, action, trigger_hook)
trigger_hook(
username=user.username,
repo_name=repo.repo_name,
repo_type=target_scm.alias,
repo=repo,
data=data)
def _parse_comment_line_number(line_no):
"""

View file

@ -542,8 +542,7 @@ class PullRequestModel(BaseModel):
pull_request, auth_user=auth_user, translator=translator)
self.notify_reviewers(pull_request, reviewer_ids)
self.trigger_pull_request_hook(
pull_request, created_by_user, 'create')
self.trigger_pull_request_hook(pull_request, created_by_user, 'create')
creation_data = pull_request.get_api_data(with_merge_state=False)
self._log_audit_action(
@ -556,28 +555,26 @@ class PullRequestModel(BaseModel):
pull_request = self.__get_pull_request(pull_request)
target_scm = pull_request.target_repo.scm_instance()
if action == 'create':
trigger_hook = hooks_utils.trigger_log_create_pull_request_hook
trigger_hook = hooks_utils.trigger_create_pull_request_hook
elif action == 'merge':
trigger_hook = hooks_utils.trigger_log_merge_pull_request_hook
trigger_hook = hooks_utils.trigger_merge_pull_request_hook
elif action == 'close':
trigger_hook = hooks_utils.trigger_log_close_pull_request_hook
trigger_hook = hooks_utils.trigger_close_pull_request_hook
elif action == 'review_status_change':
trigger_hook = hooks_utils.trigger_log_review_pull_request_hook
trigger_hook = hooks_utils.trigger_review_pull_request_hook
elif action == 'update':
trigger_hook = hooks_utils.trigger_log_update_pull_request_hook
trigger_hook = hooks_utils.trigger_update_pull_request_hook
elif action == 'comment':
# dummy hook ! for comment. We want this function to handle all cases
def trigger_hook(*args, **kwargs):
pass
comment = data['comment']
events.trigger(events.PullRequestCommentEvent(pull_request, comment))
trigger_hook = hooks_utils.trigger_comment_pull_request_hook
else:
return
log.debug('Handling pull_request %s trigger_pull_request_hook with action %s and hook: %s',
pull_request, action, trigger_hook)
trigger_hook(
username=user.username,
repo_name=pull_request.target_repo.repo_name,
repo_alias=target_scm.alias,
repo_type=target_scm.alias,
pull_request=pull_request,
data=data)
@ -1286,8 +1283,7 @@ class PullRequestModel(BaseModel):
pull_request.status = PullRequest.STATUS_CLOSED
pull_request.updated_on = datetime.datetime.now()
Session().add(pull_request)
self.trigger_pull_request_hook(
pull_request, pull_request.author, 'close')
self.trigger_pull_request_hook(pull_request, pull_request.author, 'close')
pr_data = pull_request.get_api_data(with_merge_state=False)
self._log_audit_action(
@ -1333,20 +1329,21 @@ class PullRequestModel(BaseModel):
)
Session().flush()
events.trigger(events.PullRequestCommentEvent(pull_request, comment))
self.trigger_pull_request_hook(pull_request, user, 'comment',
data={'comment': comment})
# we now calculate the status of pull request again, and based on that
# calculation trigger status change. This might happen in cases
# that non-reviewer admin closes a pr, which means his vote doesn't
# change the status, while if he's a reviewer this might change it.
calculated_status = pull_request.calculated_review_status()
if old_calculated_status != calculated_status:
self.trigger_pull_request_hook(
pull_request, user, 'review_status_change',
data={'status': calculated_status})
self.trigger_pull_request_hook(pull_request, user, 'review_status_change',
data={'status': calculated_status})
# finally close the PR
PullRequestModel().close_pull_request(
pull_request.pull_request_id, user)
PullRequestModel().close_pull_request(pull_request.pull_request_id, user)
return comment, status

View file

@ -473,7 +473,7 @@ class ScmModel(BaseModel):
# We trigger the post-push action
hooks_utils.trigger_post_push_hook(
username=user.username, action='push_local', hook_type='post_push',
repo_name=repo_name, repo_alias=repo.alias, commit_ids=[tip.raw_id])
repo_name=repo_name, repo_type=repo.alias, commit_ids=[tip.raw_id])
return tip
def _sanitize_path(self, f_path):
@ -799,7 +799,7 @@ class ScmModel(BaseModel):
if trigger_push_hook:
hooks_utils.trigger_post_push_hook(
username=user.username, action='push_local',
repo_name=repo.repo_name, repo_alias=scm_instance.alias,
repo_name=repo.repo_name, repo_type=scm_instance.alias,
hook_type='post_push',
commit_ids=[tip.raw_id])
return tip
@ -864,7 +864,7 @@ class ScmModel(BaseModel):
if trigger_push_hook:
hooks_utils.trigger_post_push_hook(
username=user.username, action='push_local', hook_type='post_push',
repo_name=repo.repo_name, repo_alias=scm_instance.alias,
repo_name=repo.repo_name, repo_type=scm_instance.alias,
commit_ids=[tip.raw_id])
return tip
@ -926,7 +926,7 @@ class ScmModel(BaseModel):
if trigger_push_hook:
hooks_utils.trigger_post_push_hook(
username=user.username, action='push_local', hook_type='post_push',
repo_name=repo.repo_name, repo_alias=scm_instance.alias,
repo_name=repo.repo_name, repo_type=scm_instance.alias,
commit_ids=[tip.raw_id])
return tip