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
Tatuya Kamada
gitlab-ce
Commits
77f8a1e3
Commit
77f8a1e3
authored
Nov 02, 2015
by
Zeger-Jan van de Weg
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Merge when build succeeds
parent
8c9e1df9
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
219 additions
and
20 deletions
+219
-20
CHANGELOG
CHANGELOG
+1
-0
app/assets/stylesheets/pages/merge_requests.scss
app/assets/stylesheets/pages/merge_requests.scss
+3
-1
app/controllers/projects/merge_requests_controller.rb
app/controllers/projects/merge_requests_controller.rb
+29
-6
app/models/ci/commit.rb
app/models/ci/commit.rb
+8
-0
app/models/commit_status.rb
app/models/commit_status.rb
+33
-0
app/models/merge_request.rb
app/models/merge_request.rb
+13
-0
app/services/merge_requests/merge_when_build_succeeds_service.rb
...vices/merge_requests/merge_when_build_succeeds_service.rb
+43
-0
app/services/merge_requests/refresh_service.rb
app/services/merge_requests/refresh_service.rb
+7
-1
app/services/system_note_service.rb
app/services/system_note_service.rb
+14
-0
app/views/projects/merge_requests/cancel_merge_when_build_succeeds.js.haml
...s/merge_requests/cancel_merge_when_build_succeeds.js.haml
+2
-0
app/views/projects/merge_requests/merge.js.haml
app/views/projects/merge_requests/merge.js.haml
+5
-1
app/views/projects/merge_requests/widget/_open.html.haml
app/views/projects/merge_requests/widget/_open.html.haml
+2
-0
app/views/projects/merge_requests/widget/open/_accept.html.haml
...ews/projects/merge_requests/widget/open/_accept.html.haml
+13
-5
app/views/projects/merge_requests/widget/open/_merge_when_build_succeeds.html.haml
...requests/widget/open/_merge_when_build_succeeds.html.haml
+27
-0
config/routes.rb
config/routes.rb
+1
-0
db/migrate/20151028152939_add_merge_when_build_succeeds_to_merge_request.rb
...8152939_add_merge_when_build_succeeds_to_merge_request.rb
+7
-0
db/schema.rb
db/schema.rb
+11
-6
No files found.
CHANGELOG
View file @
77f8a1e3
...
...
@@ -14,6 +14,7 @@ v 8.2.0 (unreleased)
- Fix: 500 error returned if destroy request without HTTP referer (Kazuki Shimizu)
- Remove deprecated CI events from project settings page
- Use issue editor as cross reference comment author when issue is edited with a new mention.
- Merge when build succeeds (Zeger-Jan van de Weg)
v 8.1.1
- Fix cloning Wiki repositories via HTTP (Stan Hu)
...
...
app/assets/stylesheets/pages/merge_requests.scss
View file @
77f8a1e3
...
...
@@ -19,18 +19,20 @@
.accept-merge-holder
{
.accept-action
{
display
:
inline-block
;
float
:
left
;
}
.accept-control
{
display
:
inline-block
;
float
:
left
;
margin
:
0
;
margin-left
:
20px
;
padding
:
5px
;
padding-top
:
12px
;
line-height
:
20px
;
&
.right
{
float
:
right
;
padding-top
:
12px
;
a
{
color
:
$gl-gray
;
}
...
...
app/controllers/projects/merge_requests_controller.rb
View file @
77f8a1e3
...
...
@@ -2,7 +2,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
before_action
:module_enabled
before_action
:merge_request
,
only:
[
:edit
,
:update
,
:show
,
:diffs
,
:commits
,
:merge
,
:merge_check
,
:ci_status
,
:toggle_subscription
:ci_status
,
:toggle_subscription
,
:cancel_merge_when_build_succeeds
]
before_action
:closes_issues
,
only:
[
:edit
,
:update
,
:show
,
:diffs
,
:commits
]
before_action
:validates_merge_request
,
only:
[
:show
,
:diffs
,
:commits
]
...
...
@@ -149,15 +149,34 @@ class Projects::MergeRequestsController < Projects::ApplicationController
render
partial:
"projects/merge_requests/widget/show.html.haml"
,
layout:
false
end
def
cancel_merge_when_build_succeeds
return
access_denied!
unless
@merge_request
.
can_be_merged_by?
(
current_user
)
if
@merge_request
.
merge_when_build_succeeds?
@merge_request
.
reset_merge_when_build_succeeds
SystemNoteService
.
cancel_merge_when_build_succeeds
(
merge_request
,
@project
,
@current_user
)
end
end
def
merge
return
access_denied!
unless
@merge_request
.
can_be_merged_by?
(
current_user
)
if
@merge_request
.
mergeable?
@merge_request
.
update
(
merge_error:
nil
)
MergeWorker
.
perform_async
(
@merge_request
.
id
,
current_user
.
id
,
params
)
@status
=
true
unless
@merge_request
.
mergeable?
@status
=
:failed
return
end
@merge_request
.
update
(
merge_error:
nil
)
if
params
[
:merge_when_build_succeeds
]
&&
@merge_request
.
ci_commit
.
active?
MergeRequests
::
MergeWhenBuildSucceedsService
.
new
(
@project
,
current_user
,
merge_params:
merge_params
)
.
execute
(
@merge_request
)
@status
=
:merge_when_build_succeeds
else
@status
=
false
MergeWorker
.
perform_async
(
@merge_request
.
id
,
current_user
.
id
,
params
)
@status
=
:success
end
end
...
...
@@ -282,6 +301,10 @@ class Projects::MergeRequestsController < Projects::ApplicationController
)
end
def
merge_params
params
.
permit
(
:should_remove_source_branch
,
:commit_message
)
end
# Make sure merge requests created before 8.0
# have head file in refs/merge-requests/
def
ensure_ref_fetched
...
...
app/models/ci/commit.rb
View file @
77f8a1e3
...
...
@@ -164,6 +164,14 @@ module Ci
status
==
'canceled'
end
def
active?
running?
||
pending?
end
def
complete?
canceled?
||
success?
||
failed?
end
def
duration
duration_array
=
latest_statuses
.
map
(
&
:duration
).
compact
duration_array
.
reduce
(:
+
).
to_i
...
...
app/models/commit_status.rb
View file @
77f8a1e3
# == Schema Information
#
# project_id integer
# status string
# finished_at datetime
# trace text
# created_at datetime
# updated_at datetime
# started_at datetime
# runner_id integer
# coverage float
# commit_id integer
# commands text
# job_id integer
# name string
# deploy boolean default: false
# options text
# allow_failure boolean default: false, null: false
# stage string
# trigger_request_id integer
# stage_idx integer
# tag boolean
# ref string
# user_id integer
# type string
# target_url string
# description string
#
class
CommitStatus
<
ActiveRecord
::
Base
self
.
table_name
=
'ci_builds'
...
...
@@ -46,6 +75,10 @@ class CommitStatus < ActiveRecord::Base
build
.
update_attributes
finished_at:
Time
.
now
end
after_transition
running: :success
do
|
build
,
transition
|
MergeRequests
::
MergeWhenBuildSucceedsService
.
new
(
build
.
commit
.
gl_project
,
nil
).
trigger
(
build
)
end
state
:pending
,
value:
'pending'
state
:running
,
value:
'running'
state
:failed
,
value:
'failed'
...
...
app/models/merge_request.rb
View file @
77f8a1e3
...
...
@@ -34,9 +34,12 @@ class MergeRequest < ActiveRecord::Base
belongs_to
:target_project
,
foreign_key: :target_project_id
,
class_name:
"Project"
belongs_to
:source_project
,
foreign_key: :source_project_id
,
class_name:
"Project"
belongs_to
:merge_user
,
class_name:
"User"
has_one
:merge_request_diff
,
dependent: :destroy
serialize
:merge_params
,
Hash
after_create
:create_merge_request_diff
after_update
:update_merge_request_diff
...
...
@@ -385,6 +388,16 @@ class MergeRequest < ActiveRecord::Base
message
end
def
reset_merge_when_build_succeeds
return
unless
merge_when_build_succeeds?
self
.
merge_when_build_succeeds
=
false
self
.
merge_user
=
nil
self
.
merge_params
=
nil
self
.
save
end
# Return array of possible target branches
# depends on target project of MR
def
target_branches
...
...
app/services/merge_requests/merge_when_build_succeeds_service.rb
0 → 100644
View file @
77f8a1e3
module
MergeRequests
class
MergeWhenBuildSucceedsService
<
MergeRequests
::
BaseService
def
execute
(
merge_request
)
merge_request
.
merge_params
.
merge!
(
params
[
:merge_params
])
# The service is also called when the merge params are updated.
already_approved
=
merge_request
.
merge_when_build_succeeds?
unless
already_approved
merge_request
.
merge_when_build_succeeds
=
true
merge_request
.
merge_user
=
@current_user
end
merge_request
.
save
unless
already_approved
SystemNoteService
.
merge_when_build_succeeds
(
merge_request
,
@project
,
@current_user
)
end
end
def
trigger
(
build
)
merge_requests
=
merge_request_from
(
build
)
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?
MergeWorker
.
perform_async
(
merge_request
.
id
,
merge_request
.
merge_user_id
,
merge_request
.
merge_params
)
end
end
end
private
def
merge_request_from
(
build
)
merge_requests
=
@project
.
origin_merge_requests
.
opened
.
where
(
source_branch:
build
.
ref
).
to_a
merge_requests
+=
@project
.
fork_merge_requests
.
opened
.
where
(
source_branch:
build
.
ref
).
to_a
merge_requests
.
uniq
.
select
(
&
:source_project
)
end
end
end
app/services/merge_requests/refresh_service.rb
View file @
77f8a1e3
...
...
@@ -8,6 +8,7 @@ module MergeRequests
find_new_commits
reload_merge_requests
reset_merge_when_build_succeeds
# Leave a system note if a branch was deleted/added
if
branch_added?
||
branch_removed?
...
...
@@ -57,7 +58,6 @@ module MergeRequests
merge_requests
=
filter_merge_requests
(
merge_requests
)
merge_requests
.
each
do
|
merge_request
|
if
merge_request
.
source_branch
==
@branch_name
||
force_push?
merge_request
.
reload_code
merge_request
.
mark_as_unchecked
...
...
@@ -76,6 +76,12 @@ module MergeRequests
end
end
def
reset_merge_when_build_succeeds
merge_requests_for_source_branch
.
each
do
|
merge_request
|
merge_request
.
reset_merge_when_build_succeeds
end
end
def
find_new_commits
if
branch_added?
@commits
=
[]
...
...
app/services/system_note_service.rb
View file @
77f8a1e3
...
...
@@ -130,6 +130,20 @@ class SystemNoteService
create_note
(
noteable:
noteable
,
project:
project
,
author:
author
,
note:
body
)
end
# Called when 'merge when build succeeds' is executed
def
self
.
merge_when_build_succeeds
(
noteable
,
project
,
author
)
body
=
"Approved this request to be merged automatically when the build 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"
create_note
(
noteable:
noteable
,
project:
project
,
author:
author
,
note:
body
)
end
# Called when the title of a Noteable is changed
#
# noteable - Noteable object that responds to `title`
...
...
app/views/projects/merge_requests/cancel_merge_when_build_succeeds.js.haml
0 → 100644
View file @
77f8a1e3
:plain
$('.mr-widget-body').html("
#{
escape_javascript
(
render
(
'projects/merge_requests/widget/open/accept'
))
}
");
app/views/projects/merge_requests/merge.js.haml
View file @
77f8a1e3
-
if
@status
-
case
@status
-
when
:success
:plain
merge_request_widget.mergeInProgress();
-
when
:merge_when_build_succeeds
:plain
$('.mr-widget-body').html("
#{
escape_javascript
(
render
(
'projects/merge_requests/widget/open/merge_when_build_succeeds'
))
}
");
-
else
:plain
$('.mr-widget-body').html("
#{
escape_javascript
(
render
(
'projects/merge_requests/widget/open/reload'
))
}
");
app/views/projects/merge_requests/widget/_open.html.haml
View file @
77f8a1e3
...
...
@@ -13,6 +13,8 @@
=
render
'projects/merge_requests/widget/open/conflicts'
-
elsif
@merge_request
.
work_in_progress?
=
render
'projects/merge_requests/widget/open/wip'
-
elsif
@merge_request
.
merge_when_build_succeeds?
=
render
'projects/merge_requests/widget/open/merge_when_build_succeeds'
-
elsif
!
@merge_request
.
can_be_merged_by?
(
current_user
)
=
render
'projects/merge_requests/widget/open/not_allowed'
-
elsif
@merge_request
.
can_be_merged?
...
...
app/views/projects/merge_requests/widget/open/_accept.html.haml
View file @
77f8a1e3
...
...
@@ -2,8 +2,15 @@
=
hidden_field_tag
:authenticity_token
,
form_authenticity_token
.accept-merge-holder.clearfix.js-toggle-container
.accept-action
=
f
.
button
class:
"btn btn-create accept_merge_request"
do
Accept Merge Request
-
ci_commit
=
@merge_request
.
ci_commit
-
if
ci_commit
&&
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-warning btn-grouped accept_merge_request"
do
Accept Merge Request Now
-
else
=
f
.
button
class:
"btn btn-create btn-grouped accept_merge_request"
do
Accept Merge Request
-
if
can_remove_branch?
(
@merge_request
.
source_project
,
@merge_request
.
source_branch
)
&&
!
@merge_request
.
for_fork?
.accept-control.checkbox
=
label_tag
:should_remove_source_branch
,
class:
"remove_source_checkbox"
do
...
...
@@ -19,7 +26,8 @@
rows:
14
,
hint:
true
:coffeescript
$('.accept-mr-form').on 'ajax:before', ->
btn = $('.accept_merge_request')
btn.disable()
$('.accept_merge_request').on 'click', ->
btn = $(this)
btn.html("<i class='fa fa-spinner fa-spin'></i> Merge in progress")
$('.accept-mr-form').on 'ajax:sen', ->
$(".accept-mr-form :input").disable()
app/views/projects/merge_requests/widget/open/_merge_when_build_succeeds.html.haml
0 → 100644
View file @
77f8a1e3
%h4
Approved 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
-
if
@merge_request
.
merge_params
[
"should_remove_source_branch"
]
=
succeed
'.'
do
The changes will be merged into
%span
.label-branch
=
@merge_request
.
target_branch
The source branch will be removed.
-
elsif
can_remove_branch?
(
@merge_request
.
source_project
,
@merge_request
.
source_branch
)
-
remove_source_branch_button
=
true
%p
=
succeed
'.'
do
The changes will be merged into
%span
.label-branch
=
@merge_request
.
target_branch
The source branch will not be removed.
-
if
remove_source_branch_button
||
@merge_request
.
can_be_merged_by?
(
current_user
)
.clearfix.prepend-top-10
-
if
remove_source_branch_button
=
link_to
merge_namespace_project_merge_request_path
(
@merge_request
.
source_project
.
namespace
,
@merge_request
.
source_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_be_merged_by?
(
current_user
)
=
link_to
merge_namespace_project_merge_request_path
(
@merge_request
.
source_project
.
namespace
,
@merge_request
.
source_project
,
@merge_request
),
remote:
true
,
method: :delete
,
class:
"btn btn-grouped btn-warning btn-sm"
do
Cancel Automatic Merge
config/routes.rb
View file @
77f8a1e3
...
...
@@ -556,6 +556,7 @@ Gitlab::Application.routes.draw do
get
:diffs
get
:commits
post
:merge
delete
:merge
,
action: :cancel_merge_when_build_succeeds
get
:merge_check
get
:ci_status
post
:toggle_subscription
...
...
db/migrate/20151028152939_add_merge_when_build_succeeds_to_merge_request.rb
0 → 100644
View file @
77f8a1e3
class
AddMergeWhenBuildSucceedsToMergeRequest
<
ActiveRecord
::
Migration
def
change
add_column
:merge_requests
,
:merge_params
,
:text
add_column
:merge_requests
,
:merge_when_build_succeeds
,
:boolean
,
default:
false
,
null:
false
add_column
:merge_requests
,
:merge_user_id
,
:integer
end
end
db/schema.rb
View file @
77f8a1e3
...
...
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord
::
Schema
.
define
(
version:
2015102
6182941
)
do
ActiveRecord
::
Schema
.
define
(
version:
2015102
8152939
)
do
# These are extensions that must be enabled in order to support this database
enable_extension
"plpgsql"
...
...
@@ -418,6 +418,7 @@ ActiveRecord::Schema.define(version: 20151026182941) do
end
add_index
"labels"
,
[
"project_id"
],
name:
"index_labels_on_project_id"
,
using: :btree
add_index
"labels"
,
[
"title"
],
name:
"index_labels_on_title"
,
using: :btree
create_table
"members"
,
force:
true
do
|
t
|
t
.
integer
"access_level"
,
null:
false
...
...
@@ -453,9 +454,9 @@ ActiveRecord::Schema.define(version: 20151026182941) do
add_index
"merge_request_diffs"
,
[
"merge_request_id"
],
name:
"index_merge_request_diffs_on_merge_request_id"
,
unique:
true
,
using: :btree
create_table
"merge_requests"
,
force:
true
do
|
t
|
t
.
string
"target_branch"
,
null:
false
t
.
string
"source_branch"
,
null:
false
t
.
integer
"source_project_id"
,
null:
false
t
.
string
"target_branch"
,
null:
false
t
.
string
"source_branch"
,
null:
false
t
.
integer
"source_project_id"
,
null:
false
t
.
integer
"author_id"
t
.
integer
"assignee_id"
t
.
string
"title"
...
...
@@ -464,13 +465,16 @@ ActiveRecord::Schema.define(version: 20151026182941) do
t
.
integer
"milestone_id"
t
.
string
"state"
t
.
string
"merge_status"
t
.
integer
"target_project_id"
,
null:
false
t
.
integer
"target_project_id"
,
null:
false
t
.
integer
"iid"
t
.
text
"description"
t
.
integer
"position"
,
default:
0
t
.
integer
"position"
,
default:
0
t
.
datetime
"locked_at"
t
.
integer
"updated_by_id"
t
.
string
"merge_error"
t
.
text
"merge_params"
t
.
boolean
"merge_when_build_succeeds"
,
default:
false
,
null:
false
t
.
integer
"merge_user_id"
end
add_index
"merge_requests"
,
[
"assignee_id"
],
name:
"index_merge_requests_on_assignee_id"
,
using: :btree
...
...
@@ -499,6 +503,7 @@ ActiveRecord::Schema.define(version: 20151026182941) do
add_index
"milestones"
,
[
"due_date"
],
name:
"index_milestones_on_due_date"
,
using: :btree
add_index
"milestones"
,
[
"project_id"
,
"iid"
],
name:
"index_milestones_on_project_id_and_iid"
,
unique:
true
,
using: :btree
add_index
"milestones"
,
[
"project_id"
],
name:
"index_milestones_on_project_id"
,
using: :btree
add_index
"milestones"
,
[
"title"
],
name:
"index_milestones_on_title"
,
using: :btree
create_table
"namespaces"
,
force:
true
do
|
t
|
t
.
string
"name"
,
null:
false
...
...
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