Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
39c342ba
Commit
39c342ba
authored
Feb 12, 2021
by
Kamil Trzciński
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Retarget MR only when source branch is removed
This ensures that we have an automation in erroring condition
parent
296cdaf8
Changes
10
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
123 additions
and
35 deletions
+123
-35
app/services/merge_requests/post_merge_service.rb
app/services/merge_requests/post_merge_service.rb
+5
-2
app/services/merge_requests/update_service.rb
app/services/merge_requests/update_service.rb
+13
-3
app/services/system_note_service.rb
app/services/system_note_service.rb
+7
-4
app/services/system_notes/merge_requests_service.rb
app/services/system_notes/merge_requests_service.rb
+15
-5
doc/user/project/merge_requests/getting_started.md
doc/user/project/merge_requests/getting_started.md
+1
-1
ee/app/services/ee/merge_requests/update_service.rb
ee/app/services/ee/merge_requests/update_service.rb
+1
-1
spec/services/merge_requests/post_merge_service_spec.rb
spec/services/merge_requests/post_merge_service_spec.rb
+24
-10
spec/services/merge_requests/update_service_spec.rb
spec/services/merge_requests/update_service_spec.rb
+27
-0
spec/services/system_note_service_spec.rb
spec/services/system_note_service_spec.rb
+6
-5
spec/services/system_notes/merge_requests_service_spec.rb
spec/services/system_notes/merge_requests_service_spec.rb
+24
-4
No files found.
app/services/merge_requests/post_merge_service.rb
View file @
39c342ba
...
@@ -35,7 +35,8 @@ module MergeRequests
...
@@ -35,7 +35,8 @@ module MergeRequests
return
unless
Feature
.
enabled?
(
:retarget_merge_requests
,
merge_request
.
target_project
)
return
unless
Feature
.
enabled?
(
:retarget_merge_requests
,
merge_request
.
target_project
)
# we can only retarget MRs that are targeting the same project
# we can only retarget MRs that are targeting the same project
return
unless
merge_request
.
for_same_project?
# and have a remove source branch set
return
unless
merge_request
.
for_same_project?
&&
merge_request
.
remove_source_branch?
# find another merge requests that
# find another merge requests that
# - as a target have a current source project and branch
# - as a target have a current source project and branch
...
@@ -51,7 +52,9 @@ module MergeRequests
...
@@ -51,7 +52,9 @@ module MergeRequests
next
unless
can?
(
current_user
,
:update_merge_request
,
other_merge_request
.
source_project
)
next
unless
can?
(
current_user
,
:update_merge_request
,
other_merge_request
.
source_project
)
::
MergeRequests
::
UpdateService
::
MergeRequests
::
UpdateService
.
new
(
other_merge_request
.
source_project
,
current_user
,
target_branch:
merge_request
.
target_branch
)
.
new
(
other_merge_request
.
source_project
,
current_user
,
target_branch:
merge_request
.
target_branch
,
target_branch_was_deleted:
true
)
.
execute
(
other_merge_request
)
.
execute
(
other_merge_request
)
end
end
end
end
...
...
app/services/merge_requests/update_service.rb
View file @
39c342ba
...
@@ -4,6 +4,12 @@ module MergeRequests
...
@@ -4,6 +4,12 @@ module MergeRequests
class
UpdateService
<
MergeRequests
::
BaseService
class
UpdateService
<
MergeRequests
::
BaseService
extend
::
Gitlab
::
Utils
::
Override
extend
::
Gitlab
::
Utils
::
Override
def
initialize
(
project
,
user
=
nil
,
params
=
{})
super
@target_branch_was_deleted
=
@params
.
delete
(
:target_branch_was_deleted
)
end
def
execute
(
merge_request
)
def
execute
(
merge_request
)
# We don't allow change of source/target projects and source branch
# We don't allow change of source/target projects and source branch
# after merge request was created
# after merge request was created
...
@@ -36,7 +42,9 @@ module MergeRequests
...
@@ -36,7 +42,9 @@ module MergeRequests
end
end
if
merge_request
.
previous_changes
.
include?
(
'target_branch'
)
if
merge_request
.
previous_changes
.
include?
(
'target_branch'
)
create_branch_change_note
(
merge_request
,
'target'
,
create_branch_change_note
(
merge_request
,
'target'
,
target_branch_was_deleted
?
'delete'
:
'update'
,
merge_request
.
previous_changes
[
'target_branch'
].
first
,
merge_request
.
previous_changes
[
'target_branch'
].
first
,
merge_request
.
target_branch
)
merge_request
.
target_branch
)
...
@@ -130,6 +138,8 @@ module MergeRequests
...
@@ -130,6 +138,8 @@ module MergeRequests
private
private
attr_reader
:target_branch_was_deleted
def
handle_milestone_change
(
merge_request
)
def
handle_milestone_change
(
merge_request
)
return
if
skip_milestone_email
return
if
skip_milestone_email
...
@@ -162,9 +172,9 @@ module MergeRequests
...
@@ -162,9 +172,9 @@ module MergeRequests
merge_request_activity_counter
.
track_users_review_requested
(
users:
new_reviewers
)
merge_request_activity_counter
.
track_users_review_requested
(
users:
new_reviewers
)
end
end
def
create_branch_change_note
(
issuable
,
branch_type
,
old_branch
,
new_branch
)
def
create_branch_change_note
(
issuable
,
branch_type
,
event_type
,
old_branch
,
new_branch
)
SystemNoteService
.
change_branch
(
SystemNoteService
.
change_branch
(
issuable
,
issuable
.
project
,
current_user
,
branch_type
,
issuable
,
issuable
.
project
,
current_user
,
branch_type
,
event_type
,
old_branch
,
new_branch
)
old_branch
,
new_branch
)
end
end
...
...
app/services/system_note_service.rb
View file @
39c342ba
...
@@ -168,16 +168,19 @@ module SystemNoteService
...
@@ -168,16 +168,19 @@ module SystemNoteService
# project - Project owning noteable
# project - Project owning noteable
# author - User performing the change
# author - User performing the change
# branch_type - 'source' or 'target'
# branch_type - 'source' or 'target'
# event_type - the source of event: 'update' or 'delete'
# old_branch - old branch name
# old_branch - old branch name
# new_branch - new branch name
# new_branch - new branch name
#
#
# Example Note text:
# Example Note text
is based on event_type
:
#
#
# "changed target branch from `Old` to `New`"
# update: "changed target branch from `Old` to `New`"
# delete: "changed automatically target branch to `New` because `Old` was deleted"
#
#
# Returns the created Note object
# Returns the created Note object
def
change_branch
(
noteable
,
project
,
author
,
branch_type
,
old_branch
,
new_branch
)
def
change_branch
(
noteable
,
project
,
author
,
branch_type
,
event_type
,
old_branch
,
new_branch
)
::
SystemNotes
::
MergeRequestsService
.
new
(
noteable:
noteable
,
project:
project
,
author:
author
).
change_branch
(
branch_type
,
old_branch
,
new_branch
)
::
SystemNotes
::
MergeRequestsService
.
new
(
noteable:
noteable
,
project:
project
,
author:
author
)
.
change_branch
(
branch_type
,
event_type
,
old_branch
,
new_branch
)
end
end
# Called when a branch in Noteable is added or deleted
# Called when a branch in Noteable is added or deleted
...
...
app/services/system_notes/merge_requests_service.rb
View file @
39c342ba
...
@@ -83,16 +83,26 @@ module SystemNotes
...
@@ -83,16 +83,26 @@ module SystemNotes
# Called when a branch in Noteable is changed
# Called when a branch in Noteable is changed
#
#
# branch_type - 'source' or 'target'
# branch_type - 'source' or 'target'
# event_type - the source of event: 'update' or 'delete'
# old_branch - old branch name
# old_branch - old branch name
# new_branch - new branch name
# new_branch - new branch name
# Example Note text is based on event_type:
#
#
# Example Note text:
# update: "changed target branch from `Old` to `New`"
#
# delete: "changed automatically target branch to `New` because `Old` was deleted"
# "changed target branch from `Old` to `New`"
#
#
# Returns the created Note object
# Returns the created Note object
def
change_branch
(
branch_type
,
old_branch
,
new_branch
)
def
change_branch
(
branch_type
,
event_type
,
old_branch
,
new_branch
)
body
=
"changed
#{
branch_type
}
branch from `
#{
old_branch
}
` to `
#{
new_branch
}
`"
body
=
case
event_type
.
to_s
when
'delete'
"changed automatically
#{
branch_type
}
branch to `
#{
new_branch
}
` because `
#{
old_branch
}
` was deleted"
when
'update'
"changed
#{
branch_type
}
branch from `
#{
old_branch
}
` to `
#{
new_branch
}
`"
else
raise
ArgumentError
,
"invalid value for event_type:
#{
event_type
}
"
end
create_note
(
NoteSummary
.
new
(
noteable
,
project
,
author
,
body
,
action:
'branch'
))
create_note
(
NoteSummary
.
new
(
noteable
,
project
,
author
,
body
,
action:
'branch'
))
end
end
...
...
doc/user/project/merge_requests/getting_started.md
View file @
39c342ba
...
@@ -208,7 +208,7 @@ open. Merge requests are often chained in this manner, with one merge request
...
@@ -208,7 +208,7 @@ open. Merge requests are often chained in this manner, with one merge request
depending on another:
depending on another:
-
**Merge request 1**
: merge
`feature-alpha`
into
`master`
.
-
**Merge request 1**
: merge
`feature-alpha`
into
`master`
.
-
**Merge
R
equest 2**
: merge
`feature-beta`
into
`feature-alpha`
.
-
**Merge
r
equest 2**
: merge
`feature-beta`
into
`feature-alpha`
.
These merge requests are usually handled in one of these ways:
These merge requests are usually handled in one of these ways:
...
...
ee/app/services/ee/merge_requests/update_service.rb
View file @
39c342ba
...
@@ -50,7 +50,7 @@ module EE
...
@@ -50,7 +50,7 @@ module EE
end
end
override
:create_branch_change_note
override
:create_branch_change_note
def
create_branch_change_note
(
merge_request
,
branch_type
,
old_branch
,
new_branch
)
def
create_branch_change_note
(
merge_request
,
branch_type
,
event_type
,
old_branch
,
new_branch
)
super
super
reset_approvals
(
merge_request
)
reset_approvals
(
merge_request
)
...
...
spec/services/merge_requests/post_merge_service_spec.rb
View file @
39c342ba
...
@@ -132,6 +132,12 @@ RSpec.describe MergeRequests::PostMergeService do
...
@@ -132,6 +132,12 @@ RSpec.describe MergeRequests::PostMergeService do
end
end
context
'for a merge request chain'
do
context
'for a merge request chain'
do
before
do
::
MergeRequests
::
UpdateService
.
new
(
project
,
user
,
force_remove_source_branch:
'1'
)
.
execute
(
merge_request
)
end
context
'when there is another MR'
do
context
'when there is another MR'
do
let!
(
:another_merge_request
)
do
let!
(
:another_merge_request
)
do
create
(
:merge_request
,
create
(
:merge_request
,
...
@@ -142,11 +148,19 @@ RSpec.describe MergeRequests::PostMergeService do
...
@@ -142,11 +148,19 @@ RSpec.describe MergeRequests::PostMergeService do
)
)
end
end
shared_examples
'does not retarget merge request'
do
it
'another merge request is unchanged'
do
expect
{
subject
}.
not_to
change
{
another_merge_request
.
reload
.
target_branch
}
.
from
(
merge_request
.
source_branch
)
end
end
shared_examples
'retargets merge request'
do
shared_examples
'retargets merge request'
do
it
'another merge request is retargeted'
do
it
'another merge request is retargeted'
do
expect
(
SystemNoteService
)
expect
(
SystemNoteService
)
.
to
receive
(
:change_branch
).
once
.
to
receive
(
:change_branch
).
once
.
with
(
another_merge_request
,
another_merge_request
.
project
,
user
,
'target'
,
.
with
(
another_merge_request
,
another_merge_request
.
project
,
user
,
'target'
,
'delete'
,
merge_request
.
source_branch
,
merge_request
.
target_branch
)
merge_request
.
source_branch
,
merge_request
.
target_branch
)
expect
{
subject
}.
to
change
{
another_merge_request
.
reload
.
target_branch
}
expect
{
subject
}.
to
change
{
another_merge_request
.
reload
.
target_branch
}
...
@@ -159,17 +173,17 @@ RSpec.describe MergeRequests::PostMergeService do
...
@@ -159,17 +173,17 @@ RSpec.describe MergeRequests::PostMergeService do
stub_feature_flags
(
retarget_merge_requests:
false
)
stub_feature_flags
(
retarget_merge_requests:
false
)
end
end
it
'another merge request is unchanged'
do
include_examples
'does not retarget merge request'
expect
{
subject
}.
not_to
change
{
another_merge_request
.
reload
.
target_branch
}
.
from
(
merge_request
.
source_branch
)
end
end
end
context
'when source branch is to be kept'
do
before
do
::
MergeRequests
::
UpdateService
.
new
(
project
,
user
,
force_remove_source_branch:
false
)
.
execute
(
merge_request
)
end
end
shared_examples
'does not retarget merge request'
do
include_examples
'does not retarget merge request'
it
'another merge request is unchanged'
do
expect
{
subject
}.
not_to
change
{
another_merge_request
.
reload
.
target_branch
}
.
from
(
merge_request
.
source_branch
)
end
end
end
end
...
...
spec/services/merge_requests/update_service_spec.rb
View file @
39c342ba
...
@@ -913,6 +913,33 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
...
@@ -913,6 +913,33 @@ RSpec.describe MergeRequests::UpdateService, :mailer do
end
end
end
end
context
'updating `target_branch`'
do
let
(
:merge_request
)
do
create
(
:merge_request
,
source_project:
project
,
source_branch:
'mr-b'
,
target_branch:
'mr-a'
)
end
it
'updates to master'
do
expect
(
SystemNoteService
).
to
receive
(
:change_branch
).
with
(
merge_request
,
project
,
user
,
'target'
,
'update'
,
'mr-a'
,
'master'
)
expect
{
update_merge_request
(
target_branch:
'master'
)
}
.
to
change
{
merge_request
.
reload
.
target_branch
}.
from
(
'mr-a'
).
to
(
'master'
)
end
it
'updates to master because of branch deletion'
do
expect
(
SystemNoteService
).
to
receive
(
:change_branch
).
with
(
merge_request
,
project
,
user
,
'target'
,
'delete'
,
'mr-a'
,
'master'
)
expect
{
update_merge_request
(
target_branch:
'master'
,
target_branch_was_deleted:
true
)
}
.
to
change
{
merge_request
.
reload
.
target_branch
}.
from
(
'mr-a'
).
to
(
'master'
)
end
end
it_behaves_like
'issuable record that supports quick actions'
do
it_behaves_like
'issuable record that supports quick actions'
do
let
(
:existing_merge_request
)
{
create
(
:merge_request
,
source_project:
project
)
}
let
(
:existing_merge_request
)
{
create
(
:merge_request
,
source_project:
project
)
}
let
(
:issuable
)
{
described_class
.
new
(
project
,
user
,
params
).
execute
(
existing_merge_request
)
}
let
(
:issuable
)
{
described_class
.
new
(
project
,
user
,
params
).
execute
(
existing_merge_request
)
}
...
...
spec/services/system_note_service_spec.rb
View file @
39c342ba
...
@@ -213,15 +213,16 @@ RSpec.describe SystemNoteService do
...
@@ -213,15 +213,16 @@ RSpec.describe SystemNoteService do
describe
'.change_branch'
do
describe
'.change_branch'
do
it
'calls MergeRequestsService'
do
it
'calls MergeRequestsService'
do
old_branch
=
double
old_branch
=
double
(
'old_branch'
)
new_branch
=
double
new_branch
=
double
(
'new_branch'
)
branch_type
=
double
branch_type
=
double
(
'branch_type'
)
event_type
=
double
(
'event_type'
)
expect_next_instance_of
(
::
SystemNotes
::
MergeRequestsService
)
do
|
service
|
expect_next_instance_of
(
::
SystemNotes
::
MergeRequestsService
)
do
|
service
|
expect
(
service
).
to
receive
(
:change_branch
).
with
(
branch_type
,
old_branch
,
new_branch
)
expect
(
service
).
to
receive
(
:change_branch
).
with
(
branch_type
,
event_type
,
old_branch
,
new_branch
)
end
end
described_class
.
change_branch
(
noteable
,
project
,
author
,
branch_type
,
old_branch
,
new_branch
)
described_class
.
change_branch
(
noteable
,
project
,
author
,
branch_type
,
event_type
,
old_branch
,
new_branch
)
end
end
end
end
...
...
spec/services/system_notes/merge_requests_service_spec.rb
View file @
39c342ba
...
@@ -167,20 +167,40 @@ RSpec.describe ::SystemNotes::MergeRequestsService do
...
@@ -167,20 +167,40 @@ RSpec.describe ::SystemNotes::MergeRequestsService do
end
end
describe
'.change_branch'
do
describe
'.change_branch'
do
subject
{
service
.
change_branch
(
'target'
,
old_branch
,
new_branch
)
}
let
(
:old_branch
)
{
'old_branch'
}
let
(
:old_branch
)
{
'old_branch'
}
let
(
:new_branch
)
{
'new_branch'
}
let
(
:new_branch
)
{
'new_branch'
}
it_behaves_like
'a system note'
do
it_behaves_like
'a system note'
do
let
(
:action
)
{
'branch'
}
let
(
:action
)
{
'branch'
}
subject
{
service
.
change_branch
(
'target'
,
'update'
,
old_branch
,
new_branch
)
}
end
end
context
'when target branch name changed'
do
context
'when target branch name changed'
do
context
'on update'
do
subject
{
service
.
change_branch
(
'target'
,
'update'
,
old_branch
,
new_branch
)
}
it
'sets the note text'
do
it
'sets the note text'
do
expect
(
subject
.
note
).
to
eq
"changed target branch from `
#{
old_branch
}
` to `
#{
new_branch
}
`"
expect
(
subject
.
note
).
to
eq
"changed target branch from `
#{
old_branch
}
` to `
#{
new_branch
}
`"
end
end
end
end
context
'on delete'
do
subject
{
service
.
change_branch
(
'target'
,
'delete'
,
old_branch
,
new_branch
)
}
it
'sets the note text'
do
expect
(
subject
.
note
).
to
eq
"changed automatically target branch to `
#{
new_branch
}
` because `
#{
old_branch
}
` was deleted"
end
end
context
'for invalid event_type'
do
subject
{
service
.
change_branch
(
'target'
,
'invalid'
,
old_branch
,
new_branch
)
}
it
'raises exception'
do
expect
{
subject
}.
to
raise_error
/invalid value for event_type/
end
end
end
end
end
describe
'.change_branch_presence'
do
describe
'.change_branch_presence'
do
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment