Add gitlab integration with commets webhook
parent
8c60b9f22b
commit
3bae896199
|
@ -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
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue