Add gitlab integration with commets webhook

remotes/origin/enhancement/email-actions
Jesús Espino 2015-06-30 17:30:06 +02:00 committed by David Barragán Merino
parent 8c60b9f22b
commit 3bae896199
4 changed files with 177 additions and 1 deletions

View File

@ -9,6 +9,7 @@
- Now every user that coments USs, Issues or Tasks will be involved in it (add author to the watchers list).
- Fix the compatibility with BitBucket webhooks and add issues and issues comments integration.
- Add custom videoconference system.
- Add support for comments in the Gitlab webhooks integration.
### Misc
- API: Mixin fields 'users', 'members' and 'memberships' in ProjectDetailSerializer

View File

@ -30,6 +30,7 @@ class GitLabViewSet(BaseWebhookApiViewSet):
event_hook_classes = {
"push": event_hooks.PushEventHook,
"issue": event_hooks.IssuesEventHook,
"note": event_hooks.IssueCommentEventHook,
}
def _validate_signature(self, project, request):

View File

@ -89,7 +89,7 @@ class PushEventHook(BaseEventHook):
def replace_gitlab_references(project_url, wiki_text):
if wiki_text == None:
if wiki_text is None:
wiki_text = ""
template = "\g<1>[GitLab#\g<2>]({}/issues/\g<2>)\g<3>".format(project_url)
@ -127,3 +127,48 @@ class IssuesEventHook(BaseEventHook):
snapshot = take_snapshot(issue, comment=_("Created from GitLab"), user=get_gitlab_user(None))
send_notifications(issue, history=snapshot)
class IssueCommentEventHook(BaseEventHook):
def process_event(self):
if self.payload.get('object_attributes', {}).get("noteable_type", None) != "Issue":
return
number = self.payload.get('issue', {}).get('iid', None)
subject = self.payload.get('issue', {}).get('title', None)
project_url = self.payload.get('repository', {}).get('homepage', None)
gitlab_url = os.path.join(project_url, "issues", str(number))
gitlab_user_name = self.payload.get('user', {}).get('username', None)
gitlab_user_url = os.path.join(os.path.dirname(os.path.dirname(project_url)), "u", gitlab_user_name)
comment_message = self.payload.get('object_attributes', {}).get('note', None)
comment_message = replace_gitlab_references(project_url, comment_message)
user = get_gitlab_user(None)
if not all([comment_message, gitlab_url, project_url]):
raise ActionSyntaxException(_("Invalid issue comment information"))
issues = Issue.objects.filter(external_reference=["gitlab", gitlab_url])
tasks = Task.objects.filter(external_reference=["gitlab", gitlab_url])
uss = UserStory.objects.filter(external_reference=["gitlab", gitlab_url])
for item in list(issues) + list(tasks) + list(uss):
if number and subject and gitlab_user_name and gitlab_user_url:
comment = _("Comment by [@{gitlab_user_name}]({gitlab_user_url} "
"\"See @{gitlab_user_name}'s GitLab profile\") "
"from GitLab.\nOrigin GitLab issue: [gh#{number} - {subject}]({gitlab_url} "
"\"Go to 'gh#{number} - {subject}'\")\n\n"
"{message}").format(gitlab_user_name=gitlab_user_name,
gitlab_user_url=gitlab_user_url,
number=number,
subject=subject,
gitlab_url=gitlab_url,
message=comment_message)
else:
comment = _("Comment From GitLab:\n\n{message}").format(message=comment_message)
snapshot = take_snapshot(item, comment=comment, user=user)
send_notifications(item, history=snapshot)

View File

@ -13,6 +13,7 @@ from taiga.projects.issues.models import Issue
from taiga.projects.tasks.models import Task
from taiga.projects.userstories.models import UserStory
from taiga.projects.models import Membership
from taiga.projects.history.services import get_history_queryset_by_model_instance, take_snapshot
from taiga.projects.notifications.choices import NotifyLevel
from taiga.projects.notifications.models import NotifyPolicy
from taiga.projects import services
@ -384,6 +385,134 @@ def test_issues_event_bad_issue(client):
assert len(mail.outbox) == 0
def test_issue_comment_event_on_existing_issue_task_and_us(client):
project = f.ProjectFactory()
role = f.RoleFactory(project=project, permissions=["view_tasks", "view_issues", "view_us"])
f.MembershipFactory(project=project, role=role, user=project.owner)
user = f.UserFactory()
issue = f.IssueFactory.create(external_reference=["gitlab", "http://gitlab.com/test/project/issues/11"], owner=project.owner, project=project)
take_snapshot(issue, user=user)
task = f.TaskFactory.create(external_reference=["gitlab", "http://gitlab.com/test/project/issues/11"], owner=project.owner, project=project)
take_snapshot(task, user=user)
us = f.UserStoryFactory.create(external_reference=["gitlab", "http://gitlab.com/test/project/issues/11"], owner=project.owner, project=project)
take_snapshot(us, user=user)
payload = {
"user": {
"username": "test"
},
"issue": {
"iid": "11",
"title": "test-title",
},
"object_attributes": {
"noteable_type": "Issue",
"note": "Test body",
},
"repository": {
"homepage": "http://gitlab.com/test/project",
},
}
mail.outbox = []
assert get_history_queryset_by_model_instance(issue).count() == 0
assert get_history_queryset_by_model_instance(task).count() == 0
assert get_history_queryset_by_model_instance(us).count() == 0
ev_hook = event_hooks.IssueCommentEventHook(issue.project, payload)
ev_hook.process_event()
issue_history = get_history_queryset_by_model_instance(issue)
assert issue_history.count() == 1
assert "Test body" in issue_history[0].comment
task_history = get_history_queryset_by_model_instance(task)
assert task_history.count() == 1
assert "Test body" in issue_history[0].comment
us_history = get_history_queryset_by_model_instance(us)
assert us_history.count() == 1
assert "Test body" in issue_history[0].comment
assert len(mail.outbox) == 3
def test_issue_comment_event_on_not_existing_issue_task_and_us(client):
issue = f.IssueFactory.create(external_reference=["gitlab", "10"])
take_snapshot(issue, user=issue.owner)
task = f.TaskFactory.create(project=issue.project, external_reference=["gitlab", "10"])
take_snapshot(task, user=task.owner)
us = f.UserStoryFactory.create(project=issue.project, external_reference=["gitlab", "10"])
take_snapshot(us, user=us.owner)
payload = {
"user": {
"username": "test"
},
"issue": {
"iid": "99999",
"title": "test-title",
},
"object_attributes": {
"noteable_type": "Issue",
"note": "test comment",
},
"repository": {
"homepage": "test",
},
}
mail.outbox = []
assert get_history_queryset_by_model_instance(issue).count() == 0
assert get_history_queryset_by_model_instance(task).count() == 0
assert get_history_queryset_by_model_instance(us).count() == 0
ev_hook = event_hooks.IssueCommentEventHook(issue.project, payload)
ev_hook.process_event()
assert get_history_queryset_by_model_instance(issue).count() == 0
assert get_history_queryset_by_model_instance(task).count() == 0
assert get_history_queryset_by_model_instance(us).count() == 0
assert len(mail.outbox) == 0
def test_issues_event_bad_comment(client):
issue = f.IssueFactory.create(external_reference=["gitlab", "10"])
take_snapshot(issue, user=issue.owner)
payload = {
"user": {
"username": "test"
},
"issue": {
"iid": "10",
"title": "test-title",
},
"object_attributes": {
"noteable_type": "Issue",
},
"repository": {
"homepage": "test",
},
}
ev_hook = event_hooks.IssueCommentEventHook(issue.project, payload)
mail.outbox = []
with pytest.raises(ActionSyntaxException) as excinfo:
ev_hook.process_event()
assert str(excinfo.value) == "Invalid issue comment information"
assert Issue.objects.count() == 1
assert len(mail.outbox) == 0
def test_api_get_project_modules(client):
project = f.create_project()
f.MembershipFactory(project=project, user=project.owner, is_owner=True)