Commit d3f26be6 authored by Sean McGivern's avatar Sean McGivern

Merge branch '23524-notify-automerge-user-of-failed-build' into 'master'

Notify the user who set auto-merge when merge is not possible

Closes #23524

See merge request !8056
parents 2a0d6342 85e0b994
...@@ -11,9 +11,10 @@ module TodosHelper ...@@ -11,9 +11,10 @@ module TodosHelper
case todo.action case todo.action
when Todo::ASSIGNED then 'assigned you' when Todo::ASSIGNED then 'assigned you'
when Todo::MENTIONED then 'mentioned you on' when Todo::MENTIONED then 'mentioned you on'
when Todo::BUILD_FAILED then 'The build failed for your' when Todo::BUILD_FAILED then 'The build failed for'
when Todo::MARKED then 'added a todo for' when Todo::MARKED then 'added a todo for'
when Todo::APPROVAL_REQUIRED then 'set you as an approver for' when Todo::APPROVAL_REQUIRED then 'set you as an approver for'
when Todo::UNMERGEABLE then 'Could not merge'
end end
end end
......
...@@ -91,6 +91,10 @@ class MergeRequest < ActiveRecord::Base ...@@ -91,6 +91,10 @@ class MergeRequest < ActiveRecord::Base
around_transition do |merge_request, transition, block| around_transition do |merge_request, transition, block|
Gitlab::Timeless.timeless(merge_request, &block) Gitlab::Timeless.timeless(merge_request, &block)
end end
after_transition unchecked: :cannot_be_merged do |merge_request, transition|
TodoService.new.merge_request_became_unmergeable(merge_request)
end
end end
validates :source_project, presence: true, unless: [:allow_broken, :importing?, :closed_without_fork?] validates :source_project, presence: true, unless: [:allow_broken, :importing?, :closed_without_fork?]
......
...@@ -6,13 +6,15 @@ class Todo < ActiveRecord::Base ...@@ -6,13 +6,15 @@ class Todo < ActiveRecord::Base
BUILD_FAILED = 3 BUILD_FAILED = 3
MARKED = 4 MARKED = 4
APPROVAL_REQUIRED = 5 # This is an EE-only feature APPROVAL_REQUIRED = 5 # This is an EE-only feature
UNMERGEABLE = 6
ACTION_NAMES = { ACTION_NAMES = {
ASSIGNED => :assigned, ASSIGNED => :assigned,
MENTIONED => :mentioned, MENTIONED => :mentioned,
BUILD_FAILED => :build_failed, BUILD_FAILED => :build_failed,
MARKED => :marked, MARKED => :marked,
APPROVAL_REQUIRED => :approval_required APPROVAL_REQUIRED => :approval_required,
UNMERGEABLE => :unmergeable
} }
belongs_to :author, class_name: "User" belongs_to :author, class_name: "User"
...@@ -66,6 +68,10 @@ class Todo < ActiveRecord::Base ...@@ -66,6 +68,10 @@ class Todo < ActiveRecord::Base
end end
end end
def unmergeable?
action == UNMERGEABLE
end
def build_failed? def build_failed?
action == BUILD_FAILED action == BUILD_FAILED
end end
......
...@@ -98,10 +98,12 @@ class TodoService ...@@ -98,10 +98,12 @@ class TodoService
# When a build fails on the HEAD of a merge request we should: # When a build fails on the HEAD of a merge request we should:
# #
# * create a todo for that user to fix it # * create a todo for author of MR to fix it
# * create a todo for merge_user to keep an eye on it
# #
def merge_request_build_failed(merge_request) def merge_request_build_failed(merge_request)
create_build_failed_todo(merge_request) create_build_failed_todo(merge_request, merge_request.author)
create_build_failed_todo(merge_request, merge_request.merge_user) if merge_request.merge_when_build_succeeds?
end end
# When a new commit is pushed to a merge request we should: # When a new commit is pushed to a merge request we should:
...@@ -115,11 +117,21 @@ class TodoService ...@@ -115,11 +117,21 @@ class TodoService
# When a build is retried to a merge request we should: # When a build is retried to a merge request we should:
# #
# * mark all pending todos related to the merge request for the author as done # * mark all pending todos related to the merge request for the author as done
# * mark all pending todos related to the merge request for the merge_user as done
# #
def merge_request_build_retried(merge_request) def merge_request_build_retried(merge_request)
mark_pending_todos_as_done(merge_request, merge_request.author) mark_pending_todos_as_done(merge_request, merge_request.author)
mark_pending_todos_as_done(merge_request, merge_request.merge_user) if merge_request.merge_when_build_succeeds?
end end
# When a merge request could not be automatically merged due to its unmergeable state we should:
#
# * create a todo for a merge_user
#
def merge_request_became_unmergeable(merge_request)
create_unmergeable_todo(merge_request, merge_request.merge_user) if merge_request.merge_when_build_succeeds?
end
# When create a note we should: # When create a note we should:
# #
# * mark all pending todos related to the noteable for the note author as done # * mark all pending todos related to the noteable for the note author as done
...@@ -236,10 +248,14 @@ class TodoService ...@@ -236,10 +248,14 @@ class TodoService
create_todos(mentioned_users, attributes) create_todos(mentioned_users, attributes)
end end
def create_build_failed_todo(merge_request) def create_build_failed_todo(merge_request, todo_author)
author = merge_request.author attributes = attributes_for_todo(merge_request.project, merge_request, todo_author, Todo::BUILD_FAILED)
attributes = attributes_for_todo(merge_request.project, merge_request, author, Todo::BUILD_FAILED) create_todos(todo_author, attributes)
create_todos(author, attributes) end
def create_unmergeable_todo(merge_request, merge_user)
attributes = attributes_for_todo(merge_request.project, merge_request, merge_user, Todo::UNMERGEABLE)
create_todos(merge_user, attributes)
end end
def attributes_for_target(target) def attributes_for_target(target)
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
.todo-item.todo-block .todo-item.todo-block
.todo-title.title .todo-title.title
- unless todo.build_failed? - unless todo.build_failed? || todo.unmergeable?
= todo_target_state_pill(todo) = todo_target_state_pill(todo)
%span.author-name %span.author-name
......
---
title: Create a TODO for user who set auto-merge when a build fails, merge conflict occurs
merge_request: 8056
author: twonegatives
...@@ -28,6 +28,10 @@ FactoryGirl.define do ...@@ -28,6 +28,10 @@ FactoryGirl.define do
action { Todo::APPROVAL_REQUIRED } action { Todo::APPROVAL_REQUIRED }
end end
trait :unmergeable do
action { Todo::UNMERGEABLE }
end
trait :done do trait :done do
state :done state :done
end end
......
...@@ -773,10 +773,12 @@ describe MergeRequest, models: true do ...@@ -773,10 +773,12 @@ describe MergeRequest, models: true do
subject { create(:merge_request, source_project: project, merge_status: :unchecked) } subject { create(:merge_request, source_project: project, merge_status: :unchecked) }
context 'when it is not broken and has no conflicts' do context 'when it is not broken and has no conflicts' do
it 'is marked as mergeable' do before do
allow(subject).to receive(:broken?) { false } allow(subject).to receive(:broken?) { false }
allow(project.repository).to receive(:can_be_merged?).and_return(true) allow(project.repository).to receive(:can_be_merged?).and_return(true)
end
it 'is marked as mergeable' do
expect { subject.check_if_can_be_merged }.to change { subject.merge_status }.to('can_be_merged') expect { subject.check_if_can_be_merged }.to change { subject.merge_status }.to('can_be_merged')
end end
end end
...@@ -787,6 +789,12 @@ describe MergeRequest, models: true do ...@@ -787,6 +789,12 @@ describe MergeRequest, models: true do
it 'becomes unmergeable' do it 'becomes unmergeable' do
expect { subject.check_if_can_be_merged }.to change { subject.merge_status }.to('cannot_be_merged') expect { subject.check_if_can_be_merged }.to change { subject.merge_status }.to('cannot_be_merged')
end end
it 'creates Todo on unmergeability' do
expect_any_instance_of(TodoService).to receive(:merge_request_became_unmergeable).with(subject)
subject.check_if_can_be_merged
end
end end
context 'when it has conflicts' do context 'when it has conflicts' do
......
...@@ -469,6 +469,13 @@ describe TodoService, services: true do ...@@ -469,6 +469,13 @@ describe TodoService, services: true do
should_create_todo(user: author, target: mr_unassigned, action: Todo::BUILD_FAILED) should_create_todo(user: author, target: mr_unassigned, action: Todo::BUILD_FAILED)
end end
it 'creates a pending todo for merge_user' do
mr_unassigned.update(merge_when_build_succeeds: true, merge_user: admin)
service.merge_request_build_failed(mr_unassigned)
should_create_todo(user: admin, author: admin, target: mr_unassigned, action: Todo::BUILD_FAILED)
end
end end
describe '#merge_request_push' do describe '#merge_request_push' do
...@@ -482,6 +489,15 @@ describe TodoService, services: true do ...@@ -482,6 +489,15 @@ describe TodoService, services: true do
end end
end end
describe '#merge_request_became_unmergeable' do
it 'creates a pending todo for a merge_user' do
mr_unassigned.update(merge_when_build_succeeds: true, merge_user: admin)
service.merge_request_became_unmergeable(mr_unassigned)
should_create_todo(user: admin, author: admin, target: mr_unassigned, action: Todo::UNMERGEABLE)
end
end
describe '#mark_todo' do describe '#mark_todo' do
it 'creates a todo from a merge request' do it 'creates a todo from a merge request' do
service.mark_todo(mr_unassigned, author) service.mark_todo(mr_unassigned, author)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment