diff --git a/marge/job.py b/marge/job.py index 696aefa4..9b33aae0 100644 --- a/marge/job.py +++ b/marge/job.py @@ -55,6 +55,9 @@ def ensure_mergeable_mr(self, merge_request): '(have: {0.approver_usernames} missing: {0.approvals_left})'.format(approvals) ) + if not merge_request.blocking_discussions_resolved: + raise CannotMerge("Sorry, I can't merge requests which have unresolved discussions!") + state = merge_request.state if state not in ('opened', 'reopened', 'locked'): if state in ('merged', 'closed'): diff --git a/marge/merge_request.py b/marge/merge_request.py index 98a14eb5..030b79b8 100644 --- a/marge/merge_request.py +++ b/marge/merge_request.py @@ -151,6 +151,10 @@ def approved_by(self): def web_url(self): return self.info['web_url'] + @property + def blocking_discussions_resolved(self): + return self.info['blocking_discussions_resolved'] + @property def force_remove_source_branch(self): return self.info['force_remove_source_branch'] diff --git a/tests/gitlab_api_mock.py b/tests/gitlab_api_mock.py index a682d52e..012fb647 100644 --- a/tests/gitlab_api_mock.py +++ b/tests/gitlab_api_mock.py @@ -58,6 +58,7 @@ def __init__(self, initial_master_sha='505e', gitlab_url=None, fork=False, merge 'force_remove_source_branch': True, 'target_branch': 'master', 'work_in_progress': False, + 'blocking_discussions_resolved': True, 'web_url': 'http://git.example.com/group/project/merge_request/666', } if merge_request_options is not None: diff --git a/tests/test_job.py b/tests/test_job.py index 77f59611..4818b293 100644 --- a/tests/test_job.py +++ b/tests/test_job.py @@ -130,6 +130,20 @@ def test_ensure_mergeable_mr_wip(self): assert exc_info.value.reason == "Sorry, I can't merge requests marked as Work-In-Progress!" + def test_ensure_mergeable_mr_unresolved_discussion(self): + merge_job = self.get_merge_job() + merge_request = self._mock_merge_request( + assignee_ids=[merge_job._user.id], + state='opened', + work_in_progress=False, + blocking_discussions_resolved=False, + ) + merge_request.fetch_approvals.return_value.sufficient = True + with pytest.raises(CannotMerge) as exc_info: + merge_job.ensure_mergeable_mr(merge_request) + + assert exc_info.value.reason == "Sorry, I can't merge requests which have unresolved discussions!" + def test_ensure_mergeable_mr_squash_and_trailers(self): merge_job = self.get_merge_job(options=MergeJobOptions.default(add_reviewers=True)) merge_request = self._mock_merge_request(