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
0
Merge Requests
0
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
Kazuhiko Shiozaki
gitlab-ce
Commits
2462a96e
Commit
2462a96e
authored
Dec 03, 2015
by
Zeger-Jan van de Weg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Incorporate feedback
parent
25907ebe
Changes
14
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
134 additions
and
83 deletions
+134
-83
app/models/merge_request.rb
app/models/merge_request.rb
+24
-22
app/services/merge_requests/merge_when_build_succeeds_service.rb
...vices/merge_requests/merge_when_build_succeeds_service.rb
+4
-5
app/services/system_note_service.rb
app/services/system_note_service.rb
+3
-3
app/views/projects/merge_requests/_merge_request.html.haml
app/views/projects/merge_requests/_merge_request.html.haml
+2
-3
app/views/projects/merge_requests/widget/_heading.html.haml
app/views/projects/merge_requests/widget/_heading.html.haml
+4
-5
app/views/projects/merge_requests/widget/open/_accept.html.haml
...ews/projects/merge_requests/widget/open/_accept.html.haml
+1
-2
app/views/projects/merge_requests/widget/open/_merge_when_build_succeeds.html.haml
...requests/widget/open/_merge_when_build_succeeds.html.haml
+12
-12
spec/factories/merge_requests.rb
spec/factories/merge_requests.rb
+5
-0
spec/features/merge_requests/merge_when_build_succeeds_spec.rb
...features/merge_requests/merge_when_build_succeeds_spec.rb
+17
-4
spec/models/merge_request_spec.rb
spec/models/merge_request_spec.rb
+36
-8
spec/requests/api/merge_requests_spec.rb
spec/requests/api/merge_requests_spec.rb
+1
-1
spec/services/merge_requests/merge_when_build_succeeds_service_spec.rb
.../merge_requests/merge_when_build_succeeds_service_spec.rb
+18
-12
spec/services/merge_requests/refresh_service_spec.rb
spec/services/merge_requests/refresh_service_spec.rb
+2
-1
spec/services/system_note_service_spec.rb
spec/services/system_note_service_spec.rb
+5
-5
No files found.
app/models/merge_request.rb
View file @
2462a96e
...
...
@@ -21,6 +21,9 @@
# locked_at :datetime
# updated_by_id :integer
# merge_error :string(255)
# merge_params :text (serialized to hash)
# merge_when_build_succeeds :boolean default(false), not null
# merge_user_id :integer
#
require
Rails
.
root
.
join
(
"app/models/commit"
)
...
...
@@ -124,6 +127,7 @@ class MergeRequest < ActiveRecord::Base
validates
:source_branch
,
presence:
true
validates
:target_project
,
presence:
true
validates
:target_branch
,
presence:
true
validates
:merge_user
,
presence:
true
,
if: :merge_when_build_succeeds?
validate
:validate_branches
validate
:validate_fork
...
...
@@ -496,8 +500,6 @@ class MergeRequest < ActiveRecord::Base
end
def
ci_commit
if
last_commit
source_project
.
ci_commit
(
last_commit
.
id
)
end
@ci_commit
||=
source_project
.
ci_commit
(
last_commit
.
id
)
if
last_commit
end
end
app/services/merge_requests/merge_when_build_succeeds_service.rb
View file @
2462a96e
module
MergeRequests
class
MergeWhenBuildSucceedsService
<
MergeRequests
::
BaseService
# Marks the passed `merge_request` to be m
ark
ed when the build succeeds or
# Marks the passed `merge_request` to be m
erg
ed when the build succeeds or
# updates the params for the automatic merge
def
execute
(
merge_request
)
merge_request
.
merge_params
.
merge!
(
params
)
...
...
@@ -12,7 +12,7 @@ module MergeRequests
merge_request
.
merge_when_build_succeeds
=
true
merge_request
.
merge_user
=
@current_user
SystemNoteService
.
merge_when_build_succeeds
(
merge_request
,
@project
,
@current_user
,
merge_request
.
ci
_commit
)
SystemNoteService
.
merge_when_build_succeeds
(
merge_request
,
@project
,
@current_user
,
merge_request
.
last
_commit
)
end
merge_request
.
save
...
...
@@ -25,8 +25,7 @@ module MergeRequests
merge_requests
.
each
do
|
merge_request
|
next
unless
merge_request
.
merge_when_build_succeeds?
ci_commit
=
merge_request
.
ci_commit
if
ci_commit
&&
ci_commit
.
success?
&&
merge_request
.
mergeable?
if
merge_request
.
ci_commit
&&
merge_request
.
ci_commit
.
success?
&&
merge_request
.
mergeable?
MergeWorker
.
perform_async
(
merge_request
.
id
,
merge_request
.
merge_user_id
,
merge_request
.
merge_params
)
end
end
...
...
@@ -34,7 +33,7 @@ module MergeRequests
# Cancels the automatic merge
def
cancel
(
merge_request
)
if
merge_request
.
merge_when_build_succeeds?
&&
merge_request
.
open?
&&
!
merge_request
.
merged?
if
merge_request
.
merge_when_build_succeeds?
&&
merge_request
.
open?
merge_request
.
reset_merge_when_build_succeeds
SystemNoteService
.
cancel_merge_when_build_succeeds
(
merge_request
,
@project
,
@current_user
)
...
...
app/services/system_note_service.rb
View file @
2462a96e
...
...
@@ -131,15 +131,15 @@ class SystemNoteService
end
# Called when 'merge when build succeeds' is executed
def
self
.
merge_when_build_succeeds
(
noteable
,
project
,
author
,
ci
_commit
)
body
=
"Enabled an automatic merge when the build for
#{
ci_commit
.
sha
}
succeeds"
def
self
.
merge_when_build_succeeds
(
noteable
,
project
,
author
,
last
_commit
)
body
=
"Enabled an automatic merge when the build for
#{
last_commit
.
to_reference
}
succeeds"
create_note
(
noteable:
noteable
,
project:
project
,
author:
author
,
note:
body
)
end
# Called when 'merge when build succeeds' is canceled
def
self
.
cancel_merge_when_build_succeeds
(
noteable
,
project
,
author
)
body
=
"Canceled the automatic merge"
body
=
"Cancel
l
ed the automatic merge"
create_note
(
noteable:
noteable
,
project:
project
,
author:
author
,
note:
body
)
end
...
...
app/views/projects/merge_requests/_merge_request.html.haml
View file @
2462a96e
-
ci_commit
=
merge_request
.
ci_commit
%li
{
class:
mr_css_classes
(
merge_request
)
}
.merge-request-title
%span
.merge-request-title-text
...
...
@@ -7,8 +6,8 @@
-
merge_request
.
labels
.
each
do
|
label
|
=
link_to_label
(
label
,
project:
merge_request
.
project
)
.pull-right.light
-
if
ci_commit
=
render_ci_status
(
ci_commit
)
-
if
merge_request
.
ci_commit
=
render_ci_status
(
merge_request
.
ci_commit
)
-
if
merge_request
.
merged?
%span
%i
.fa.fa-check
...
...
app/views/projects/merge_requests/widget/_heading.html.haml
View file @
2462a96e
-
ci_commit
=
@merge_request
.
ci_commit
-
if
ci_commit
-
status
=
ci_commit
.
status
-
if
@merge_request
.
ci_commit
-
status
=
@merge_request
.
ci_commit
.
status
.mr-widget-heading
.ci_widget
{
class:
"ci-#{status}"
}
=
ci_status_icon
(
ci_commit
)
=
ci_status_icon
(
@merge_request
.
ci_commit
)
%span
CI build
#{
status
}
for
#{
@merge_request
.
last_commit_short_sha
}
.
%span
.ci-coverage
=
link_to
"View build details"
,
ci_status_path
(
ci_commit
)
=
link_to
"View build details"
,
ci_status_path
(
@merge_request
.
ci_commit
)
-
elsif
@merge_request
.
has_ci?
-
# Compatibility with old CI integrations (ex jenkins) when you request status from CI server via AJAX
...
...
app/views/projects/merge_requests/widget/open/_accept.html.haml
View file @
2462a96e
...
...
@@ -4,8 +4,7 @@
=
hidden_field_tag
:authenticity_token
,
form_authenticity_token
.accept-merge-holder.clearfix.js-toggle-container
.accept-action
-
ci_commit
=
@merge_request
.
ci_commit
-
if
ci_commit
&&
ci_commit
.
active?
-
if
@merge_request
.
ci_commit
&&
@merge_request
.
ci_commit
.
active?
=
f
.
button
class:
"btn btn-create btn-grouped merge_when_build_succeeds"
,
name:
"merge_when_build_succeeds"
do
Merge When Build Succeeds
=
f
.
button
class:
"btn btn-create btn-grouped accept_merge_request
#{
status_class
}
"
do
...
...
app/views/projects/merge_requests/widget/open/_merge_when_build_succeeds.html.haml
View file @
2462a96e
%h4
Approved
by
#{
link_to_member
(
@project
,
@merge_request
.
merge_user
,
avatar:
true
)
}
Set
by
#{
link_to_member
(
@project
,
@merge_request
.
merge_user
,
avatar:
true
)
}
to be merged automatically when
#{
link_to
"the build"
,
ci_status_path
(
@merge_request
.
ci_commit
)
}
succeeds.
%div
-
s
ource_branch_removed
=
@merge_request
.
merge_params
[
"should_remove_source_branch"
].
present?
-
if
source_branch_removed
-
s
hould_remove_source_branch
=
@merge_request
.
merge_params
[
"should_remove_source_branch"
].
present?
%p
=
succeed
'.'
do
The changes will be merged into
%span
.label-branch
=
@merge_request
.
target_branch
-
if
should_remove_source_branch
The source branch will be removed.
-
else
%p
=
succeed
'.'
do
The changes will be merged into
%span
.label-branch
=
@merge_request
.
target_branch
The source branch will not be removed.
-
if
(
@merge_request
.
can_remove_source_branch?
(
current_user
)
&&
!
source_branch_removed
)
||
@merge_request
.
can_cancel_merge_when_build_succeeds?
(
current_user
)
-
remove_source_branch_button
=
@merge_request
.
can_remove_source_branch?
(
current_user
)
&&
!
should_remove_source_branch
-
user_can_cancel_automatic_merge
=
@merge_request
.
can_cancel_merge_when_build_succeeds?
(
current_user
)
-
if
remove_source_branch_button
||
user_can_cancel_automatic_merge
.clearfix.prepend-top-10
-
if
@merge_request
.
can_remove_source_branch?
(
current_user
)
&&
!
source_branch_removed
-
if
remove_source_branch_button
=
link_to
merge_namespace_project_merge_request_path
(
@merge_request
.
target_project
.
namespace
,
@merge_request
.
target_project
,
@merge_request
,
merge_when_build_succeeds:
true
,
should_remove_source_branch:
true
),
remote:
true
,
method: :post
,
class:
"btn btn-grouped btn-primary btn-sm remove_source_branch"
do
=
icon
(
'times'
)
Remove Source Branch When Merged
-
if
@merge_request
.
can_cancel_merge_when_build_succeeds?
(
current_user
)
-
if
user_can_cancel_automatic_merge
=
link_to
cancel_merge_when_build_succeeds_namespace_project_merge_request_path
(
@merge_request
.
target_project
.
namespace
,
@merge_request
.
target_project
,
@merge_request
),
remote:
true
,
method: :post
,
class:
"btn btn-grouped btn-warning btn-sm"
do
Cancel Automatic Merge
spec/factories/merge_requests.rb
View file @
2462a96e
...
...
@@ -65,6 +65,11 @@ FactoryGirl.define do
target_branch
"master"
end
trait
:merge_when_build_succeeds
do
merge_when_build_succeeds
true
merge_user
author
end
factory
:closed_merge_request
,
traits:
[
:closed
]
factory
:reopened_merge_request
,
traits:
[
:reopened
]
factory
:merge_request_with_diffs
,
traits:
[
:with_diffs
]
...
...
spec/features/merge_requests/merge_when_build_succeeds_spec.rb
View file @
2462a96e
require
'spec_helper'
# rubocop:disable Lint/UselessAssignment
# As rubocop doesn't see a need for both `ci_commit` and `ci_build`
feature
'Merge When Build Succeeds'
,
feature:
true
,
js:
true
do
let
(
:user
)
{
create
(
:user
)
}
...
...
@@ -32,16 +34,20 @@ feature 'Merge When Build Succeeds', feature: true, js: true do
it
'activates Merge When Build Succeeds feature'
do
expect
(
page
).
to
have_link
"Cancel Automatic Merge"
expect
(
page
).
to
have_content
"
Approved
by
#{
user
.
name
}
to be merged automatically when the build succeeds."
expect
(
page
).
to
have_content
"
Set
by
#{
user
.
name
}
to be merged automatically when the build succeeds."
expect
(
page
).
to
have_content
"The source branch will not be removed."
visit_merge_request
(
merge_request
)
# Needed to refresh the page
expect
(
page
).
to
have_content
/Enabled an automatic merge when the build for [0-9a-f]{8} succeeds/i
end
end
end
context
'When it is enabled'
do
# No clue how, but push a new commit to the branch
let
(
:merge_request
)
{
create
(
:merge_request_with_diffs
,
source_project:
project
,
# source_branch: "mepmep",
author:
user
,
title:
"Bug NS-04"
,
merge_when_build_succeeds:
true
)
}
let
(
:merge_request
)
do
create
(
:merge_request_with_diffs
,
source_project:
project
,
author:
user
,
merge_user:
user
,
title:
"MepMep"
,
merge_when_build_succeeds:
true
)
end
before
do
merge_request
.
source_project
.
team
<<
[
user
,
:master
]
...
...
@@ -60,10 +66,16 @@ feature 'Merge When Build Succeeds', feature: true, js: true do
click_link
"Cancel Automatic Merge"
expect
(
page
).
to
have_button
"Merge When Build Succeeds"
visit_merge_request
(
merge_request
)
# Needed to refresh the page
expect
(
page
).
to
have_content
"Cancelled the automatic merge"
end
it
"allows the user to remove the source branch"
do
expect
(
page
).
to
have_link
"Remove Source Branch When Merged"
click_link
"Remove Source Branch When Merged"
expect
(
page
).
to
have_content
"The source branch will be removed"
end
end
...
...
@@ -78,3 +90,4 @@ feature 'Merge When Build Succeeds', feature: true, js: true do
visit
namespace_project_merge_request_path
(
merge_request
.
project
.
namespace
,
merge_request
.
project
,
merge_request
)
end
end
# rubocop:enable Lint/UselessAssignment
spec/models/merge_request_spec.rb
View file @
2462a96e
...
...
@@ -48,6 +48,24 @@ describe MergeRequest do
describe
'validation'
do
it
{
is_expected
.
to
validate_presence_of
(
:target_branch
)
}
it
{
is_expected
.
to
validate_presence_of
(
:source_branch
)
}
context
"Validation of merge user with Merge When Build succeeds"
do
it
"allows user to be nil when the feature is disabled"
do
expect
(
subject
).
to
be_valid
end
it
"is invalid without merge user"
do
subject
.
merge_when_build_succeeds
=
true
expect
(
subject
).
not_to
be_valid
end
it
"is valid with merge user"
do
subject
.
merge_when_build_succeeds
=
true
subject
.
merge_user
=
build
(
:user
)
expect
(
subject
).
to
be_valid
end
end
end
describe
'respond to'
do
...
...
@@ -175,31 +193,41 @@ describe MergeRequest do
end
describe
'#can_remove_source_branch'
do
let
(
:user
)
{
build
(
:user
)}
let
(
:user
)
{
create
(
:user
)
}
let
(
:user2
)
{
create
(
:user
)
}
before
do
subject
.
source_project
.
team
<<
[
user
,
:master
]
end
it
"cant be merged when its a a protected branch"
do
subject
.
source_project
.
protected_branches
=
[];
subject
.
source_branch
=
"feature"
subject
.
target_branch
=
"master"
subject
.
save!
end
it
"can't be removed when its a protected branch"
do
allow
(
subject
.
source_project
).
to
receive
(
:protected_branch?
).
and_return
(
true
)
expect
(
subject
.
can_remove_source_branch?
(
user
)).
to
be_falsey
end
it
"cant remove a root ref"
do
subject
.
source_branch
=
"master"
;
subject
.
source_branch
=
"master"
subject
.
target_branch
=
"feature"
expect
(
subject
.
can_remove_source_branch?
(
user
)).
to
be_falsey
end
it
"is truthy in all other cases"
do
expect
(
subject
.
can_remove_source_branch?
(
user
))
it
"is unable to remove the source branch for a project the user cannot push to"
do
expect
(
subject
.
can_remove_source_branch?
(
user2
)).
to
be_falsey
end
it
"is can be removed in all other cases"
do
expect
(
subject
.
can_remove_source_branch?
(
user
)).
to
be_truthy
end
end
describe
"#reset_merge_when_build_succeeds"
do
let
(
:merge_if_green
)
{
create
:merge_request
,
merge_when_build_succeeds:
true
}
let
(
:merge_if_green
)
{
create
:merge_request
,
merge_when_build_succeeds:
true
,
merge_user:
create
(
:user
)
}
it
"sets the item to false"
do
merge_if_green
.
reset_merge_when_build_succeeds
merge_if_green
.
reload
...
...
spec/requests/api/merge_requests_spec.rb
View file @
2462a96e
...
...
@@ -303,7 +303,7 @@ describe API::API, api: true do
end
describe
"PUT /projects/:id/merge_request/:merge_request_id/merge"
do
let
(
:ci_commit
)
{
create
(
:ci_commit_without_jobs
)
}
let
(
:ci_commit
)
{
create
(
:ci_commit_without_jobs
)
}
it
"should return merge_request in case of success"
do
put
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
/merge"
,
user
)
...
...
spec/services/merge_requests/merge_when_build_succeeds_service_spec.rb
View file @
2462a96e
...
...
@@ -3,37 +3,38 @@ require 'spec_helper'
describe
MergeRequests
::
MergeWhenBuildSucceedsService
do
let
(
:user
)
{
create
(
:user
)
}
let
(
:merge_request
)
{
create
(
:merge_request
)
}
let
(
:mr_merge_if_green_enabled
)
{
create
(
:merge_request
,
merge_when_build_succeeds:
true
,
let
(
:mr_merge_if_green_enabled
)
do
create
(
:merge_request
,
merge_when_build_succeeds:
true
,
merge_user:
user
,
source_branch:
"source_branch"
,
target_branch:
project
.
default_branch
,
source_project:
project
,
target_project:
project
,
state:
"opened"
)
}
let
(
:ci_commit
)
{
create
(
:ci_commit_with_one_job
,
ref:
mr_merge_if_green_enabled
.
source_branch
)
}
source_project:
project
,
target_project:
project
,
state:
"opened"
)
end
let
(
:project
)
{
create
(
:project
)
}
let
(
:ci_commit
)
{
create
(
:ci_commit_with_one_job
,
ref:
mr_merge_if_green_enabled
.
source_branch
,
gl_project:
project
)
}
let
(
:service
)
{
MergeRequests
::
MergeWhenBuildSucceedsService
.
new
(
project
,
user
,
commit_message:
'Awesome message'
)
}
before
do
project
.
ci_commits
=
[
ci_commit
]
project
.
save!
end
describe
"#execute"
do
context
'first time enabling'
do
before
do
allow
(
merge_request
).
to
receive
(
:ci_commit
).
and_return
(
ci_commit
)
service
.
execute
(
merge_request
)
end
it
'sets the params, merge_user, and flag'
do
service
.
execute
(
merge_request
)
expect
(
merge_request
).
to
be_valid
expect
(
merge_request
.
merge_when_build_succeeds
).
to
be_truthy
expect
(
merge_request
.
merge_params
).
to
eq
commit_message:
'Awesome message'
expect
(
merge_request
.
merge_user
).
to
be
user
end
it
'creates a system note'
do
note
=
merge_request
.
notes
.
last
expect
(
note
.
note
).
to
include
'Enabled an automatic merge when the build for'
expect
(
note
.
note
).
to
match
/Enabled an automatic merge when the build for (\w+\/\w+@)?[0-9a-z]{8}/
end
end
context
'al
l
ready approved'
do
context
'already approved'
do
let
(
:service
)
{
MergeRequests
::
MergeWhenBuildSucceedsService
.
new
(
project
,
user
,
new_key:
true
)
}
let
(
:build
)
{
create
(
:ci_build
,
ref:
mr_merge_if_green_enabled
.
source_branch
)
}
...
...
@@ -74,5 +75,10 @@ describe MergeRequests::MergeWhenBuildSucceedsService do
expect
(
mr_merge_if_green_enabled
.
merge_params
).
to
eq
({})
expect
(
mr_merge_if_green_enabled
.
merge_user
).
to
be
nil
end
it
'Posts a system note'
do
note
=
mr_merge_if_green_enabled
.
notes
.
last
expect
(
note
.
note
).
to
include
'Cancelled the automatic merge'
end
end
end
spec/services/merge_requests/refresh_service_spec.rb
View file @
2462a96e
...
...
@@ -18,7 +18,8 @@ describe MergeRequests::RefreshService do
source_branch:
'master'
,
target_branch:
'feature'
,
target_project:
@project
,
merge_when_build_succeeds:
true
)
merge_when_build_succeeds:
true
,
merge_user:
@user
)
@fork_merge_request
=
create
(
:merge_request
,
source_project:
@fork_project
,
...
...
spec/services/system_note_service_spec.rb
View file @
2462a96e
...
...
@@ -208,20 +208,20 @@ describe SystemNoteService do
end
describe
'.merge_when_build_succeeds'
do
let
(
:ci_commit
)
{
create
:ci_commit_without_jobs
}
let
(
:ci_commit
)
{
build
:ci_commit_without_jobs
}
let
(
:noteable
)
{
create
:merge_request
}
subject
{
described_class
.
merge_when_build_succeeds
(
noteable
,
project
,
author
,
ci
_commit
)
}
subject
{
described_class
.
merge_when_build_succeeds
(
noteable
,
project
,
author
,
noteable
.
last
_commit
)
}
it_behaves_like
'a system note'
it
"posts the Merge When Build Succeeds system note"
do
expect
(
subject
.
note
).
to
eq
"Enabled an automatic merge when the build for 97de212e80737a608d939f648d959671fb0a0142 succeeds"
expect
(
subject
.
note
).
to
match
/Enabled an automatic merge when the build for (\w+\/\w+@)?[0-9a-f]{40} succeeds/
end
end
describe
'.cancel_merge_when_build_succeeds'
do
let
(
:ci_commit
)
{
create
:ci_commit_without_jobs
}
let
(
:ci_commit
)
{
build
:ci_commit_without_jobs
}
let
(
:noteable
)
{
create
:merge_request
}
subject
{
described_class
.
cancel_merge_when_build_succeeds
(
noteable
,
project
,
author
)
}
...
...
@@ -229,7 +229,7 @@ describe SystemNoteService do
it_behaves_like
'a system note'
it
"posts the Merge When Build Succeeds system note"
do
expect
(
subject
.
note
).
to
eq
"Canceled the automatic merge"
expect
(
subject
.
note
).
to
eq
"Cancel
l
ed the automatic merge"
end
end
...
...
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