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
69c4e0a1
Commit
69c4e0a1
authored
Jan 28, 2016
by
James Lopez
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce into hotfix/ruby-21-broken-update
parents
902baa2e
88e16c3d
Changes
40
Hide whitespace changes
Inline
Side-by-side
Showing
40 changed files
with
569 additions
and
313 deletions
+569
-313
CHANGELOG
CHANGELOG
+3
-0
app/assets/javascripts/issue.js.coffee
app/assets/javascripts/issue.js.coffee
+1
-0
app/assets/javascripts/notes.js.coffee
app/assets/javascripts/notes.js.coffee
+3
-0
app/assets/javascripts/projects_list.js.coffee
app/assets/javascripts/projects_list.js.coffee
+3
-1
app/assets/stylesheets/framework/typography.scss
app/assets/stylesheets/framework/typography.scss
+1
-1
app/assets/stylesheets/pages/projects.scss
app/assets/stylesheets/pages/projects.scss
+50
-0
app/controllers/application_controller.rb
app/controllers/application_controller.rb
+22
-1
app/controllers/projects/forks_controller.rb
app/controllers/projects/forks_controller.rb
+10
-1
app/helpers/blob_helper.rb
app/helpers/blob_helper.rb
+2
-4
app/helpers/icons_helper.rb
app/helpers/icons_helper.rb
+1
-1
app/helpers/projects_helper.rb
app/helpers/projects_helper.rb
+1
-1
app/models/group.rb
app/models/group.rb
+1
-1
app/views/admin/groups/index.html.haml
app/views/admin/groups/index.html.haml
+1
-1
app/views/admin/projects/index.html.haml
app/views/admin/projects/index.html.haml
+1
-1
app/views/admin/users/index.html.haml
app/views/admin/users/index.html.haml
+1
-1
app/views/explore/groups/index.html.haml
app/views/explore/groups/index.html.haml
+1
-1
app/views/explore/projects/_dropdown.html.haml
app/views/explore/projects/_dropdown.html.haml
+1
-2
app/views/layouts/nav/_project.html.haml
app/views/layouts/nav/_project.html.haml
+7
-0
app/views/projects/branches/index.html.haml
app/views/projects/branches/index.html.haml
+1
-1
app/views/projects/buttons/_dropdown.html.haml
app/views/projects/buttons/_dropdown.html.haml
+1
-1
app/views/projects/forks/index.html.haml
app/views/projects/forks/index.html.haml
+58
-0
app/views/projects/forks/new.html.haml
app/views/projects/forks/new.html.haml
+1
-1
app/views/projects/tree/_tree_header.html.haml
app/views/projects/tree/_tree_header.html.haml
+3
-3
app/views/shared/_sort_dropdown.html.haml
app/views/shared/_sort_dropdown.html.haml
+1
-1
app/views/shared/projects/_list.html.haml
app/views/shared/projects/_list.html.haml
+5
-1
app/views/shared/projects/_project.html.haml
app/views/shared/projects/_project.html.haml
+17
-4
config/routes.rb
config/routes.rb
+1
-1
doc/api/merge_requests.md
doc/api/merge_requests.md
+7
-67
features/dashboard/dashboard.feature
features/dashboard/dashboard.feature
+30
-0
features/project/fork.feature
features/project/fork.feature
+15
-0
features/project/issues/issues.feature
features/project/issues/issues.feature
+22
-0
features/project/merge_requests.feature
features/project/merge_requests.feature
+22
-0
features/steps/dashboard/dashboard.rb
features/steps/dashboard/dashboard.rb
+1
-0
features/steps/project/fork.rb
features/steps/project/fork.rb
+25
-0
features/steps/project/forked_merge_requests.rb
features/steps/project/forked_merge_requests.rb
+3
-1
features/steps/shared/issuable.rb
features/steps/shared/issuable.rb
+13
-0
lib/api/merge_requests.rb
lib/api/merge_requests.rb
+181
-170
lib/gitlab/current_settings.rb
lib/gitlab/current_settings.rb
+19
-12
spec/requests/api/merge_requests_spec.rb
spec/requests/api/merge_requests_spec.rb
+31
-31
spec/routing/project_routing_spec.rb
spec/routing/project_routing_spec.rb
+2
-2
No files found.
CHANGELOG
View file @
69c4e0a1
Please view this file on the master branch, on stable branches it's out of date.
v 8.5.0 (unreleased)
- Ensure rake tasks that don't need a DB connection can be run without one
- Add "visibility" flag to GET /projects api endpoint
- Ignore binary files in code search to prevent Error 500 (Stan Hu)
- Upgrade gitlab_git to 7.2.23 to fix commit message mentions in first branch push
...
...
@@ -14,6 +15,8 @@ v 8.5.0 (unreleased)
- Track project import failure
- Fix visibility level text in admin area (Zeger-Jan van de Weg)
- Update the ExternalIssue regex pattern (Blake Hitchcock)
- Deprecate API "merge_request/:merge_request_id/comments". Use "merge_requests/:merge_request_id/notes" instead
- Deprecate API "merge_request/:merge_request_id/...". Use "merge_requests/:merge_request_id/..." instead
v 8.4.2
- Bump required gitlab-workhorse version to bring in a fix for missing
...
...
app/assets/javascripts/issue.js.coffee
View file @
69c4e0a1
...
...
@@ -50,6 +50,7 @@ class @Issue
new
Flash
(
issueFailMessage
,
'alert'
)
success
:
(
data
,
textStatus
,
jqXHR
)
->
if
data
.
saved
$
(
document
).
trigger
(
'issuable:change'
);
if
isClose
$
(
'a.btn-close'
).
addClass
(
'hidden'
)
$
(
'a.btn-reopen'
).
removeClass
(
'hidden'
)
...
...
app/assets/javascripts/notes.js.coffee
View file @
69c4e0a1
...
...
@@ -64,6 +64,9 @@ class @Notes
# fetch notes when tab becomes visible
$
(
document
).
on
"visibilitychange"
,
@
visibilityChange
# when issue status changes, we need to refresh data
$
(
document
).
on
"issuable:change"
,
@
refresh
cleanBinding
:
->
$
(
document
).
off
"ajax:success"
,
".js-main-target-form"
$
(
document
).
off
"ajax:success"
,
".js-discussion-note-form"
...
...
app/assets/javascripts/projects_list.js.coffee
View file @
69c4e0a1
...
...
@@ -9,11 +9,13 @@ class @ProjectsList
$
(
".projects-list-filter"
).
keyup
->
terms
=
$
(
this
).
val
()
uiBox
=
$
(
'div.projects-list-holder'
)
filterSelector
=
$
(
this
).
data
(
'filter-selector'
)
||
'span.filter-title'
if
terms
==
""
||
terms
==
undefined
uiBox
.
find
(
"ul.projects-list li"
).
show
()
else
uiBox
.
find
(
"ul.projects-list li"
).
each
(
index
)
->
name
=
$
(
this
).
find
(
"span.filter-title"
).
text
()
name
=
$
(
this
).
find
(
filterSelector
).
text
()
if
name
.
toLowerCase
().
search
(
terms
.
toLowerCase
())
==
-
1
$
(
this
).
hide
()
...
...
app/assets/stylesheets/framework/typography.scss
View file @
69c4e0a1
...
...
@@ -115,7 +115,7 @@
ul
,
ol
{
padding
:
0
;
margin
:
6px
0
6px
1
8px
!
important
;
margin
:
6px
0
6px
2
8px
!
important
;
}
li
{
...
...
app/assets/stylesheets/pages/projects.scss
View file @
69c4e0a1
...
...
@@ -564,3 +564,53 @@ pre.light-well {
color
:
#E62958
;
margin-top
:
2px
;
}
/*
* Forks list rendered on Project's forks page
*/
.forks-top-block
{
padding
:
16px
0
;
}
.projects-search-form
{
.dropdown-toggle.btn
{
margin-top
:
-3px
;
}
&
.fork-search-form
{
margin
:
0
;
margin-top
:
-
$gl-padding
;
padding-bottom
:
0
;
input
{
/* Small devices (tablets, 768px and up) */
@media
(
min-width
:
$screen-sm-min
)
{
width
:
180px
;
}
/* Medium devices (desktops, 992px and up) */
@media
(
min-width
:
$screen-md-min
)
{
width
:
350px
;
}
/* Large devices (large desktops, 1200px and up) */
@media
(
min-width
:
$screen-lg-min
)
{
width
:
400px
;
}
}
.sort-forks
{
width
:
160px
;
}
.fork-link
{
float
:
right
;
margin-left
:
$gl-padding
;
}
}
}
.private-forks-notice
.private-fork-icon
{
i
:nth-child
(
1
)
{
color
:
#2AA056
;
}
i
:nth-child
(
2
)
{
color
:
#FFFFFF
;
}
}
app/controllers/application_controller.rb
View file @
69c4e0a1
...
...
@@ -298,7 +298,8 @@ class ApplicationController < ActionController::Base
end
def
set_filters_params
params
[
:sort
]
||=
'id_desc'
set_default_sort
params
[
:scope
]
=
'all'
if
params
[
:scope
].
blank?
params
[
:state
]
=
'opened'
if
params
[
:state
].
blank?
...
...
@@ -405,4 +406,24 @@ class ApplicationController < ActionController::Base
current_user
.
nil?
&&
root_path
==
request
.
path
end
private
def
set_default_sort
key
=
if
is_a_listing_page_for?
(
'issues'
)
||
is_a_listing_page_for?
(
'merge_requests'
)
'issuable_sort'
end
cookies
[
key
]
=
params
[
:sort
]
if
key
&&
params
[
:sort
].
present?
params
[
:sort
]
=
cookies
[
key
]
if
key
params
[
:sort
]
||=
'id_desc'
end
def
is_a_listing_page_for?
(
page_type
)
controller_name
,
action_name
=
params
.
values_at
(
:controller
,
:action
)
(
controller_name
==
"projects/
#{
page_type
}
"
&&
action_name
==
'index'
)
||
(
controller_name
==
'groups'
&&
action_name
==
page_type
)
||
(
controller_name
==
'dashboard'
&&
action_name
==
page_type
)
end
end
app/controllers/projects/forks_controller.rb
View file @
69c4e0a1
...
...
@@ -3,6 +3,15 @@ class Projects::ForksController < Projects::ApplicationController
before_action
:require_non_empty_project
before_action
:authorize_download_code!
def
index
@sort
=
params
[
:sort
]
||
'id_desc'
@all_forks
=
project
.
forks
.
includes
(
:creator
).
order_by
(
@sort
)
@public_forks
,
@protected_forks
=
@all_forks
.
partition
do
|
project
|
can?
(
current_user
,
:read_project
,
project
)
end
end
def
new
@namespaces
=
current_user
.
manageable_namespaces
@namespaces
.
delete
(
@project
.
namespace
)
...
...
@@ -10,7 +19,7 @@ class Projects::ForksController < Projects::ApplicationController
def
create
namespace
=
Namespace
.
find
(
params
[
:namespace_key
])
@forked_project
=
namespace
.
projects
.
find_by
(
path:
project
.
path
)
@forked_project
=
nil
unless
@forked_project
&&
@forked_project
.
forked_from_project
==
project
...
...
app/helpers/blob_helper.rb
View file @
69c4e0a1
...
...
@@ -36,8 +36,7 @@ module BlobHelper
notice:
edit_in_new_fork_notice
,
notice_now:
edit_in_new_fork_notice_now
}
fork_path
=
namespace_project_fork_path
(
project
.
namespace
,
project
,
namespace_key:
current_user
.
namespace
.
id
,
continue:
continue_params
)
fork_path
=
namespace_project_forks_path
(
project
.
namespace
,
project
,
namespace_key:
current_user
.
namespace
.
id
,
continue:
continue_params
)
link_to
"Edit"
,
fork_path
,
class:
'btn'
,
method: :post
end
...
...
@@ -62,8 +61,7 @@ module BlobHelper
notice:
edit_in_new_fork_notice
+
" Try to
#{
action
}
this file again."
,
notice_now:
edit_in_new_fork_notice_now
}
fork_path
=
namespace_project_fork_path
(
project
.
namespace
,
project
,
namespace_key:
current_user
.
namespace
.
id
,
continue:
continue_params
)
fork_path
=
namespace_project_forks_path
(
project
.
namespace
,
project
,
namespace_key:
current_user
.
namespace
.
id
,
continue:
continue_params
)
link_to
label
,
fork_path
,
class:
"btn btn-
#{
btn_class
}
"
,
method: :post
end
...
...
app/helpers/icons_helper.rb
View file @
69c4e0a1
...
...
@@ -7,7 +7,7 @@ module IconsHelper
# font-awesome-rails gem, but should we ever use a different icon pack in the
# future we won't have to change hundreds of method calls.
def
icon
(
names
,
options
=
{})
fa_icon
(
names
,
options
)
options
.
include?
(
:base
)
?
fa_stacked_icon
(
names
,
options
)
:
fa_icon
(
names
,
options
)
end
def
spinner
(
text
=
nil
,
visible
=
false
)
...
...
app/helpers/projects_helper.rb
View file @
69c4e0a1
...
...
@@ -116,7 +116,7 @@ module ProjectsHelper
private
def
get_project_nav_tabs
(
project
,
current_user
)
nav_tabs
=
[
:home
]
nav_tabs
=
[
:home
,
:forks
]
if
!
project
.
empty_repo?
&&
can?
(
current_user
,
:download_code
,
project
)
nav_tabs
<<
[
:files
,
:commits
,
:network
,
:graphs
]
...
...
app/models/group.rb
View file @
69c4e0a1
...
...
@@ -19,7 +19,7 @@ require 'file_size_validator'
class
Group
<
Namespace
include
Gitlab
::
ConfigHelper
include
Referable
has_many
:group_members
,
dependent: :destroy
,
as: :source
,
class_name:
'GroupMember'
alias_method
:members
,
:group_members
has_many
:users
,
through: :group_members
...
...
app/views/admin/groups/index.html.haml
View file @
69c4e0a1
...
...
@@ -17,7 +17,7 @@
.pull-right
.dropdown.inline
%a
.dropdown-toggle.btn
{
href:
'#'
,
"data-toggle"
=>
"dropdown"
}
%span
.light
sort:
%span
.light
-
if
@sort
.
present?
=
sort_options_hash
[
@sort
]
-
else
...
...
app/views/admin/projects/index.html.haml
View file @
69c4e0a1
...
...
@@ -50,7 +50,7 @@
.controls
.dropdown.inline
%button
.dropdown-toggle.btn.btn-sm
{
type:
'button'
,
'data-toggle'
=>
'dropdown'
}
%span
.light
sort:
%span
.light
-
if
@sort
.
present?
=
sort_options_hash
[
@sort
]
-
else
...
...
app/views/admin/users/index.html.haml
View file @
69c4e0a1
...
...
@@ -32,7 +32,7 @@
.pull-right
.dropdown.inline
%a
.dropdown-toggle.btn
{
href:
'#'
,
"data-toggle"
=>
"dropdown"
}
%span
.light
sort:
%span
.light
-
if
@sort
.
present?
=
sort_options_hash
[
@sort
]
-
else
...
...
app/views/explore/groups/index.html.haml
View file @
69c4e0a1
...
...
@@ -18,7 +18,7 @@
.pull-right
.dropdown.inline
%button
.dropdown-toggle.btn
{
type:
'button'
,
'data-toggle'
=>
'dropdown'
}
%span
.light
sort:
%span
.light
-
if
@sort
.
present?
=
sort_options_hash
[
@sort
]
-
else
...
...
app/views/explore/projects/_dropdown.html.haml
View file @
69c4e0a1
.dropdown.inline
%button
.dropdown-toggle.btn
{
type:
'button'
,
'data-toggle'
=>
'dropdown'
}
%span
.light
sort:
%span
.light
-
if
@sort
.
present?
=
sort_options_hash
[
@sort
]
-
elsif
current_page?
(
trending_explore_projects_path
)
||
current_page?
(
explore_root_path
)
...
...
@@ -24,4 +24,3 @@
=
sort_title_recently_updated
=
link_to
explore_projects_filter_path
(
sort:
sort_value_oldest_updated
)
do
=
sort_title_oldest_updated
app/views/layouts/nav/_project.html.haml
View file @
69c4e0a1
...
...
@@ -98,6 +98,13 @@
%span
Wiki
-
if
project_nav_tab?
:forks
=
nav_link
(
controller: :forks
,
action: :index
)
do
=
link_to
namespace_project_forks_path
(
@project
.
namespace
,
@project
),
title:
'Forks'
do
=
icon
(
'code-fork fw'
)
%span
Forks
-
if
project_nav_tab?
:snippets
=
nav_link
(
controller: :snippets
)
do
=
link_to
namespace_project_snippets_path
(
@project
.
namespace
,
@project
),
title:
'Snippets'
,
class:
'shortcuts-snippets'
do
...
...
app/views/projects/branches/index.html.haml
View file @
69c4e0a1
...
...
@@ -10,7 +10,7 @@
.dropdown.inline
%button
.dropdown-toggle.btn
{
type:
'button'
,
'data-toggle'
=>
'dropdown'
}
%span
.light
sort:
%span
.light
-
if
@sort
.
present?
=
@sort
.
humanize
-
else
...
...
app/views/projects/buttons/_dropdown.html.haml
View file @
69c4e0a1
...
...
@@ -46,7 +46,7 @@
-
continue_params
=
{
to:
namespace_project_new_blob_path
(
@project
.
namespace
,
@project
,
@project
.
default_branch
||
'master'
),
notice:
edit_in_new_fork_notice
,
notice_now:
edit_in_new_fork_notice_now
}
-
fork_path
=
namespace_project_fork_path
(
@project
.
namespace
,
@project
,
namespace_key:
current_user
.
namespace
.
id
,
-
fork_path
=
namespace_project_fork
s
_path
(
@project
.
namespace
,
@project
,
namespace_key:
current_user
.
namespace
.
id
,
continue:
continue_params
)
=
link_to
fork_path
,
method: :post
do
=
icon
(
'file fw'
)
...
...
app/views/projects/forks/index.html.haml
0 → 100644
View file @
69c4e0a1
.gray-content-block.top-block.clearfix.white.forks-top-block
.pull-left
-
public_count
=
@public_forks
.
size
-
protected_count
=
@protected_forks
.
size
-
full_count_title
=
"
#{
public_count
}
public and
#{
protected_count
}
private"
==
#{
pluralize
(
@all_forks
.
size
,
'fork'
)
}
:
#{
full_count_title
}
.pull-right
.projects-search-form.fork-search-form
=
search_field_tag
:filter_projects
,
nil
,
placeholder:
'Search forks'
,
class:
'projects-list-filter form-control'
,
spellcheck:
false
,
data:
{
'filter-selector'
=>
'span.namespace-name'
}
.dropdown.inline.prepend-left-10
%button
.dropdown-toggle.btn.sort-forks
{
type:
'button'
,
'data-toggle'
=>
'dropdown'
}
%span
.light
sort:
-
if
@sort
.
present?
=
sort_options_hash
[
@sort
]
-
else
=
sort_title_recently_created
%b
.caret
%ul
.dropdown-menu.dropdown-menu-align-right
%li
-
excluded_filters
=
[
:state
,
:scope
,
:label_name
,
:milestone_id
,
:assignee_id
,
:author_id
]
=
link_to
page_filter_path
(
sort:
sort_value_recently_created
,
without:
excluded_filters
)
do
=
sort_title_recently_created
=
link_to
page_filter_path
(
sort:
sort_value_oldest_created
,
without:
excluded_filters
)
do
=
sort_title_oldest_created
=
link_to
page_filter_path
(
sort:
sort_value_recently_updated
,
without:
excluded_filters
)
do
=
sort_title_recently_updated
=
link_to
page_filter_path
(
sort:
sort_value_oldest_updated
,
without:
excluded_filters
)
do
=
sort_title_oldest_updated
.fork-link.inline
-
if
current_user
.
already_forked?
(
@project
)
&&
current_user
.
manageable_namespaces
.
size
<
2
=
link_to
namespace_project_path
(
current_user
,
current_user
.
fork_of
(
@project
)),
title:
'Go to your fork'
,
class:
'pull-right btn btn-new'
do
=
icon
(
'code-fork fw'
)
Fork
-
else
=
link_to
new_namespace_project_fork_path
(
@project
.
namespace
,
@project
),
title:
"Fork project"
,
class:
'pull-right btn btn-new'
do
=
icon
(
'code-fork fw'
)
Fork
.projects-list-holder
-
if
@public_forks
.
blank?
%ul
.content-list
%li
.nothing-here-block
No forks to show
-
else
=
render
'shared/projects/list'
,
projects:
@public_forks
,
use_creator_avatar:
true
,
forks:
true
,
show_last_commit_as_description:
true
-
if
protected_count
>
0
%ul
.projects-list.private-forks-notice
%li
.project-row
=
icon
(
'lock fw'
,
base:
'circle'
,
class:
'fa-lg private-fork-icon'
)
%strong
=
pluralize
(
protected_count
,
'private fork'
)
%span
you have no access to.
app/views/projects/forks/new.html.haml
View file @
69c4e0a1
...
...
@@ -22,7 +22,7 @@
-
else
.fork-thumbnail
=
link_to
namespace_project_fork_path
(
@project
.
namespace
,
@project
,
namespace_key:
namespace
.
id
),
title:
"Fork here"
,
method:
"POST"
,
class:
'has_tooltip'
do
=
link_to
namespace_project_fork
s
_path
(
@project
.
namespace
,
@project
,
namespace_key:
namespace
.
id
),
title:
"Fork here"
,
method:
"POST"
,
class:
'has_tooltip'
do
=
image_tag
namespace_icon
(
namespace
,
100
)
.caption
%strong
...
...
app/views/projects/tree/_tree_header.html.haml
View file @
69c4e0a1
...
...
@@ -40,7 +40,7 @@
-
continue_params
=
{
to:
namespace_project_new_blob_path
(
@project
.
namespace
,
@project
,
@id
),
notice:
edit_in_new_fork_notice
,
notice_now:
edit_in_new_fork_notice_now
}
-
fork_path
=
namespace_project_fork_path
(
@project
.
namespace
,
@project
,
namespace_key:
current_user
.
namespace
.
id
,
-
fork_path
=
namespace_project_fork
s
_path
(
@project
.
namespace
,
@project
,
namespace_key:
current_user
.
namespace
.
id
,
continue:
continue_params
)
=
link_to
fork_path
,
method: :post
do
=
icon
(
'pencil fw'
)
...
...
@@ -49,7 +49,7 @@
-
continue_params
=
{
to:
request
.
fullpath
,
notice:
edit_in_new_fork_notice
+
" Try to upload a file again."
,
notice_now:
edit_in_new_fork_notice_now
}
-
fork_path
=
namespace_project_fork_path
(
@project
.
namespace
,
@project
,
namespace_key:
current_user
.
namespace
.
id
,
-
fork_path
=
namespace_project_fork
s
_path
(
@project
.
namespace
,
@project
,
namespace_key:
current_user
.
namespace
.
id
,
continue:
continue_params
)
=
link_to
fork_path
,
method: :post
do
=
icon
(
'file fw'
)
...
...
@@ -58,7 +58,7 @@
-
continue_params
=
{
to:
request
.
fullpath
,
notice:
edit_in_new_fork_notice
+
" Try to create a new directory again."
,
notice_now:
edit_in_new_fork_notice_now
}
-
fork_path
=
namespace_project_fork_path
(
@project
.
namespace
,
@project
,
namespace_key:
current_user
.
namespace
.
id
,
-
fork_path
=
namespace_project_fork
s
_path
(
@project
.
namespace
,
@project
,
namespace_key:
current_user
.
namespace
.
id
,
continue:
continue_params
)
=
link_to
fork_path
,
method: :post
do
=
icon
(
'folder fw'
)
...
...
app/views/shared/_sort_dropdown.html.haml
View file @
69c4e0a1
.dropdown.inline.prepend-left-10
%button
.dropdown-toggle.btn
{
type:
'button'
,
'data-toggle'
=>
'dropdown'
}
%span
.light
sort:
%span
.light
-
if
@sort
.
present?
=
sort_options_hash
[
@sort
]
-
else
...
...
app/views/shared/projects/_list.html.haml
View file @
69c4e0a1
-
projects_limit
=
20
unless
local_assigns
[
:projects_limit
]
-
avatar
=
true
unless
local_assigns
[
:avatar
]
==
false
-
use_creator_avatar
=
false
unless
local_assigns
[
:use_creator_avatar
]
==
true
-
stars
=
true
unless
local_assigns
[
:stars
]
==
false
-
forks
=
false
unless
local_assigns
[
:forks
]
==
true
-
ci
=
false
unless
local_assigns
[
:ci
]
==
true
-
skip_namespace
=
false
unless
local_assigns
[
:skip_namespace
]
==
true
-
show_last_commit_as_description
=
false
unless
local_assigns
[
:show_last_commit_as_description
]
==
true
%ul
.projects-list
-
projects
.
each_with_index
do
|
project
,
i
|
-
css_class
=
(
i
>=
projects_limit
)
?
'hide'
:
nil
=
render
"shared/projects/project"
,
project:
project
,
skip_namespace:
skip_namespace
,
avatar:
avatar
,
stars:
stars
,
css_class:
css_class
,
ci:
ci
avatar:
avatar
,
stars:
stars
,
css_class:
css_class
,
ci:
ci
,
use_creator_avatar:
use_creator_avatar
,
forks:
forks
,
show_last_commit_as_description:
show_last_commit_as_description
-
if
projects
.
size
>
projects_limit
%li
.bottom.center
...
...
app/views/shared/projects/_project.html.haml
View file @
69c4e0a1
-
avatar
=
true
unless
local_assigns
[
:avatar
]
==
false
-
stars
=
true
unless
local_assigns
[
:stars
]
==
false
-
forks
=
false
unless
local_assigns
[
:forks
]
==
true
-
ci
=
false
unless
local_assigns
[
:ci
]
==
true
-
skip_namespace
=
false
unless
local_assigns
[
:skip_namespace
]
==
true
-
css_class
=
''
unless
local_assigns
[
:css_class
]
-
css_class
+=
" no-description"
unless
project
.
description
.
present?
-
show_last_commit_as_description
=
false
unless
local_assigns
[
:show_last_commit_as_description
]
==
true
-
css_class
+=
" no-description"
if
project
.
description
.
blank?
&&
!
show_last_commit_as_description
-
ci_commit
=
project
.
ci_commit
(
project
.
commit
.
sha
)
if
ci
&&
!
project
.
empty_repo?
&&
project
.
commit
-
cache_key
=
[
project
.
namespace
,
project
,
controller
.
controller_name
,
controller
.
action_name
,
current_application_settings
,
'v2.2'
]
-
cache_key
.
push
(
ci_commit
.
status
)
if
ci_commit
...
...
@@ -13,7 +15,10 @@
=
link_to
project_path
(
project
),
class:
dom_class
(
project
)
do
-
if
avatar
.dash-project-avatar
=
project_icon
(
project
,
alt:
''
,
class:
'avatar project-avatar s46'
)
-
if
use_creator_avatar
=
image_tag
avatar_icon
(
project
.
creator
.
email
,
46
),
class:
"avatar s46"
,
alt
:''
-
else
=
project_icon
(
project
,
alt:
''
,
class:
'avatar project-avatar s46'
)
%span
.project-full-name
%span
.namespace-name
-
if
project
.
namespace
&&
!
skip_namespace
...
...
@@ -26,10 +31,18 @@
-
if
ci_commit
=
render_ci_status
(
ci_commit
)
-
if
forks
%span
=
icon
(
'code-fork'
)
=
project
.
forks_count
-
if
stars
%span
%i
.fa.fa-star
=
icon
(
'star'
)
=
project
.
star_count
-
if
project
.
description
.
present?
-
if
show_last_commit_as_description
.project-description
=
link_to_gfm
project
.
commit
.
title
,
namespace_project_commit_path
(
project
.
namespace
,
project
,
project
.
commit
),
class:
"commit-row-message"
-
elsif
project
.
description
.
present?
.project-description
=
markdown
(
project
.
description
,
pipeline: :description
)
config/routes.rb
View file @
69c4e0a1
...
...
@@ -554,7 +554,7 @@ Rails.application.routes.draw do
end
end
resource
:fork
,
only:
[
:new
,
:create
]
resource
s
:forks
,
only:
[
:index
,
:new
,
:create
]
resource
:import
,
only:
[
:new
,
:create
,
:show
]
resources
:refs
,
only:
[]
do
...
...
doc/api/merge_requests.md
View file @
69c4e0a1
...
...
@@ -60,7 +60,7 @@ Parameters:
Shows information about a single merge request.
```
GET /projects/:id/merge_request/:merge_request_id
GET /projects/:id/merge_request
s
/:merge_request_id
```
Parameters:
...
...
@@ -105,7 +105,7 @@ Parameters:
Get a list of merge request commits.
```
GET /projects/:id/merge_request/:merge_request_id/commits
GET /projects/:id/merge_request
s
/:merge_request_id/commits
```
Parameters:
...
...
@@ -142,7 +142,7 @@ Parameters:
Shows information about the merge request including its files and changes.
```
GET /projects/:id/merge_request/:merge_request_id/changes
GET /projects/:id/merge_request
s
/:merge_request_id/changes
```
Parameters:
...
...
@@ -264,7 +264,7 @@ If an error occurs, an error number and a message explaining the reason is retur
Updates an existing merge request. You can change the target branch, title, or even close the MR.
```
PUT /projects/:id/merge_request/:merge_request_id
PUT /projects/:id/merge_request
s
/:merge_request_id
```
Parameters:
...
...
@@ -323,7 +323,7 @@ If merge request is already merged or closed - you get 405 and error message 'Me
If you don't have permissions to accept this merge request - you'll get a 401
```
PUT /projects/:id/merge_request/:merge_request_id/merge
PUT /projects/:id/merge_request
s
/:merge_request_id/merge
```
Parameters:
...
...
@@ -373,7 +373,7 @@ If the merge request is already merged or closed - you get 405 and error message
In case the merge request is not set to be merged when the build succeeds, you'll also get a 406 error.
```
PUT /projects/:id/merge_request/:merge_request_id/cancel_merge_when_build_succeeds
PUT /projects/:id/merge_request
s
/:merge_request_id/cancel_merge_when_build_succeeds
```
Parameters:
...
...
@@ -409,66 +409,6 @@ Parameters:
}
```
## Post comment to MR
Adds a comment to a merge request.
```
POST /projects/:id/merge_request/:merge_request_id/comments
```
Parameters:
-
`id`
(required) - The ID of a project
-
`merge_request_id`
(required) - ID of merge request
-
`note`
(required) - Text of comment
```
json
{
"note"
:
"text1"
}
```
## Get the comments on a MR
Gets all the comments associated with a merge request.
```
GET /projects/:id/merge_request/:merge_request_id/comments
```
Parameters:
-
`id`
(required) - The ID of a project
-
`merge_request_id`
(required) - ID of merge request
```
json
[
{
"note"
:
"this is the 1st comment on the 2merge merge request"
,
"author"
:
{
"id"
:
11
,
"username"
:
"admin"
,
"email"
:
"admin@example.com"
,
"name"
:
"Administrator"
,
"state"
:
"active"
,
"created_at"
:
"2014-03-06T08:17:35.000Z"
}
},
{
"note"
:
"Status changed to closed"
,
"author"
:
{
"id"
:
11
,
"username"
:
"admin"
,
"email"
:
"admin@example.com"
,
"name"
:
"Administrator"
,
"state"
:
"active"
,
"created_at"
:
"2014-03-06T08:17:35.000Z"
}
}
]
```
## Comments on merge requets
Comments are done via the
notes
resource.
Comments are done via the
[
notes
](
notes.md
)
resource.
features/dashboard/dashboard.feature
View file @
69c4e0a1
...
...
@@ -41,3 +41,33 @@ Feature: Dashboard
And
user with name
"John Doe"
left project
"Shop"
When
I visit dashboard activity page
Then
I should see
"John Doe left project Shop"
event
@javascript
Scenario
:
Sorting Issues
Given
I visit dashboard issues page
And
I sort the list by
"Oldest updated"
And
I visit dashboard activity page
And
I visit dashboard issues page
Then
The list should be sorted by
"Oldest updated"
@javascript
Scenario
:
Visiting Project's issues after sorting
Given
I visit dashboard issues page
And
I sort the list by
"Oldest updated"
And
I visit project
"Shop"
issues page
Then
The list should be sorted by
"Oldest updated"
@javascript
Scenario
:
Sorting Merge Requests
Given
I visit dashboard merge requests page
And
I sort the list by
"Oldest updated"
And
I visit dashboard activity page
And
I visit dashboard merge requests page
Then
The list should be sorted by
"Oldest updated"
@javascript
Scenario
:
Visiting Project's merge requests after sorting
Given
I visit dashboard merge requests page
And
I sort the list by
"Oldest updated"
And
I visit project
"Shop"
merge requests page
Then
The list should be sorted by
"Oldest updated"
features/project/fork.feature
View file @
69c4e0a1
...
...
@@ -25,3 +25,18 @@ Feature: Project Fork
Then
I should see
"New merge request"
And
I click link
"New merge request"
Then
I should see the new merge request page for my namespace
Scenario
:
Viewing forks of a Project
Given
I click link
"Fork"
When
I fork to my namespace
And
I visit the forks page of the
"Shop"
project
Then
I should see my fork on the list
Scenario
:
Viewing private forks of a Project
Given
There is an existent fork of the
"Shop"
project
And
I click link
"Fork"
When
I fork to my namespace
And
I visit the forks page of the
"Shop"
project
Then
I should see my fork on the list
And
I should not see the other fork listed
And
I should see a private fork notice
features/project/issues/issues.feature
View file @
69c4e0a1
...
...
@@ -59,6 +59,28 @@ Feature: Project Issues
And
I sort the list by
"Last updated"
Then
I should see
"Release 0.4"
at the top
@javascript
Scenario
:
Visiting Issues after being sorted the list
Given
I visit project
"Shop"
issues page
And
I sort the list by
"Oldest updated"
And
I visit my project's home page
And
I visit project
"Shop"
issues page
Then
The list should be sorted by
"Oldest updated"
@javascript
Scenario
:
Visiting Merge Requests after being sorted the list
Given
I visit project
"Shop"
issues page
And
I sort the list by
"Oldest updated"
And
I visit project
"Shop"
merge requests page
Then
The list should be sorted by
"Oldest updated"
@javascript
Scenario
:
Visiting Merge Requests from a differente Project after sorting
Given
I visit project
"Shop"
merge requests page
And
I sort the list by
"Oldest updated"
And
I visit dashboard merge requests page
Then
The list should be sorted by
"Oldest updated"
@javascript
Scenario
:
I
search issue
Given
I fill in issue search with
"Re"
...
...
features/project/merge_requests.feature
View file @
69c4e0a1
...
...
@@ -84,6 +84,28 @@ Feature: Project Merge Requests
And
I sort the list by
"Last updated"
Then
I should see
"Bug NS-04"
at the top
@javascript
Scenario
:
Visiting Merge Requests after being sorted the list
Given
I visit project
"Shop"
merge requests page
And
I sort the list by
"Oldest updated"
And
I visit my project's home page
And
I visit project
"Shop"
merge requests page
Then
The list should be sorted by
"Oldest updated"
@javascript
Scenario
:
Visiting Issues after being sorted the list
Given
I visit project
"Shop"
merge requests page
And
I sort the list by
"Oldest updated"
And
I visit project
"Shop"
issues page
Then
The list should be sorted by
"Oldest updated"
@javascript
Scenario
:
Visiting Merge Requests from a differente Project after sorting
Given
I visit project
"Shop"
merge requests page
And
I sort the list by
"Oldest updated"
And
I visit dashboard merge requests page
Then
The list should be sorted by
"Oldest updated"
@javascript
Scenario
:
Visiting Merge Requests after commenting on diffs
Given
project
"Shop"
have
"Bug NS-05"
open merge request with diffs inside
...
...
features/steps/dashboard/dashboard.rb
View file @
69c4e0a1
...
...
@@ -2,6 +2,7 @@ class Spinach::Features::Dashboard < Spinach::FeatureSteps
include
SharedAuthentication
include
SharedPaths
include
SharedProject
include
SharedIssuable
step
'I should see "New Project" link'
do
expect
(
page
).
to
have_link
"New project"
...
...
features/steps/project/fork.rb
View file @
69c4e0a1
...
...
@@ -49,4 +49,29 @@ class Spinach::Features::ProjectFork < Spinach::FeatureSteps
step
'I should see the new merge request page for my namespace'
do
current_path
.
should
have_content
(
/
#{
current_user
.
namespace
.
name
}
/i
)
end
step
'I visit the forks page of the "Shop" project'
do
@project
=
Project
.
where
(
name:
'Shop'
).
last
visit
namespace_project_forks_path
(
@project
.
namespace
,
@project
)
end
step
'I should see my fork on the list'
do
page
.
within
(
'.projects-list-holder'
)
do
project
=
@user
.
fork_of
(
@project
)
expect
(
page
).
to
have_content
(
"
#{
project
.
namespace
.
human_name
}
/
#{
project
.
name
}
"
)
end
end
step
'There is an existent fork of the "Shop" project'
do
user
=
create
(
:user
,
name:
'Mike'
)
@forked_project
=
Projects
::
ForkService
.
new
(
@project
,
user
).
execute
end
step
'I should not see the other fork listed'
do
expect
(
page
).
not_to
have_content
(
"
#{
@forked_project
.
namespace
.
human_name
}
/
#{
@forked_project
.
name
}
"
)
end
step
'I should see a private fork notice'
do
expect
(
page
).
to
have_content
(
"1 private fork"
)
end
end
features/steps/project/forked_merge_requests.rb
View file @
69c4e0a1
...
...
@@ -43,7 +43,9 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps
expect
(
page
).
to
have_css
(
"h3.page-title"
,
text:
"New Merge Request"
)
fill_in
"merge_request_title"
,
with:
"Merge Request On Forked Project"
page
.
within
'form#new_merge_request'
do
fill_in
"merge_request_title"
,
with:
"Merge Request On Forked Project"
end
end
step
'I submit the merge request'
do
...
...
features/steps/shared/issuable.rb
View file @
69c4e0a1
...
...
@@ -106,6 +106,19 @@ module SharedIssuable
edit_issuable
end
step
'I sort the list by "Oldest updated"'
do
find
(
'button.dropdown-toggle.btn'
).
click
page
.
within
(
'ul.dropdown-menu.dropdown-menu-align-right li'
)
do
click_link
"Oldest updated"
end
end
step
'The list should be sorted by "Oldest updated"'
do
page
.
within
(
'div.dropdown.inline.prepend-left-10'
)
do
expect
(
page
.
find
(
'button.dropdown-toggle.btn'
)).
to
have_content
(
'Oldest updated'
)
end
end
def
create_issuable_for_project
(
project_name
:,
title
:,
type: :issue
)
project
=
Project
.
find_by
(
name:
project_name
)
...
...
lib/api/merge_requests.rb
View file @
69c4e0a1
...
...
@@ -59,55 +59,6 @@ module API
present
paginate
(
merge_requests
),
with:
Entities
::
MergeRequest
end
# Show MR
#
# Parameters:
# id (required) - The ID of a project
# merge_request_id (required) - The ID of MR
#
# Example:
# GET /projects/:id/merge_request/:merge_request_id
#
get
":id/merge_request/:merge_request_id"
do
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
authorize!
:read_merge_request
,
merge_request
present
merge_request
,
with:
Entities
::
MergeRequest
end
# Show MR commits
#
# Parameters:
# id (required) - The ID of a project
# merge_request_id (required) - The ID of MR
#
# Example:
# GET /projects/:id/merge_request/:merge_request_id/commits
#
get
':id/merge_request/:merge_request_id/commits'
do
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
authorize!
:read_merge_request
,
merge_request
present
merge_request
.
commits
,
with:
Entities
::
RepoCommit
end
# Show MR changes
#
# Parameters:
# id (required) - The ID of a project
# merge_request_id (required) - The ID of MR
#
# Example:
# GET /projects/:id/merge_request/:merge_request_id/changes
#
get
':id/merge_request/:merge_request_id/changes'
do
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
authorize!
:read_merge_request
,
merge_request
present
merge_request
,
with:
Entities
::
MergeRequestChanges
end
# Create MR
#
# Parameters:
...
...
@@ -148,146 +99,206 @@ module API
end
end
# Update MR
# Routing "merge_request/:merge_request_id/..." is DEPRECATED and WILL BE REMOVED in version 9.0
# Use "merge_requests/:merge_request_id/..." instead.
#
# Parameters:
# id (required) - The ID of a project
# merge_request_id (required) - ID of MR
# target_branch - The target branch
# assignee_id - Assignee user ID
# title - Title of MR
# state_event - Status of MR. (close|reopen|merge)
# description - Description of MR
# labels (optional) - Labels for a MR as a comma-separated list
# Example:
# PUT /projects/:id/merge_request/:merge_request_id
#
put
":id/merge_request/:merge_request_id"
do
attrs
=
attributes_for_keys
[
:target_branch
,
:assignee_id
,
:title
,
:state_event
,
:description
]
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
authorize!
:update_merge_request
,
merge_request
# Ensure source_branch is not specified
if
params
[
:source_branch
].
present?
render_api_error!
(
'Source branch cannot be changed'
,
400
)
end
# Validate label names in advance
if
(
errors
=
validate_label_params
(
params
)).
any?
render_api_error!
({
labels:
errors
},
400
)
end
merge_request
=
::
MergeRequests
::
UpdateService
.
new
(
user_project
,
current_user
,
attrs
).
execute
(
merge_request
)
if
merge_request
.
valid?
# Find or create labels and attach to issue
unless
params
[
:labels
].
nil?
merge_request
.
remove_labels
merge_request
.
add_labels_by_names
(
params
[
:labels
].
split
(
","
))
end
[
":id/merge_request/:merge_request_id"
,
":id/merge_requests/:merge_request_id"
].
each
do
|
path
|
# Show MR
#
# Parameters:
# id (required) - The ID of a project
# merge_request_id (required) - The ID of MR
#
# Example:
# GET /projects/:id/merge_requests/:merge_request_id
#
get
path
do
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
authorize!
:read_merge_request
,
merge_request
present
merge_request
,
with:
Entities
::
MergeRequest
else
handle_merge_request_errors!
merge_request
.
errors
end
end
# Merge MR
#
# Parameters:
# id (required) - The ID of a project
# merge_request_id (required) - ID of MR
# merge_commit_message (optional) - Custom merge commit message
# should_remove_source_branch (optional) - When true, the source branch will be deleted if possible
# merge_when_build_succeeds (optional) - When true, this MR will be merged when the build succeeds
# Example:
# PUT /projects/:id/merge_request/:merge_request_id/merge
#
put
":id/merge_request/:merge_request_id/merge"
do
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
# Merge request can not be merged
# because user dont have permissions to push into target branch
unauthorized!
unless
merge_request
.
can_be_merged_by?
(
current_user
)
not_allowed!
if
!
merge_request
.
open?
||
merge_request
.
work_in_progress?
merge_request
.
check_if_can_be_merged
render_api_error!
(
'Branch cannot be merged'
,
406
)
unless
merge_request
.
can_be_merged?
merge_params
=
{
commit_message:
params
[
:merge_commit_message
],
should_remove_source_branch:
params
[
:should_remove_source_branch
]
}
if
parse_boolean
(
params
[
:merge_when_build_succeeds
])
&&
merge_request
.
ci_commit
&&
merge_request
.
ci_commit
.
active?
::
MergeRequests
::
MergeWhenBuildSucceedsService
.
new
(
merge_request
.
target_project
,
current_user
,
merge_params
).
execute
(
merge_request
)
else
::
MergeRequests
::
MergeService
.
new
(
merge_request
.
target_project
,
current_user
,
merge_params
).
execute
(
merge_request
)
# Show MR commits
#
# Parameters:
# id (required) - The ID of a project
# merge_request_id (required) - The ID of MR
#
# Example:
# GET /projects/:id/merge_requests/:merge_request_id/commits
#
get
"
#{
path
}
/commits"
do
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
authorize!
:read_merge_request
,
merge_request
present
merge_request
.
commits
,
with:
Entities
::
RepoCommit
end
present
merge_request
,
with:
Entities
::
MergeRequest
end
# Show MR changes
#
# Parameters:
# id (required) - The ID of a project
# merge_request_id (required) - The ID of MR
#
# Example:
# GET /projects/:id/merge_requests/:merge_request_id/changes
#
get
"
#{
path
}
/changes"
do
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
authorize!
:read_merge_request
,
merge_request
present
merge_request
,
with:
Entities
::
MergeRequestChanges
end
# Cancel Merge if Merge When build succeeds is enabled
# Parameters:
# id (required) - The ID of a project
# merge_request_id (required) - ID of MR
#
post
":id/merge_request/:merge_request_id/cancel_merge_when_build_succeeds"
do
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
# Update MR
#
# Parameters:
# id (required) - The ID of a project
# merge_request_id (required) - ID of MR
# target_branch - The target branch
# assignee_id - Assignee user ID
# title - Title of MR
# state_event - Status of MR. (close|reopen|merge)
# description - Description of MR
# labels (optional) - Labels for a MR as a comma-separated list
# Example:
# PUT /projects/:id/merge_requests/:merge_request_id
#
put
path
do
attrs
=
attributes_for_keys
[
:target_branch
,
:assignee_id
,
:title
,
:state_event
,
:description
]
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
authorize!
:update_merge_request
,
merge_request
# Ensure source_branch is not specified
if
params
[
:source_branch
].
present?
render_api_error!
(
'Source branch cannot be changed'
,
400
)
end
unauthorized!
unless
merge_request
.
can_cancel_merge_when_build_succeeds?
(
current_user
)
# Validate label names in advance
if
(
errors
=
validate_label_params
(
params
)).
any?
render_api_error!
({
labels:
errors
},
400
)
end
::
MergeRequest
::
MergeWhenBuildSucceedsService
.
new
(
merge_request
.
target_project
,
current_user
).
cancel
(
merge_request
)
end
merge_request
=
::
MergeRequests
::
UpdateService
.
new
(
user_project
,
current_user
,
attrs
).
execute
(
merge_request
)
# Get a merge request's comments
#
# Parameters:
# id (required) - The ID of a project
# merge_request_id (required) - ID of MR
# Examples:
# GET /projects/:id/merge_request/:merge_request_id/comments
#
get
":id/merge_request/:merge_request_id/comments"
do
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
if
merge_request
.
valid?
# Find or create labels and attach to issue
unless
params
[
:labels
].
nil?
merge_request
.
remove_labels
merge_request
.
add_labels_by_names
(
params
[
:labels
].
split
(
","
))
end
authorize!
:read_merge_request
,
merge_request
present
merge_request
,
with:
Entities
::
MergeRequest
else
handle_merge_request_errors!
merge_request
.
errors
end
end
present
paginate
(
merge_request
.
notes
.
fresh
),
with:
Entities
::
MRNote
end
# Merge MR
#
# Parameters:
# id (required) - The ID of a project
# merge_request_id (required) - ID of MR
# merge_commit_message (optional) - Custom merge commit message
# should_remove_source_branch (optional) - When true, the source branch will be deleted if possible
# merge_when_build_succeeds (optional) - When true, this MR will be merged when the build succeeds
# Example:
# PUT /projects/:id/merge_requests/:merge_request_id/merge
#
put
"
#{
path
}
/merge"
do
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
# Merge request can not be merged
# because user dont have permissions to push into target branch
unauthorized!
unless
merge_request
.
can_be_merged_by?
(
current_user
)
not_allowed!
if
!
merge_request
.
open?
||
merge_request
.
work_in_progress?
merge_request
.
check_if_can_be_merged
render_api_error!
(
'Branch cannot be merged'
,
406
)
unless
merge_request
.
can_be_merged?
merge_params
=
{
commit_message:
params
[
:merge_commit_message
],
should_remove_source_branch:
params
[
:should_remove_source_branch
]
}
if
parse_boolean
(
params
[
:merge_when_build_succeeds
])
&&
merge_request
.
ci_commit
&&
merge_request
.
ci_commit
.
active?
::
MergeRequests
::
MergeWhenBuildSucceedsService
.
new
(
merge_request
.
target_project
,
current_user
,
merge_params
).
execute
(
merge_request
)
else
::
MergeRequests
::
MergeService
.
new
(
merge_request
.
target_project
,
current_user
,
merge_params
).
execute
(
merge_request
)
end
# Post comment to merge request
#
# Parameters:
# id (required) - The ID of a project
# merge_request_id (required) - ID of MR
# note (required) - Text of comment
# Examples:
# POST /projects/:id/merge_request/:merge_request_id/comments
#
post
":id/merge_request/:merge_request_id/comments"
do
required_attributes!
[
:note
]
present
merge_request
,
with:
Entities
::
MergeRequest
end
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
# Cancel Merge if Merge When build succeeds is enabled
# Parameters:
# id (required) - The ID of a project
# merge_request_id (required) - ID of MR
#
post
"
#{
path
}
/cancel_merge_when_build_succeeds"
do
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
authorize!
:create_note
,
merge_request
unauthorized!
unless
merge_request
.
can_cancel_merge_when_build_succeeds?
(
current_user
)
opts
=
{
note:
params
[
:note
],
noteable_type:
'MergeRequest'
,
noteable_id:
merge_request
.
id
}
::
MergeRequest
::
MergeWhenBuildSucceedsService
.
new
(
merge_request
.
target_project
,
current_user
).
cancel
(
merge_request
)
end
note
=
::
Notes
::
CreateService
.
new
(
user_project
,
current_user
,
opts
).
execute
# Duplicate. DEPRECATED and WILL BE REMOVED in 9.0.
# Use GET "/projects/:id/merge_requests/:merge_request_id/notes" instead
#
# Get a merge request's comments
#
# Parameters:
# id (required) - The ID of a project
# merge_request_id (required) - ID of MR
# Examples:
# GET /projects/:id/merge_requests/:merge_request_id/comments
#
get
"
#{
path
}
/comments"
do
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
authorize!
:read_merge_request
,
merge_request
present
paginate
(
merge_request
.
notes
.
fresh
),
with:
Entities
::
MRNote
end
if
note
.
save
present
note
,
with:
Entities
::
MRNote
else
render_api_error!
(
"Failed to save note
#{
note
.
errors
.
messages
}
"
,
400
)
# Duplicate. DEPRECATED and WILL BE REMOVED in 9.0.
# Use POST "/projects/:id/merge_requests/:merge_request_id/notes" instead
#
# Post comment to merge request
#
# Parameters:
# id (required) - The ID of a project
# merge_request_id (required) - ID of MR
# note (required) - Text of comment
# Examples:
# POST /projects/:id/merge_requests/:merge_request_id/comments
#
post
"
#{
path
}
/comments"
do
required_attributes!
[
:note
]
merge_request
=
user_project
.
merge_requests
.
find
(
params
[
:merge_request_id
])
authorize!
:create_note
,
merge_request
opts
=
{
note:
params
[
:note
],
noteable_type:
'MergeRequest'
,
noteable_id:
merge_request
.
id
}
note
=
::
Notes
::
CreateService
.
new
(
user_project
,
current_user
,
opts
).
execute
if
note
.
save
present
note
,
with:
Entities
::
MRNote
else
render_api_error!
(
"Failed to save note
#{
note
.
errors
.
messages
}
"
,
400
)
end
end
end
end
...
...
lib/gitlab/current_settings.rb
View file @
69c4e0a1
...
...
@@ -4,11 +4,14 @@ module Gitlab
key
=
:current_application_settings
RequestStore
.
store
[
key
]
||=
begin
settings
=
nil
if
connect_to_db?
ApplicationSetting
.
current
||
ApplicationSetting
.
create_from_defaults
else
fake_application_settings
settings
=
ApplicationSetting
.
current
settings
||=
ApplicationSetting
.
create_from_defaults
unless
ActiveRecord
::
Migrator
.
needs_migration?
end
settings
||
fake_application_settings
end
end
...
...
@@ -18,28 +21,32 @@ module Gitlab
default_branch_protection:
Settings
.
gitlab
[
'default_branch_protection'
],
signup_enabled:
Settings
.
gitlab
[
'signup_enabled'
],
signin_enabled:
Settings
.
gitlab
[
'signin_enabled'
],
twitter_sharing_enabled:
Settings
.
gitlab
[
'twitter_sharing_enabled'
],
gravatar_enabled:
Settings
.
gravatar
[
'enabled'
],
sign_in_text:
Settings
.
extra
[
'sign_in_text'
],
restricted_visibility_levels:
Settings
.
gitlab
[
'restricted_visibility_levels'
],
max_attachment_size:
Settings
.
gitlab
[
'max_attachment_size'
],
session_expire_delay:
Settings
.
gitlab
[
'session_expire_delay'
],
import_sources:
Settings
.
gitlab
[
'import_sources'
],
default_project_visibility:
Settings
.
gitlab
.
default_projects_features
[
'visibility_level'
],
default_snippet_visibility:
Settings
.
gitlab
.
default_projects_features
[
'visibility_level'
],
restricted_signup_domains:
Settings
.
gitlab
[
'restricted_signup_domains'
],
import_sources:
[
'github'
,
'bitbucket'
,
'gitlab'
,
'gitorious'
,
'google_code'
,
'fogbugz'
,
'git'
],
shared_runners_enabled:
Settings
.
gitlab_ci
[
'shared_runners_enabled'
],
max_artifacts_size:
Settings
.
artifacts
[
'max_size'
],
require_two_factor_authentication:
false
,
two_factor_grace_period:
48
)
end
private
def
connect_to_db?
use_db
=
if
ENV
[
'USE_DB'
]
==
"false"
false
else
true
end
use_db
&&
ActiveRecord
::
Base
.
connection
.
active?
&&
ActiveRecord
::
Base
.
connection
.
table_exists?
(
'application_settings'
)
# When the DBMS is not available, an exception (e.g. PG::ConnectionBad) is raised
active_db_connection
=
ActiveRecord
::
Base
.
connection
.
active?
rescue
false
ENV
[
'USE_DB'
]
!=
'false'
&&
active_db_connection
&&
ActiveRecord
::
Base
.
connection
.
table_exists?
(
'application_settings'
)
rescue
ActiveRecord
::
NoDatabaseError
false
...
...
spec/requests/api/merge_requests_spec.rb
View file @
69c4e0a1
...
...
@@ -109,9 +109,9 @@ describe API::API, api: true do
end
end
describe
"GET /projects/:id/merge_request/:merge_request_id"
do
describe
"GET /projects/:id/merge_request
s
/:merge_request_id"
do
it
"should return merge_request"
do
get
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
"
,
user
)
get
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
"
,
user
)
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
json_response
[
'title'
]).
to
eq
(
merge_request
.
title
)
expect
(
json_response
[
'iid'
]).
to
eq
(
merge_request
.
iid
)
...
...
@@ -126,14 +126,14 @@ describe API::API, api: true do
end
it
"should return a 404 error if merge_request_id not found"
do
get
api
(
"/projects/
#{
project
.
id
}
/merge_request/999"
,
user
)
get
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/999"
,
user
)
expect
(
response
.
status
).
to
eq
(
404
)
end
end
describe
'GET /projects/:id/merge_request/:merge_request_id/commits'
do
describe
'GET /projects/:id/merge_request
s
/:merge_request_id/commits'
do
context
'valid merge request'
do
before
{
get
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
/commits"
,
user
)
}
before
{
get
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
/commits"
,
user
)
}
let
(
:commit
)
{
merge_request
.
commits
.
first
}
it
{
expect
(
response
.
status
).
to
eq
200
}
...
...
@@ -143,20 +143,20 @@ describe API::API, api: true do
end
it
'returns a 404 when merge_request_id not found'
do
get
api
(
"/projects/
#{
project
.
id
}
/merge_request/999/commits"
,
user
)
get
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/999/commits"
,
user
)
expect
(
response
.
status
).
to
eq
(
404
)
end
end
describe
'GET /projects/:id/merge_request/:merge_request_id/changes'
do
describe
'GET /projects/:id/merge_request
s
/:merge_request_id/changes'
do
it
'should return the change information of the merge_request'
do
get
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
/changes"
,
user
)
get
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
/changes"
,
user
)
expect
(
response
.
status
).
to
eq
200
expect
(
json_response
[
'changes'
].
size
).
to
eq
(
merge_request
.
diffs
.
size
)
end
it
'returns a 404 when merge_request_id not found'
do
get
api
(
"/projects/
#{
project
.
id
}
/merge_request/999/changes"
,
user
)
get
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/999/changes"
,
user
)
expect
(
response
.
status
).
to
eq
(
404
)
end
end
...
...
@@ -311,19 +311,19 @@ describe API::API, api: true do
end
end
describe
"PUT /projects/:id/merge_request/:merge_request_id to close MR"
do
describe
"PUT /projects/:id/merge_request
s
/:merge_request_id to close MR"
do
it
"should return merge_request"
do
put
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
"
,
user
),
state_event:
"close"
put
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
"
,
user
),
state_event:
"close"
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
json_response
[
'state'
]).
to
eq
(
'closed'
)
end
end
describe
"PUT /projects/:id/merge_request/:merge_request_id/merge"
do
describe
"PUT /projects/:id/merge_request
s
/:merge_request_id/merge"
do
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
)
put
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
/merge"
,
user
)
expect
(
response
.
status
).
to
eq
(
200
)
end
...
...
@@ -332,7 +332,7 @@ describe API::API, api: true do
allow_any_instance_of
(
MergeRequest
).
to
receive
(
:can_be_merged?
).
and_return
(
false
)
put
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
/merge"
,
user
)
put
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
/merge"
,
user
)
expect
(
response
.
status
).
to
eq
(
406
)
expect
(
json_response
[
'message'
]).
to
eq
(
'Branch cannot be merged'
)
...
...
@@ -340,14 +340,14 @@ describe API::API, api: true do
it
"should return 405 if merge_request is not open"
do
merge_request
.
close
put
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
/merge"
,
user
)
put
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
/merge"
,
user
)
expect
(
response
.
status
).
to
eq
(
405
)
expect
(
json_response
[
'message'
]).
to
eq
(
'405 Method Not Allowed'
)
end
it
"should return 405 if merge_request is a work in progress"
do
merge_request
.
update_attribute
(
:title
,
"WIP:
#{
merge_request
.
title
}
"
)
put
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
/merge"
,
user
)
put
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
/merge"
,
user
)
expect
(
response
.
status
).
to
eq
(
405
)
expect
(
json_response
[
'message'
]).
to
eq
(
'405 Method Not Allowed'
)
end
...
...
@@ -355,7 +355,7 @@ describe API::API, api: true do
it
"should return 401 if user has no permissions to merge"
do
user2
=
create
(
:user
)
project
.
team
<<
[
user2
,
:reporter
]
put
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
/merge"
,
user2
)
put
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
/merge"
,
user2
)
expect
(
response
.
status
).
to
eq
(
401
)
expect
(
json_response
[
'message'
]).
to
eq
(
'401 Unauthorized'
)
end
...
...
@@ -364,7 +364,7 @@ describe API::API, api: true do
allow_any_instance_of
(
MergeRequest
).
to
receive
(
:ci_commit
).
and_return
(
ci_commit
)
allow
(
ci_commit
).
to
receive
(
:active?
).
and_return
(
true
)
put
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
/merge"
,
user
),
merge_when_build_succeeds:
true
put
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
/merge"
,
user
),
merge_when_build_succeeds:
true
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
json_response
[
'title'
]).
to
eq
(
'Test'
)
...
...
@@ -372,33 +372,33 @@ describe API::API, api: true do
end
end
describe
"PUT /projects/:id/merge_request/:merge_request_id"
do
describe
"PUT /projects/:id/merge_request
s
/:merge_request_id"
do
it
"should return merge_request"
do
put
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
"
,
user
),
title:
"New title"
put
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
"
,
user
),
title:
"New title"
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
json_response
[
'title'
]).
to
eq
(
'New title'
)
end
it
"should return merge_request"
do
put
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
"
,
user
),
description:
"New description"
put
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
"
,
user
),
description:
"New description"
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
json_response
[
'description'
]).
to
eq
(
'New description'
)
end
it
"should return 400 when source_branch is specified"
do
put
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
"
,
user
),
put
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
"
,
user
),
source_branch:
"master"
,
target_branch:
"master"
expect
(
response
.
status
).
to
eq
(
400
)
end
it
"should return merge_request with renamed target_branch"
do
put
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
"
,
user
),
target_branch:
"wiki"
put
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
"
,
user
),
target_branch:
"wiki"
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
json_response
[
'target_branch'
]).
to
eq
(
'wiki'
)
end
it
'should return 400 on invalid label names'
do
put
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
"
,
put
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
"
,
user
),
title:
'new issue'
,
labels:
'label, ?'
...
...
@@ -407,11 +407,11 @@ describe API::API, api: true do
end
end
describe
"POST /projects/:id/merge_request/:merge_request_id/comments"
do
describe
"POST /projects/:id/merge_request
s
/:merge_request_id/comments"
do
it
"should return comment"
do
original_count
=
merge_request
.
notes
.
size
post
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
/comments"
,
user
),
note:
"My comment"
post
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
/comments"
,
user
),
note:
"My comment"
expect
(
response
.
status
).
to
eq
(
201
)
expect
(
json_response
[
'note'
]).
to
eq
(
'My comment'
)
expect
(
json_response
[
'author'
][
'name'
]).
to
eq
(
user
.
name
)
...
...
@@ -420,20 +420,20 @@ describe API::API, api: true do
end
it
"should return 400 if note is missing"
do
post
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
/comments"
,
user
)
post
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
/comments"
,
user
)
expect
(
response
.
status
).
to
eq
(
400
)
end
it
"should return 404 if note is attached to non existent merge request"
do
post
api
(
"/projects/
#{
project
.
id
}
/merge_request/404/comments"
,
user
),
post
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/404/comments"
,
user
),
note:
'My comment'
expect
(
response
.
status
).
to
eq
(
404
)
end
end
describe
"GET :id/merge_request/:merge_request_id/comments"
do
describe
"GET :id/merge_request
s
/:merge_request_id/comments"
do
it
"should return merge_request comments ordered by created_at"
do
get
api
(
"/projects/
#{
project
.
id
}
/merge_request/
#{
merge_request
.
id
}
/comments"
,
user
)
get
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/
#{
merge_request
.
id
}
/comments"
,
user
)
expect
(
response
.
status
).
to
eq
(
200
)
expect
(
json_response
).
to
be_an
Array
expect
(
json_response
.
length
).
to
eq
(
2
)
...
...
@@ -443,7 +443,7 @@ describe API::API, api: true do
end
it
"should return a 404 error if merge_request_id not found"
do
get
api
(
"/projects/
#{
project
.
id
}
/merge_request/999/comments"
,
user
)
get
api
(
"/projects/
#{
project
.
id
}
/merge_request
s
/999/comments"
,
user
)
expect
(
response
.
status
).
to
eq
(
404
)
end
end
...
...
spec/routing/project_routing_spec.rb
View file @
69c4e0a1
...
...
@@ -496,11 +496,11 @@ end
describe
Projects
::
ForksController
,
'routing'
do
it
'to #new'
do
expect
(
get
(
'/gitlab/gitlabhq/fork/new'
)).
to
route_to
(
'projects/forks#new'
,
namespace_id:
'gitlab'
,
project_id:
'gitlabhq'
)
expect
(
get
(
'/gitlab/gitlabhq/fork
s
/new'
)).
to
route_to
(
'projects/forks#new'
,
namespace_id:
'gitlab'
,
project_id:
'gitlabhq'
)
end
it
'to #create'
do
expect
(
post
(
'/gitlab/gitlabhq/fork'
)).
to
route_to
(
'projects/forks#create'
,
namespace_id:
'gitlab'
,
project_id:
'gitlabhq'
)
expect
(
post
(
'/gitlab/gitlabhq/fork
s
'
)).
to
route_to
(
'projects/forks#create'
,
namespace_id:
'gitlab'
,
project_id:
'gitlabhq'
)
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