Commit 93bcc9ca authored by Valery Sizov's avatar Valery Sizov

Merge remote-tracking branch 'origin/master' into ce_upsteram

parents 412f8f47 4f574388
...@@ -6,6 +6,8 @@ v 8.1.0 ...@@ -6,6 +6,8 @@ v 8.1.0
v 8.0.1 v 8.0.1
v 8.1.0 (unreleased) v 8.1.0 (unreleased)
v 8.2.0 (unreleased) v 8.2.0 (unreleased)
- Force update refs/merge-requests/X/head upon a push to the source branch of a merge request (Stan Hu)
- Improved performance of finding users by one of their Email addresses
- Improved performance of replacing references in comments - Improved performance of replacing references in comments
- Show last project commit to default branch on project home page - Show last project commit to default branch on project home page
- Highlight comment based on anchor in URL - Highlight comment based on anchor in URL
...@@ -13,12 +15,43 @@ v 8.2.0 (unreleased) ...@@ -13,12 +15,43 @@ v 8.2.0 (unreleased)
- Improved performance of sorting milestone issues - Improved performance of sorting milestone issues
- Allow users to select the Files view as default project view (Cristian Bica) - Allow users to select the Files view as default project view (Cristian Bica)
- Show "Empty Repository Page" for repository without branches (Artem V. Navrotskiy) - Show "Empty Repository Page" for repository without branches (Artem V. Navrotskiy)
- Fix: Inability to reply to code comments in the MR view, if the MR comes from a fork
- Use git follow flag for commits page when retrieve history for file or directory
- Show merge request CI status on merge requests index page
- Extend yml syntax for only and except to support specifying repository path
- 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.
- [API] Add ability to fetch the commit ID of the last commit that actually touched a file
- Add "New file" link to dropdown on project page
- Include commit logs in project search
- Add "added", "modified" and "removed" properties to commit object in webhook
- Rename "Back to" links to "Go to" because its not always a case it point to place user come from
- Allow groups to appear in the search results if the group owner allows it
v 8.1.3
- Spread out runner contacted_at updates
- New design for user profile page
- Add Facebook authentication
v 8.1.1
- Fix cloning Wiki repositories via HTTP (Stan Hu)
- Add migration to remove satellites directory
- Fix specific runners visibility
- Fix 500 when editing CI service
- Require CI jobs to be named
- Fix CSS for runner status
- Fix CI badge
- Allow developer to manage builds
v 8.1.0 v 8.1.0
- Ensure MySQL CI limits DB migrations occur after the fields have been created (Stan Hu) - Ensure MySQL CI limits DB migrations occur after the fields have been created (Stan Hu)
- Fix duplicate repositories in GitHub import page (Stan Hu) - Fix duplicate repositories in GitHub import page (Stan Hu)
- Redirect to a default path if HTTP_REFERER is not set (Stan Hu) - Redirect to a default path if HTTP_REFERER is not set (Stan Hu)
- Fix CSS for runner status - Adds ability to create directories using the web editor (Ben Ford)
- Cleanup stuck CI builds
v 8.1.0 (unreleased)
- Send an email to admin email when a user is reported for spam (Jonathan Rochkind) - Send an email to admin email when a user is reported for spam (Jonathan Rochkind)
- Show notifications button when user is member of group rather than project (Grzegorz Bizon) - Show notifications button when user is member of group rather than project (Grzegorz Bizon)
- Fix bug preventing mentioned issued from being closed when MR is merged using fast-forward merge. - Fix bug preventing mentioned issued from being closed when MR is merged using fast-forward merge.
...@@ -26,12 +59,11 @@ v 8.1.0 ...@@ -26,12 +59,11 @@ v 8.1.0
- Don't show "Add README" link in an empty repository if user doesn't have access to push (Stan Hu) - Don't show "Add README" link in an empty repository if user doesn't have access to push (Stan Hu)
- Fix error preventing displaying of commit data for a directory with a leading dot (Stan Hu) - Fix error preventing displaying of commit data for a directory with a leading dot (Stan Hu)
- Speed up load times of issue detail pages by roughly 1.5x - Speed up load times of issue detail pages by roughly 1.5x
- Require CI jobs to be named - Fix CI rendering regressions
- If a merge request is to close an issue, show this on the issue page (Zeger-Jan van de Weg) - If a merge request is to close an issue, show this on the issue page (Zeger-Jan van de Weg)
- Add a system note and update relevant merge requests when a branch is deleted or re-added (Stan Hu) - Add a system note and update relevant merge requests when a branch is deleted or re-added (Stan Hu)
- Make diff file view easier to use on mobile screens (Stan Hu) - Make diff file view easier to use on mobile screens (Stan Hu)
- Improved performance of finding users by username or Email address - Improved performance of finding users by username or Email address
- Fix 500 when editing CI service
- Fix bug where merge request comments created by API would not trigger notifications (Stan Hu) - Fix bug where merge request comments created by API would not trigger notifications (Stan Hu)
- Add support for creating directories from Files page (Stan Hu) - Add support for creating directories from Files page (Stan Hu)
- Allow removing of project without confirmation when JavaScript is disabled (Stan Hu) - Allow removing of project without confirmation when JavaScript is disabled (Stan Hu)
......
...@@ -83,6 +83,7 @@ If you can, please submit a merge request with the fix or improvements including ...@@ -83,6 +83,7 @@ If you can, please submit a merge request with the fix or improvements including
1. Be prepared to answer questions and incorporate feedback even if requests for this arrive weeks or months after your MR submission 1. Be prepared to answer questions and incorporate feedback even if requests for this arrive weeks or months after your MR submission
1. If your MR touches code that executes shell commands, make sure it adheres to the [shell command guidelines]( doc/development/shell_commands.md). 1. If your MR touches code that executes shell commands, make sure it adheres to the [shell command guidelines]( doc/development/shell_commands.md).
1. Also have a look at the [shell command guidelines](doc/development/shell_commands.md) if your code reads or opens files, or handles paths to files on disk. 1. Also have a look at the [shell command guidelines](doc/development/shell_commands.md) if your code reads or opens files, or handles paths to files on disk.
1. If your code creates new files on disk please read the [shared files guidelines](doc/development/shared_files.md).
The **official merge window** is in the beginning of the month from the 1st to the 7th day of the month. The best time to submit a MR and get feedback fast. The **official merge window** is in the beginning of the month from the 1st to the 7th day of the month. The best time to submit a MR and get feedback fast.
Before this time the GitLab B.V. team is still dealing with work that is created by the monthly release such as regressions requiring patch releases. Before this time the GitLab B.V. team is still dealing with work that is created by the monthly release such as regressions requiring patch releases.
......
...@@ -19,6 +19,7 @@ gem 'devise-async', '~> 0.9.0' ...@@ -19,6 +19,7 @@ gem 'devise-async', '~> 0.9.0'
gem 'doorkeeper', '~> 2.1.3' gem 'doorkeeper', '~> 2.1.3'
gem 'omniauth', '~> 1.2.2' gem 'omniauth', '~> 1.2.2'
gem 'omniauth-bitbucket', '~> 0.0.2' gem 'omniauth-bitbucket', '~> 0.0.2'
gem 'omniauth-facebook', '~> 3.0.0'
gem 'omniauth-github', '~> 1.1.1' gem 'omniauth-github', '~> 1.1.1'
gem 'omniauth-gitlab', '~> 1.0.0' gem 'omniauth-gitlab', '~> 1.0.0'
gem 'omniauth-google-oauth2', '~> 0.2.0' gem 'omniauth-google-oauth2', '~> 0.2.0'
...@@ -65,7 +66,7 @@ gem 'rack-cors', '~> 0.4.0', require: 'rack/cors' ...@@ -65,7 +66,7 @@ gem 'rack-cors', '~> 0.4.0', require: 'rack/cors'
# Format dates and times # Format dates and times
# based on human-friendly examples # based on human-friendly examples
gem "stamp", '~> 0.5.0' gem "stamp", '~> 0.6.0'
# Enumeration fields # Enumeration fields
gem 'enumerize', '~> 0.7.0' gem 'enumerize', '~> 0.7.0'
...@@ -199,11 +200,11 @@ gem 'bootstrap-sass', '~> 3.0' ...@@ -199,11 +200,11 @@ gem 'bootstrap-sass', '~> 3.0'
gem 'font-awesome-rails', '~> 4.2' gem 'font-awesome-rails', '~> 4.2'
gem 'gitlab_emoji', '~> 0.1' gem 'gitlab_emoji', '~> 0.1'
gem 'gon', '~> 5.0.0' gem 'gon', '~> 5.0.0'
gem 'jquery-atwho-rails', '~> 1.0.0' gem 'jquery-atwho-rails', '~> 1.3.2'
gem 'jquery-rails', '~> 3.1.3' gem 'jquery-rails', '~> 3.1.3'
gem 'jquery-scrollto-rails', '~> 1.4.3' gem 'jquery-scrollto-rails', '~> 1.4.3'
gem 'jquery-ui-rails', '~> 4.2.1' gem 'jquery-ui-rails', '~> 4.2.1'
gem 'nprogress-rails', '~> 0.1.2.3' gem 'nprogress-rails', '~> 0.1.6.7'
gem 'raphael-rails', '~> 2.1.2' gem 'raphael-rails', '~> 2.1.2'
gem 'request_store', '~> 1.2.0' gem 'request_store', '~> 1.2.0'
gem 'select2-rails', '~> 3.5.9' gem 'select2-rails', '~> 3.5.9'
......
...@@ -357,7 +357,7 @@ GEM ...@@ -357,7 +357,7 @@ GEM
ice_nine (0.11.1) ice_nine (0.11.1)
inflecto (0.0.2) inflecto (0.0.2)
ipaddress (0.8.0) ipaddress (0.8.0)
jquery-atwho-rails (1.0.1) jquery-atwho-rails (1.3.2)
jquery-rails (3.1.3) jquery-rails (3.1.3)
railties (>= 3.0, < 5.0) railties (>= 3.0, < 5.0)
thor (>= 0.14, < 2.0) thor (>= 0.14, < 2.0)
...@@ -409,7 +409,7 @@ GEM ...@@ -409,7 +409,7 @@ GEM
newrelic_rpm (3.9.4.245) newrelic_rpm (3.9.4.245)
nokogiri (1.6.6.2) nokogiri (1.6.6.2)
mini_portile (~> 0.6.0) mini_portile (~> 0.6.0)
nprogress-rails (0.1.2.3) nprogress-rails (0.1.6.7)
oauth (0.4.7) oauth (0.4.7)
oauth2 (1.0.0) oauth2 (1.0.0)
faraday (>= 0.8, < 0.10) faraday (>= 0.8, < 0.10)
...@@ -426,6 +426,8 @@ GEM ...@@ -426,6 +426,8 @@ GEM
multi_json (~> 1.7) multi_json (~> 1.7)
omniauth (~> 1.1) omniauth (~> 1.1)
omniauth-oauth (~> 1.0) omniauth-oauth (~> 1.0)
omniauth-facebook (3.0.0)
omniauth-oauth2 (~> 1.2)
omniauth-github (1.1.2) omniauth-github (1.1.2)
omniauth (~> 1.0) omniauth (~> 1.0)
omniauth-oauth2 (~> 1.1) omniauth-oauth2 (~> 1.1)
...@@ -692,7 +694,7 @@ GEM ...@@ -692,7 +694,7 @@ GEM
actionpack (>= 3.0) actionpack (>= 3.0)
activesupport (>= 3.0) activesupport (>= 3.0)
sprockets (>= 2.8, < 4.0) sprockets (>= 2.8, < 4.0)
stamp (0.5.0) stamp (0.6.0)
state_machine (1.2.0) state_machine (1.2.0)
stringex (2.5.2) stringex (2.5.2)
systemu (2.6.5) systemu (2.6.5)
...@@ -845,7 +847,7 @@ DEPENDENCIES ...@@ -845,7 +847,7 @@ DEPENDENCIES
hipchat (~> 1.5.0) hipchat (~> 1.5.0)
html-pipeline (~> 1.11.0) html-pipeline (~> 1.11.0)
httparty (~> 0.13.3) httparty (~> 0.13.3)
jquery-atwho-rails (~> 1.0.0) jquery-atwho-rails (~> 1.3.2)
jquery-rails (~> 3.1.3) jquery-rails (~> 3.1.3)
jquery-scrollto-rails (~> 1.4.3) jquery-scrollto-rails (~> 1.4.3)
jquery-turbolinks (~> 2.0.1) jquery-turbolinks (~> 2.0.1)
...@@ -860,11 +862,12 @@ DEPENDENCIES ...@@ -860,11 +862,12 @@ DEPENDENCIES
net-ldap net-ldap
newrelic-grape newrelic-grape
newrelic_rpm (~> 3.9.4.245) newrelic_rpm (~> 3.9.4.245)
nprogress-rails (~> 0.1.2.3) nprogress-rails (~> 0.1.6.7)
oauth2 (~> 1.0.0) oauth2 (~> 1.0.0)
octokit (~> 3.7.0) octokit (~> 3.7.0)
omniauth (~> 1.2.2) omniauth (~> 1.2.2)
omniauth-bitbucket (~> 0.0.2) omniauth-bitbucket (~> 0.0.2)
omniauth-facebook (~> 3.0.0)
omniauth-github (~> 1.1.1) omniauth-github (~> 1.1.1)
omniauth-gitlab (~> 1.0.0) omniauth-gitlab (~> 1.0.0)
omniauth-google-oauth2 (~> 0.2.0) omniauth-google-oauth2 (~> 0.2.0)
...@@ -915,7 +918,7 @@ DEPENDENCIES ...@@ -915,7 +918,7 @@ DEPENDENCIES
spring-commands-spinach (~> 1.0.0) spring-commands-spinach (~> 1.0.0)
spring-commands-teaspoon (~> 0.0.2) spring-commands-teaspoon (~> 0.0.2)
sprockets (~> 2.12.3) sprockets (~> 2.12.3)
stamp (~> 0.5.0) stamp (~> 0.6.0)
state_machine (~> 1.2.0) state_machine (~> 1.2.0)
task_list (~> 1.0.2) task_list (~> 1.0.2)
teaspoon (~> 1.0.0) teaspoon (~> 1.0.0)
......
...@@ -115,3 +115,10 @@ We can only accept a merge request if all the tests are green. I've just ...@@ -115,3 +115,10 @@ We can only accept a merge request if all the tests are green. I've just
restarted the build. When the tests are still not passing after this restart and restarted the build. When the tests are still not passing after this restart and
you're sure that is does not have anything to do with your code changes, please you're sure that is does not have anything to do with your code changes, please
rebase with master to see if that solves the issue. rebase with master to see if that solves the issue.
### Closing down the issue tracker on GitHub
We are currently in the process of closing down the issue tracker on GitHub, to
prevent duplication with the [GitLab.com issue tracker][https://gitlab.com/gitlab-org/gitlab-ce/issues].
Since this is an older issue I'll be closing this for now. If you think this is
still an issue I encourage you to open it on the [GitLab.com issue tracker][https://gitlab.com/gitlab-org/gitlab-ce/issues].
No preview for this file type
File mode changed from 100755 to 100644
No preview for this file type
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
...@@ -11,10 +11,10 @@ class @EditBlob ...@@ -11,10 +11,10 @@ class @EditBlob
if ace_mode if ace_mode
editor.getSession().setMode "ace/mode/" + ace_mode editor.getSession().setMode "ace/mode/" + ace_mode
$(".js-commit-button").click -> # Before a form submission, move the content from the Ace editor into the
$("#file-content").val editor.getValue() # submitted textarea
$(".file-editor form").submit() $('form').submit ->
return false $("#file-content").val(editor.getValue())
editModePanes = $(".js-edit-mode-pane") editModePanes = $(".js-edit-mode-pane")
editModeLinks = $(".js-edit-mode a") editModeLinks = $(".js-edit-mode a")
......
...@@ -11,10 +11,10 @@ class @NewBlob ...@@ -11,10 +11,10 @@ class @NewBlob
if ace_mode if ace_mode
editor.getSession().setMode "ace/mode/" + ace_mode editor.getSession().setMode "ace/mode/" + ace_mode
$(".js-commit-button").click -> # Before a form submission, move the content from the Ace editor into the
$("#file-content").val editor.getValue() # submitted textarea
$(".file-editor form").submit() $('form').submit ->
return false $("#file-content").val(editor.getValue())
editor: -> editor: ->
return @editor return @editor
...@@ -25,7 +25,7 @@ class @Calendar ...@@ -25,7 +25,7 @@ class @Calendar
30 30
] ]
legendCellPadding: 3 legendCellPadding: 3
cellSize: $('.user-calendar').width() / 80 cellSize: $('.user-calendar').width() / 73
onClick: (date, count) -> onClick: (date, count) ->
formated_date = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate() formated_date = date.getFullYear() + "-" + (date.getMonth()+1) + "-" + date.getDate()
$.ajax $.ajax
......
...@@ -31,7 +31,7 @@ class CiBuild ...@@ -31,7 +31,7 @@ class CiBuild
$('#build-trace code').html build.trace_html $('#build-trace code').html build.trace_html
$('#build-trace code').append '<i class="fa fa-refresh fa-spin"/>' $('#build-trace code').append '<i class="fa fa-refresh fa-spin"/>'
@checkAutoscroll() @checkAutoscroll()
else else if build.status != build_status
Turbolinks.visit build_url Turbolinks.visit build_url
, 4000 , 4000
......
#= require clipboard
$ ->
clipboard = new Clipboard '.js-clipboard-trigger',
text: (trigger) ->
$target = $(trigger.nextElementSibling || trigger.previousElementSibling)
$target.data('clipboard-text') || $target.text().trim()
clipboard.on 'success', (e) ->
$(e.trigger).
tooltip(trigger: 'manual', placement: 'auto bottom', title: 'Copied!').
tooltip('show')
# Clear the selection and blur the trigger so it loses its border
e.clearSelection()
$(e.trigger).blur()
# Manually hide the tooltip after 1 second
setTimeout(->
$(e.trigger).tooltip('hide')
, 1000)
...@@ -100,7 +100,7 @@ ...@@ -100,7 +100,7 @@
} }
.cover-desc { .cover-desc {
padding: 0 $gl-padding; padding: 0 $gl-padding 3px;
color: $gl-text-color; color: $gl-text-color;
} }
......
...@@ -180,3 +180,7 @@ ...@@ -180,3 +180,7 @@
} }
} }
} }
.btn-clipboard {
border: none;
}
...@@ -396,6 +396,36 @@ table { ...@@ -396,6 +396,36 @@ table {
} }
} }
.center-middle-menu {
@include nav-menu;
padding: 0;
text-align: center;
margin: -$gl-padding;
margin-top: 0;
margin-bottom: 0;
height: 58px;
border-bottom: 1px solid $border-color;
li {
&:after {
content: "|";
color: $border-gray-light;
}
&:last-child {
&:after {
content: none;
}
}
> a {
display: inline-block;
text-transform: uppercase;
font-size: 13px;
}
}
}
.dropzone .dz-preview .dz-progress { .dropzone .dz-preview .dz-progress {
border-color: $border-color !important; border-color: $border-color !important;
} }
......
...@@ -137,6 +137,7 @@ ...@@ -137,6 +137,7 @@
&:hover, &:active, &:focus { &:hover, &:active, &:focus {
text-decoration: none; text-decoration: none;
outline: none;
} }
} }
......
...@@ -33,6 +33,8 @@ ...@@ -33,6 +33,8 @@
} }
li.commit { li.commit {
list-style: none;
.commit-row-title { .commit-row-title {
font-size: $list-font-size; font-size: $list-font-size;
line-height: 20px; line-height: 20px;
......
...@@ -50,7 +50,7 @@ ...@@ -50,7 +50,7 @@
.editor-file-name { .editor-file-name {
.new-file-name { .new-file-name {
display: inline-block; display: inline-block;
width: 200px; width: 450px;
} }
.form-control { .form-control {
......
...@@ -88,3 +88,16 @@ ...@@ -88,3 +88,16 @@
padding: 13px 0; padding: 13px 0;
} }
} }
.cross-project-reference {
text-align: center;
width: 100%;
.slead {
padding: 5px;
}
span, button {
background-color: $background-color;
}
}
...@@ -205,6 +205,15 @@ ...@@ -205,6 +205,15 @@
#modal_merge_info .modal-dialog { #modal_merge_info .modal-dialog {
width: 600px; width: 600px;
.btn-clipboard {
@extend .pull-right;
margin-right: 18px;
margin-top: 5px;
position: absolute;
right: 0;
}
} }
.mr-source-target { .mr-source-target {
......
...@@ -53,3 +53,25 @@ ...@@ -53,3 +53,25 @@
float: right; float: right;
font-size: 12px; font-size: 12px;
} }
.profile-link-holder {
display: inline;
&:after {
content: "\00B7";
padding: 0px 6px;
font-weight: bold;
}
&:last-child {
&:after {
content: "";
padding: 0;
}
}
a {
color: $blue-dark;
text-decoration: none;
}
}
...@@ -59,13 +59,8 @@ class ApplicationController < ActionController::Base ...@@ -59,13 +59,8 @@ class ApplicationController < ActionController::Base
end end
def authenticate_user!(*args) def authenticate_user!(*args)
# If user is not signed-in and tries to access root_path - redirect him to landing page if redirect_to_home_page_url?
# Don't redirect to the default URL to prevent endless redirections redirect_to current_application_settings.home_page_url and return
if current_application_settings.home_page_url.present? &&
current_application_settings.home_page_url.chomp('/') != Gitlab.config.gitlab['url'].chomp('/')
if current_user.nil? && root_path == request.path
redirect_to current_application_settings.home_page_url and return
end
end end
super(*args) super(*args)
...@@ -352,4 +347,17 @@ class ApplicationController < ActionController::Base ...@@ -352,4 +347,17 @@ class ApplicationController < ActionController::Base
def git_import_enabled? def git_import_enabled?
current_application_settings.import_sources.include?('git') current_application_settings.import_sources.include?('git')
end end
def redirect_to_home_page_url?
# If user is not signed-in and tries to access root_path - redirect him to landing page
# Don't redirect to the default URL to prevent endless redirections
return false unless current_application_settings.home_page_url.present?
home_page_url = current_application_settings.home_page_url.chomp('/')
root_urls = [Gitlab.config.gitlab['url'].chomp('/'), root_url.chomp('/')]
return false if root_urls.include?(home_page_url)
current_user.nil? && root_path == request.path
end
end end
...@@ -17,6 +17,7 @@ module Ci ...@@ -17,6 +17,7 @@ module Ci
@projects = @projects.where(gitlab_id: @gl_projects.select(:id)) @projects = @projects.where(gitlab_id: @gl_projects.select(:id))
end end
@projects = @projects.where("ci_projects.id NOT IN (?)", @runner.projects.pluck(:id)) if @runner.projects.any? @projects = @projects.where("ci_projects.id NOT IN (?)", @runner.projects.pluck(:id)) if @runner.projects.any?
@projects = @projects.joins(:gl_project)
@projects = @projects.page(params[:page]).per(30) @projects = @projects.page(params[:page]).per(30)
end end
......
...@@ -8,14 +8,6 @@ module Ci ...@@ -8,14 +8,6 @@ module Ci
private private
def authenticate_public_page!
unless project.public
authenticate_user!
return access_denied! unless can?(current_user, :read_project, gl_project)
end
end
def authenticate_token! def authenticate_token!
unless project.valid_token?(params[:token]) unless project.valid_token?(params[:token])
return head(403) return head(403)
......
module Ci
class EventsController < Ci::ApplicationController
EVENTS_PER_PAGE = 50
before_action :authenticate_user!
before_action :project
before_action :authorize_manage_project!
layout 'ci/project'
def index
@events = project.events.order("created_at DESC").page(params[:page]).per(EVENTS_PER_PAGE)
end
private
def project
@project ||= Ci::Project.find(params[:project_id])
end
end
end
...@@ -4,8 +4,6 @@ module Ci ...@@ -4,8 +4,6 @@ module Ci
before_action :project before_action :project
before_action :authorize_manage_project! before_action :authorize_manage_project!
layout 'ci/project'
def create def create
@runner = Ci::Runner.find(params[:runner_project][:runner_id]) @runner = Ci::Runner.find(params[:runner_project][:runner_id])
......
...@@ -4,12 +4,12 @@ class GroupsController < Groups::ApplicationController ...@@ -4,12 +4,12 @@ class GroupsController < Groups::ApplicationController
before_action :group, except: [:new, :create] before_action :group, except: [:new, :create]
# Authorize # Authorize
before_action :authorize_read_group!, except: [:show, :new, :create] before_action :authorize_read_group!, except: [:show, :new, :create, :autocomplete]
before_action :authorize_admin_group!, only: [:edit, :update, :destroy, :projects] before_action :authorize_admin_group!, only: [:edit, :update, :destroy, :projects]
before_action :authorize_create_group!, only: [:new, :create] before_action :authorize_create_group!, only: [:new, :create]
# Load group projects # Load group projects
before_action :load_projects, except: [:new, :create, :projects, :edit, :update] before_action :load_projects, except: [:new, :create, :projects, :edit, :update, :autocomplete]
before_action :event_filter, only: :show before_action :event_filter, only: :show
layout :determine_layout layout :determine_layout
...@@ -135,7 +135,7 @@ class GroupsController < Groups::ApplicationController ...@@ -135,7 +135,7 @@ class GroupsController < Groups::ApplicationController
end end
def group_params def group_params
params.require(:group).permit(:name, :description, :path, :avatar, :membership_lock, :share_with_group_lock) params.require(:group).permit(:name, :description, :path, :avatar, :membership_lock, :share_with_group_lock, :public)
end end
def load_events def load_events
......
...@@ -161,7 +161,7 @@ class Projects::BlobController < Projects::ApplicationController ...@@ -161,7 +161,7 @@ class Projects::BlobController < Projects::ApplicationController
if params[:file].present? if params[:file].present?
params[:file_name] = params[:file].original_filename params[:file_name] = params[:file].original_filename
end end
File.join(@path, File.basename(params[:file_name])) File.join(@path, params[:file_name])
else else
@path @path
end end
......
...@@ -2,23 +2,24 @@ class Projects::BuildsController < Projects::ApplicationController ...@@ -2,23 +2,24 @@ class Projects::BuildsController < Projects::ApplicationController
before_action :ci_project before_action :ci_project
before_action :build, except: [:index, :cancel_all] before_action :build, except: [:index, :cancel_all]
before_action :authorize_admin_project!, except: [:index, :show, :status] before_action :authorize_manage_builds!, except: [:index, :show, :status]
layout "project" layout "project"
def index def index
@scope = params[:scope] @scope = params[:scope]
@all_builds = project.ci_builds @all_builds = project.ci_builds
@builds = @all_builds.order('created_at DESC')
@builds = @builds =
case @scope case @scope
when 'all' when 'all'
@all_builds @builds
when 'finished' when 'finished'
@all_builds.finished @builds.finished
else else
@all_builds.running_or_pending @builds.running_or_pending.reverse_order
end end
@builds = @builds.order('created_at DESC').page(params[:page]).per(30) @builds = @builds.page(params[:page]).per(30)
end end
def cancel_all def cancel_all
...@@ -73,4 +74,10 @@ class Projects::BuildsController < Projects::ApplicationController ...@@ -73,4 +74,10 @@ class Projects::BuildsController < Projects::ApplicationController
def build_path(build) def build_path(build)
namespace_project_build_path(build.gl_project.namespace, build.gl_project, build) namespace_project_build_path(build.gl_project.namespace, build.gl_project, build)
end end
def authorize_manage_builds!
unless can?(current_user, :manage_builds, project)
return page_404
end
end
end end
...@@ -4,7 +4,8 @@ ...@@ -4,7 +4,8 @@
class Projects::CommitController < Projects::ApplicationController class Projects::CommitController < Projects::ApplicationController
# Authorize # Authorize
before_action :require_non_empty_project before_action :require_non_empty_project
before_action :authorize_download_code! before_action :authorize_download_code!, except: [:cancel_builds]
before_action :authorize_manage_builds!, only: [:cancel_builds]
before_action :commit before_action :commit
def show def show
...@@ -55,4 +56,12 @@ class Projects::CommitController < Projects::ApplicationController ...@@ -55,4 +56,12 @@ class Projects::CommitController < Projects::ApplicationController
def commit def commit
@commit ||= @project.commit(params[:id]) @commit ||= @project.commit(params[:id])
end end
private
def authorize_manage_builds!
unless can?(current_user, :manage_builds, project)
return page_404
end
end
end end
...@@ -12,7 +12,7 @@ class Projects::CommitsController < Projects::ApplicationController ...@@ -12,7 +12,7 @@ class Projects::CommitsController < Projects::ApplicationController
@limit, @offset = (params[:limit] || 40), (params[:offset] || 0) @limit, @offset = (params[:limit] || 40), (params[:offset] || 0)
@commits = @repo.commits(@ref, @path, @limit, @offset) @commits = @repo.commits(@ref, @path, @limit, @offset)
@note_counts = Note.where(commit_id: @commits.map(&:id)). @note_counts = project.notes.where(commit_id: @commits.map(&:id)).
group(:commit_id).count group(:commit_id).count
respond_to do |format| respond_to do |format|
......
...@@ -6,11 +6,10 @@ class Projects::RunnersController < Projects::ApplicationController ...@@ -6,11 +6,10 @@ class Projects::RunnersController < Projects::ApplicationController
layout 'project_settings' layout 'project_settings'
def index def index
@runners = @ci_project.runners.order('id DESC') @runners = @ci_project.runners.ordered
@specific_runners = @specific_runners = current_user.ci_authorized_runners.
Ci::Runner.specific.includes(:runner_projects). where.not(id: @ci_project.runners).
where(Ci::RunnerProject.table_name => { project_id: current_user.authorized_projects } ). ordered.page(params[:page]).per(20)
where.not(id: @runners).order("#{Ci::Runner.table_name}.id DESC").page(params[:page]).per(20)
@shared_runners = Ci::Runner.shared.active @shared_runners = Ci::Runner.shared.active
@shared_runners_count = @shared_runners.count(:all) @shared_runners_count = @shared_runners.count(:all)
end end
......
class ProjectsController < ApplicationController class ProjectsController < ApplicationController
include ExtractsPath include ExtractsPath
prepend_before_filter :render_go_import, only: [:show] prepend_before_action :render_go_import, only: [:show]
skip_before_action :authenticate_user!, only: [:show, :activity] skip_before_action :authenticate_user!, only: [:show, :activity]
before_action :project, except: [:new, :create] before_action :project, except: [:new, :create]
before_action :repository, except: [:new, :create] before_action :repository, except: [:new, :create]
...@@ -124,11 +124,7 @@ class ProjectsController < ApplicationController ...@@ -124,11 +124,7 @@ class ProjectsController < ApplicationController
::Projects::DestroyService.new(@project, current_user, {}).execute ::Projects::DestroyService.new(@project, current_user, {}).execute
flash[:alert] = "Project '#{@project.name}' was deleted." flash[:alert] = "Project '#{@project.name}' was deleted."
if request.referer.include?('/admin') redirect_back_or_default(default: dashboard_projects_path, options: {})
redirect_to admin_namespaces_projects_path
else
redirect_to dashboard_projects_path
end
rescue Projects::DestroyService::DestroyError => ex rescue Projects::DestroyService::DestroyError => ex
redirect_to edit_project_path(@project), alert: ex.message redirect_to edit_project_path(@project), alert: ex.message
end end
......
...@@ -23,8 +23,8 @@ class SearchController < ApplicationController ...@@ -23,8 +23,8 @@ class SearchController < ApplicationController
@search_results = @search_results =
if @project if @project
unless %w(blobs notes issues merge_requests milestones wiki_blobs). unless %w(blobs notes issues merge_requests milestones wiki_blobs
include?(@scope) commits).include?(@scope)
@scope = 'blobs' @scope = 'blobs'
end end
......
...@@ -6,33 +6,34 @@ class GroupsFinder ...@@ -6,33 +6,34 @@ class GroupsFinder
private private
def all_groups(current_user) def all_groups(current_user)
if current_user group_ids = if current_user
if current_user.authorized_groups.any? if current_user.authorized_groups.any?
# User has access to groups # User has access to groups
# #
# Return only: # Return only:
# groups with public projects # groups with public projects
# groups with internal projects # groups with internal projects
# groups with joined projects # groups with joined projects
# #
group_ids = Project.public_and_internal_only.pluck(:namespace_id) + Project.public_and_internal_only.pluck(:namespace_id) +
current_user.authorized_groups.pluck(:id) current_user.authorized_groups.pluck(:id)
Group.where(id: group_ids) else
else # User has no group membership
# User has no group membership #
# # Return only:
# Return only: # groups with public projects
# groups with public projects # groups with internal projects
# groups with internal projects #
# Project.public_and_internal_only.pluck(:namespace_id)
Group.where(id: Project.public_and_internal_only.pluck(:namespace_id)) end
end else
else # Not authenticated
# Not authenticated #
# # Return only:
# Return only: # groups with public projects
# groups with public projects Project.public_only.pluck(:namespace_id)
Group.where(id: Project.public_only.pluck(:namespace_id)) end
end
Group.where("public IS TRUE OR id IN(?)", group_ids)
end end
end end
module AuthHelper module AuthHelper
PROVIDERS_WITH_ICONS = %w(twitter github gitlab bitbucket google_oauth2).freeze PROVIDERS_WITH_ICONS = %w(twitter github gitlab bitbucket google_oauth2 facebook).freeze
FORM_BASED_PROVIDERS = [/\Aldap/, 'kerberos', 'crowd'].freeze FORM_BASED_PROVIDERS = [/\Aldap/, 'kerberos', 'crowd'].freeze
def ldap_enabled? def ldap_enabled?
......
...@@ -42,4 +42,13 @@ module CiStatusHelper ...@@ -42,4 +42,13 @@ module CiStatusHelper
icon(icon_name) icon(icon_name)
end end
def render_ci_status(ci_commit)
link_to ci_status_path(ci_commit),
class: "c#{ci_status_color(ci_commit)}",
title: "Build status: #{ci_commit.status}",
data: { toggle: 'tooltip', placement: 'left' } do
ci_status_icon(ci_commit)
end
end
end end
module ClipboardHelper
def clipboard_button
content_tag :button,
icon('clipboard'),
class: 'btn btn-xs btn-clipboard js-clipboard-trigger',
type: :button
end
end
...@@ -70,7 +70,7 @@ module SearchHelper ...@@ -70,7 +70,7 @@ module SearchHelper
# Autocomplete results for the current user's groups # Autocomplete results for the current user's groups
def groups_autocomplete(term, limit = 5) def groups_autocomplete(term, limit = 5)
current_user.authorized_groups.search(term).limit(limit).map do |group| GroupsFinder.new.execute(current_user).search(term).limit(limit).map do |group|
{ {
label: "group: #{search_result_sanitize(group.name)}", label: "group: #{search_result_sanitize(group.name)}",
url: group_path(group) url: group_path(group)
......
...@@ -187,7 +187,7 @@ module Ci ...@@ -187,7 +187,7 @@ module Ci
end end
def config_processor def config_processor
@config_processor ||= Ci::GitlabCiYamlProcessor.new(ci_yaml_file) @config_processor ||= Ci::GitlabCiYamlProcessor.new(ci_yaml_file, gl_project.path_with_namespace)
rescue Ci::GitlabCiYamlProcessor::ValidationError => e rescue Ci::GitlabCiYamlProcessor::ValidationError => e
save_yaml_error(e.message) save_yaml_error(e.message)
nil nil
......
...@@ -99,6 +99,7 @@ module Ci ...@@ -99,6 +99,7 @@ module Ci
def ordered_by_last_commit_date def ordered_by_last_commit_date
last_commit_subquery = "(SELECT gl_project_id, MAX(committed_at) committed_at FROM #{Ci::Commit.table_name} GROUP BY gl_project_id)" last_commit_subquery = "(SELECT gl_project_id, MAX(committed_at) committed_at FROM #{Ci::Commit.table_name} GROUP BY gl_project_id)"
joins("LEFT JOIN #{last_commit_subquery} AS last_commit ON #{Ci::Project.table_name}.gitlab_id = last_commit.gl_project_id"). joins("LEFT JOIN #{last_commit_subquery} AS last_commit ON #{Ci::Project.table_name}.gitlab_id = last_commit.gl_project_id").
joins(:gl_project).
order("CASE WHEN last_commit.committed_at IS NULL THEN 1 ELSE 0 END, last_commit.committed_at DESC") order("CASE WHEN last_commit.committed_at IS NULL THEN 1 ELSE 0 END, last_commit.committed_at DESC")
end end
end end
......
...@@ -27,9 +27,5 @@ module Ci ...@@ -27,9 +27,5 @@ module Ci
def human_status def human_status
status status
end end
def last_commit_for_ref(ref)
commits.where(ref: ref).last
end
end end
end end
...@@ -36,6 +36,7 @@ module Ci ...@@ -36,6 +36,7 @@ module Ci
scope :active, ->() { where(active: true) } scope :active, ->() { where(active: true) }
scope :paused, ->() { where(active: false) } scope :paused, ->() { where(active: false) }
scope :online, ->() { where('contacted_at > ?', LAST_CONTACT_TIME) } scope :online, ->() { where('contacted_at > ?', LAST_CONTACT_TIME) }
scope :ordered, ->() { order(id: :desc) }
acts_as_taggable acts_as_taggable
......
...@@ -20,7 +20,6 @@ class CommitStatus < ActiveRecord::Base ...@@ -20,7 +20,6 @@ class CommitStatus < ActiveRecord::Base
scope :latest, -> { where(id: unscope(:select).select('max(id)').group(:name, :ref)) } scope :latest, -> { where(id: unscope(:select).select('max(id)').group(:name, :ref)) }
scope :ordered, -> { order(:ref, :stage_idx, :name) } scope :ordered, -> { order(:ref, :stage_idx, :name) }
scope :for_ref, ->(ref) { where(ref: ref) } scope :for_ref, ->(ref) { where(ref: ref) }
scope :running_or_pending, -> { where(status: [:running, :pending]) }
state_machine :status, initial: :pending do state_machine :status, initial: :pending do
event :run do event :run do
......
...@@ -8,12 +8,12 @@ module Sortable ...@@ -8,12 +8,12 @@ module Sortable
included do included do
# By default all models should be ordered # By default all models should be ordered
# by created_at field starting from newest # by created_at field starting from newest
default_scope { order(created_at: :desc, id: :desc) } default_scope { order(id: :desc) }
scope :order_created_desc, -> { reorder(created_at: :desc, id: :desc) } scope :order_created_desc, -> { reorder(created_at: :desc) }
scope :order_created_asc, -> { reorder(created_at: :asc, id: :asc) } scope :order_created_asc, -> { reorder(created_at: :asc) }
scope :order_updated_desc, -> { reorder(updated_at: :desc, id: :desc) } scope :order_updated_desc, -> { reorder(updated_at: :desc) }
scope :order_updated_asc, -> { reorder(updated_at: :asc, id: :asc) } scope :order_updated_asc, -> { reorder(updated_at: :asc) }
scope :order_name_asc, -> { reorder(name: :asc) } scope :order_name_asc, -> { reorder(name: :asc) }
scope :order_name_desc, -> { reorder(name: :desc) } scope :order_name_desc, -> { reorder(name: :desc) }
end end
......
...@@ -128,7 +128,7 @@ class Group < Namespace ...@@ -128,7 +128,7 @@ class Group < Namespace
end end
def public_profile? def public_profile?
projects.public_only.any? self.public || projects.public_only.any?
end end
# NOTE: Backwards compatibility with old ldap situation # NOTE: Backwards compatibility with old ldap situation
......
...@@ -163,11 +163,11 @@ class MergeRequest < ActiveRecord::Base ...@@ -163,11 +163,11 @@ class MergeRequest < ActiveRecord::Base
def last_commit def last_commit
merge_request_diff ? merge_request_diff.last_commit : compare_commits.last merge_request_diff ? merge_request_diff.last_commit : compare_commits.last
end end
def first_commit def first_commit
merge_request_diff ? merge_request_diff.first_commit : compare_commits.first merge_request_diff ? merge_request_diff.first_commit : compare_commits.first
end end
def last_commit_short_sha def last_commit_short_sha
last_commit.short_id last_commit.short_id
...@@ -261,7 +261,7 @@ class MergeRequest < ActiveRecord::Base ...@@ -261,7 +261,7 @@ class MergeRequest < ActiveRecord::Base
Note.where( Note.where(
"(project_id = :target_project_id AND noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR" + "(project_id = :target_project_id AND noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR" +
"(project_id = :source_project_id AND noteable_type = 'Commit' AND commit_id IN (:commit_ids))", "((project_id = :source_project_id OR project_id = :target_project_id) AND noteable_type = 'Commit' AND commit_id IN (:commit_ids))",
mr_id: id, mr_id: id,
commit_ids: commit_ids, commit_ids: commit_ids,
target_project_id: target_project_id, target_project_id: target_project_id,
...@@ -542,4 +542,10 @@ class MergeRequest < ActiveRecord::Base ...@@ -542,4 +542,10 @@ class MergeRequest < ActiveRecord::Base
def rebase_in_progress? def rebase_in_progress?
File.exist?(rebase_dir_path) File.exist?(rebase_dir_path)
end end
def ci_commit
if last_commit
source_project.ci_commit(last_commit.id)
end
end
end end
...@@ -67,13 +67,16 @@ class Repository ...@@ -67,13 +67,16 @@ class Repository
end end
def commits(ref, path = nil, limit = nil, offset = nil, skip_merges = false) def commits(ref, path = nil, limit = nil, offset = nil, skip_merges = false)
commits = Gitlab::Git::Commit.where( options = {
repo: raw_repository, repo: raw_repository,
ref: ref, ref: ref,
path: path, path: path,
limit: limit, limit: limit,
offset: offset, offset: offset,
) follow: path.present?
}
commits = Gitlab::Git::Commit.where(options)
commits = Commit.decorate(commits, @project) if commits.present? commits = Commit.decorate(commits, @project) if commits.present?
commits commits
end end
...@@ -84,6 +87,15 @@ class Repository ...@@ -84,6 +87,15 @@ class Repository
commits commits
end end
def find_commits_by_message(query)
# Limited to 1000 commits for now, could be parameterized?
args = %W(#{Gitlab.config.git.bin_path} log --pretty=%H --max-count 1000 --grep=#{query})
git_log_results = Gitlab::Popen.popen(args, path_to_repo).first.lines.map(&:chomp)
commits = git_log_results.map { |c| commit(c) }
commits
end
def find_branch(name) def find_branch(name)
branches.find { |branch| branch.name == name } branches.find { |branch| branch.name == name }
end end
...@@ -284,7 +296,7 @@ class Repository ...@@ -284,7 +296,7 @@ class Repository
end end
def last_commit_for_path(sha, path) def last_commit_for_path(sha, path)
args = %W(git rev-list --max-count=1 #{sha} -- #{path}) args = %W(#{Gitlab.config.git.bin_path} rev-list --max-count=1 #{sha} -- #{path})
sha = Gitlab::Popen.popen(args, path_to_repo).first.strip sha = Gitlab::Popen.popen(args, path_to_repo).first.strip
commit(sha) commit(sha)
end end
...@@ -335,7 +347,7 @@ class Repository ...@@ -335,7 +347,7 @@ class Repository
end end
def branch_names_contains(sha) def branch_names_contains(sha)
args = %W(git branch --contains #{sha}) args = %W(#{Gitlab.config.git.bin_path} branch --contains #{sha})
names = Gitlab::Popen.popen(args, path_to_repo).first names = Gitlab::Popen.popen(args, path_to_repo).first
if names.respond_to?(:split) if names.respond_to?(:split)
...@@ -352,7 +364,7 @@ class Repository ...@@ -352,7 +364,7 @@ class Repository
end end
def tag_names_contains(sha) def tag_names_contains(sha)
args = %W(git tag --contains #{sha}) args = %W(#{Gitlab.config.git.bin_path} tag --contains #{sha})
names = Gitlab::Popen.popen(args, path_to_repo).first names = Gitlab::Popen.popen(args, path_to_repo).first
if names.respond_to?(:split) if names.respond_to?(:split)
...@@ -505,7 +517,7 @@ class Repository ...@@ -505,7 +517,7 @@ class Repository
def search_files(query, ref) def search_files(query, ref)
offset = 2 offset = 2
args = %W(git grep -i -n --before-context #{offset} --after-context #{offset} #{query} #{ref || root_ref}) args = %W(#{Gitlab.config.git.bin_path} grep -i -n --before-context #{offset} --after-context #{offset} -e #{query} #{ref || root_ref})
Gitlab::Popen.popen(args, path_to_repo).first.scrub.split(/^--$/) Gitlab::Popen.popen(args, path_to_repo).first.scrub.split(/^--$/)
end end
...@@ -537,7 +549,7 @@ class Repository ...@@ -537,7 +549,7 @@ class Repository
end end
def fetch_ref(source_path, source_ref, target_ref) def fetch_ref(source_path, source_ref, target_ref)
args = %W(git fetch #{source_path} #{source_ref}:#{target_ref}) args = %W(#{Gitlab.config.git.bin_path} fetch -f #{source_path} #{source_ref}:#{target_ref})
Gitlab::Popen.popen(args, path_to_repo) Gitlab::Popen.popen(args, path_to_repo)
end end
......
...@@ -238,21 +238,16 @@ class User < ActiveRecord::Base ...@@ -238,21 +238,16 @@ class User < ActiveRecord::Base
# Find a User by their primary email or any associated secondary email # Find a User by their primary email or any associated secondary email
def find_by_any_email(email) def find_by_any_email(email)
user_table = arel_table sql = 'SELECT *
email_table = Email.arel_table FROM users
WHERE id IN (
SELECT id FROM users WHERE email = :email
UNION
SELECT emails.user_id FROM emails WHERE email = :email
)
LIMIT 1;'
# Use ARel to build a query: User.find_by_sql([sql, { email: email }]).first
query = user_table.
# SELECT "users".* FROM "users"
project(user_table[Arel.star]).
# LEFT OUTER JOIN "emails"
join(email_table, Arel::Nodes::OuterJoin).
# ON "users"."id" = "emails"."user_id"
on(user_table[:id].eq(email_table[:user_id])).
# WHERE ("user"."email" = '<email>' OR "emails"."email" = '<email>')
where(user_table[:email].eq(email).or(email_table[:email].eq(email)))
find_by_sql(query.to_sql).first
end end
def existing_member?(email) def existing_member?(email)
...@@ -429,16 +424,18 @@ class User < ActiveRecord::Base ...@@ -429,16 +424,18 @@ class User < ActiveRecord::Base
end end
end end
def authorized_projects_id
@authorized_projects_id ||= begin
project_ids = personal_projects.pluck(:id)
project_ids.push(*groups_projects.pluck(:id))
project_ids.push(*projects.pluck(:id).uniq)
project_ids.push(*groups.joins(:shared_projects).pluck(:project_id))
end
end
# Projects user has access to # Projects user has access to
def authorized_projects def authorized_projects
@authorized_projects ||= begin @authorized_projects ||= Project.where(id: authorized_projects_id)
project_ids = personal_projects.pluck(:id)
project_ids.push(*groups_projects.pluck(:id))
project_ids.push(*projects.pluck(:id).uniq)
project_ids.push(*groups.joins(:shared_projects).pluck(:project_id))
Project.where(id: project_ids)
end
end end
def owned_projects def owned_projects
...@@ -801,11 +798,14 @@ class User < ActiveRecord::Base ...@@ -801,11 +798,14 @@ class User < ActiveRecord::Base
end end
def ci_authorized_projects def ci_authorized_projects
@ci_authorized_projects ||= Ci::Project.where(gitlab_id: authorized_projects) @ci_authorized_projects ||= Ci::Project.where(gitlab_id: authorized_projects_id)
end end
def ci_authorized_runners def ci_authorized_runners
Ci::Runner.specific.includes(:runner_projects). @ci_authorized_runners ||= begin
where(ci_runner_projects: { project_id: ci_authorized_projects } ) runner_ids = Ci::RunnerProject.joins(:project).
where(ci_projects: { gitlab_id: authorized_projects_id }).select(:runner_id)
Ci::Runner.specific.where(id: runner_ids)
end
end end
end end
module Ci module Ci
class ImageForBuildService class ImageForBuildService
def execute(project, params) def execute(project, params)
image_name = sha = params[:sha]
if params[:sha] sha ||=
commit = project.commits.find_by(sha: params[:sha]) if params[:ref]
image_for_commit(commit) project.gl_project.commit(params[:ref]).try(:sha)
elsif params[:ref]
commit = project.last_commit_for_ref(params[:ref])
image_for_commit(commit)
else
'build-unknown.svg'
end end
commit = project.commits.ordered.find_by(sha: sha)
image_name = image_for_commit(commit)
image_path = Rails.root.join('public/ci', image_name) image_path = Rails.root.join('public/ci', image_name)
OpenStruct.new( OpenStruct.new(
......
...@@ -5,5 +5,16 @@ module Files ...@@ -5,5 +5,16 @@ module Files
def commit def commit
repository.commit_dir(current_user, @file_path, @commit_message, @target_branch) repository.commit_dir(current_user, @file_path, @commit_message, @target_branch)
end end
def validate
super
unless @file_path =~ Gitlab::Regex.file_path_regex
raise_error(
'Your changes could not be committed, because the file path ' +
Gitlab::Regex.file_path_regex_message
)
end
end
end end
end end
...@@ -9,12 +9,17 @@ module Files ...@@ -9,12 +9,17 @@ module Files
def validate def validate
super super
file_name = File.basename(@file_path) if @file_path =~ Gitlab::Regex.directory_traversal_regex
raise_error(
'Your changes could not be committed, because the file name ' +
Gitlab::Regex.directory_traversal_regex_message
)
end
unless file_name =~ Gitlab::Regex.file_name_regex unless @file_path =~ Gitlab::Regex.file_path_regex
raise_error( raise_error(
'Your changes could not be committed, because the file name ' + 'Your changes could not be committed, because the file name ' +
Gitlab::Regex.file_name_regex_message Gitlab::Regex.file_path_regex_message
) )
end end
......
...@@ -35,7 +35,7 @@ module Issues ...@@ -35,7 +35,7 @@ module Issues
create_title_change_note(issue, issue.previous_changes['title'].first) create_title_change_note(issue, issue.previous_changes['title'].first)
end end
issue.create_new_cross_references! issue.create_new_cross_references!(current_user)
execute_hooks(issue, 'update') execute_hooks(issue, 'update')
end end
......
...@@ -59,7 +59,7 @@ module MergeRequests ...@@ -59,7 +59,7 @@ module MergeRequests
merge_request.mark_as_unchecked merge_request.mark_as_unchecked
end end
merge_request.create_new_cross_references! merge_request.create_new_cross_references!(current_user)
execute_hooks(merge_request, 'update') execute_hooks(merge_request, 'update')
end end
......
...@@ -4,7 +4,7 @@ module Notes ...@@ -4,7 +4,7 @@ module Notes
return note unless note.editable? return note unless note.editable?
note.update_attributes(params.merge(updated_by: current_user)) note.update_attributes(params.merge(updated_by: current_user))
note.create_new_cross_references! note.create_new_cross_references!(current_user)
note.reset_events_cache note.reset_events_cache
note note
......
...@@ -94,8 +94,6 @@ module Projects ...@@ -94,8 +94,6 @@ module Projects
@project.team << [current_user, :master, current_user] @project.team << [current_user, :master, current_user]
end end
@project.update_column(:last_activity_at, @project.created_at)
if @project.import? if @project.import?
@project.import_start @project.import_start
end end
......
%p.lead %p.lead
To register new runner visit #{link_to 'this page ', ci_runners_path} To register a new runner visit #{link_to 'this page ', ci_runners_path}
.row .row
.col-md-8 .col-md-8
......
%p.lead %p.lead
%span To register new runner you should enter the following registration token. With this token the runner will request a unique runner token and use that for future communication. %span To register a new runner you should enter the following registration token. With this token the runner will request a unique runner token and use that for future communication.
%code #{GitlabCi::REGISTRATION_TOKEN} %code #{GitlabCi::REGISTRATION_TOKEN}
.bs-callout .bs-callout
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
\- run builds from assigned projects \- run builds from assigned projects
%li %li
%span.label.label-danger paused %span.label.label-danger paused
\- runner will not receive any new build \- runner will not receive any new builds
.append-bottom-20.clearfix .append-bottom-20.clearfix
.pull-left .pull-left
......
...@@ -13,13 +13,13 @@ ...@@ -13,13 +13,13 @@
- if @runner.shared? - if @runner.shared?
.bs-callout.bs-callout-success .bs-callout.bs-callout-success
%h4 This runner will process build from ALL UNASSIGNED projects %h4 This runner will process builds from ALL UNASSIGNED projects
%p %p
If you want runners to build only specific projects, enable them in the table below. If you want runners to build only specific projects, enable them in the table below.
Keep in mind that this is a one way transition. Keep in mind that this is a one way transition.
- else - else
.bs-callout.bs-callout-info .bs-callout.bs-callout-info
%h4 This runner will process build only from ASSIGNED projects %h4 This runner will process builds only from ASSIGNED projects
%p You can't make this a shared runner. %p You can't make this a shared runner.
%hr %hr
= form_for @runner, url: ci_admin_runner_path(@runner), html: { class: 'form-horizontal' } do |f| = form_for @runner, url: ci_admin_runner_path(@runner), html: { class: 'form-horizontal' } do |f|
...@@ -53,13 +53,14 @@ ...@@ -53,13 +53,14 @@
%th %th
- @runner.runner_projects.each do |runner_project| - @runner.runner_projects.each do |runner_project|
- project = runner_project.project - project = runner_project.project
%tr.alert-info - if project.gl_project
%td %tr.alert-info
%strong %td
= project.name %strong
%td = project.name
.pull-right %td
= link_to 'Disable', [:ci, :admin, project, runner_project], method: :delete, class: 'btn btn-danger btn-xs' .pull-right
= link_to 'Disable', [:ci, :admin, project, runner_project], method: :delete, class: 'btn btn-danger btn-xs'
%table.table %table.table
%thead %thead
...@@ -103,21 +104,26 @@ ...@@ -103,21 +104,26 @@
%th Finished at %th Finished at
- @builds.each do |build| - @builds.each do |build|
- gl_project = build.gl_project
%tr.build %tr.build
%td.id %td.id
- gl_project = build.project.gl_project - if gl_project
= link_to namespace_project_build_path(gl_project.namespace, gl_project, build) do = link_to namespace_project_build_path(gl_project.namespace, gl_project, build) do
= build.id
- else
= build.id = build.id
%td.status %td.status
= ci_status_with_icon(build.status) = ci_status_with_icon(build.status)
%td.status %td.status
= build.project.name - if gl_project
= gl_project.name_with_namespace
%td.build-link %td.build-link
= link_to ci_status_path(build.commit) do - if gl_project
%strong #{build.commit.short_sha} = link_to ci_status_path(build.commit) do
%strong #{build.commit.short_sha}
%td.timestamp %td.timestamp
- if build.finished_at - if build.finished_at
......
%h3.page-title Events
.table-holder
%table.table
%thead
%tr
%th User ID
%th Description
%th When
- @events.each do |event|
%tr
%td
= event.user_id
%td
= event.description
%td.light
= time_ago_in_words event.updated_at
ago
= paginate @events
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
%td #{stage.capitalize} Job - #{build[:name]} %td #{stage.capitalize} Job - #{build[:name]}
%td %td
%pre %pre
= simple_format build[:script] = simple_format build[:commands]
%br %br
%b Tag list: %b Tag list:
...@@ -28,6 +28,11 @@ ...@@ -28,6 +28,11 @@
%br %br
%b Refs except: %b Refs except:
= build[:except] && build[:except].join(", ") = build[:except] && build[:except].join(", ")
%br
%b When:
= build[:when]
- if build[:allow_failure]
%b Allowed to fail
-else -else
%p %p
......
.login-block .login-block
%h2 Login using GitLab account %h2 Login using GitLab account
%p.light %p.light
Make sure you have account on GitLab server Make sure you have an account on the GitLab server
= link_to GitlabCi.config.gitlab_server.url, GitlabCi.config.gitlab_server.url, no_turbolink = link_to GitlabCi.config.gitlab_server.url, GitlabCi.config.gitlab_server.url, no_turbolink
%hr %hr
= link_to "Login with GitLab", auth_ci_user_sessions_path(state: params[:state]), no_turbolink.merge( class: 'btn btn-login btn-success' ) = link_to "Login with GitLab", auth_ci_user_sessions_path(state: params[:state]), no_turbolink.merge( class: 'btn btn-login btn-success' )
...@@ -43,6 +43,15 @@ ...@@ -43,6 +43,15 @@
= f.check_box :share_with_group_lock = f.check_box :share_with_group_lock
%span.descr Prevent sharing a project with another group within this group %span.descr Prevent sharing a project with another group within this group
.form-group
%hr
= f.label :public, class: 'control-label' do
Public
.col-sm-10
.checkbox
= f.check_box :public
%span.descr Make this group public (even if there is no any public project inside this group)
.form-actions .form-actions
= f.submit 'Save group', class: "btn btn-save" = f.submit 'Save group', class: "btn btn-save"
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
= hidden_field_tag :scope, 'merge_requests' = hidden_field_tag :scope, 'merge_requests'
- elsif current_controller?(:wikis) - elsif current_controller?(:wikis)
= hidden_field_tag :scope, 'wiki_blobs' = hidden_field_tag :scope, 'wiki_blobs'
- elsif current_controller?(:commits)
= hidden_field_tag :scope, 'commits'
- else - else
= hidden_field_tag :search_code, true = hidden_field_tag :search_code, true
......
!!! 5
%html{ lang: "en"}
= render 'layouts/head'
%body{class: "ci-body #{user_application_theme}", 'data-page' => body_data_page}
- header_title @project.name, ci_project_path(@project)
- if current_user
= render "layouts/header/default", title: header_title
- else
= render "layouts/header/public", title: header_title
= render 'layouts/ci/page', sidebar: 'nav_project'
%ul.nav.nav-sidebar %ul.nav.nav-sidebar
= nav_link do = nav_link do
= link_to root_path, title: 'Back to dashboard', data: {placement: 'right'}, class: 'back-link' do = link_to root_path, title: 'Go to dashboard', data: {placement: 'right'}, class: 'back-link' do
= icon('caret-square-o-left fw') = icon('caret-square-o-left fw')
%span %span
Back to dashboard Go to dashboard
%li.separate-item %li.separate-item
......
%ul.nav.nav-sidebar %ul.nav.nav-sidebar
= nav_link do = nav_link do
= link_to group_path(@group), title: 'Back to group', data: {placement: 'right'}, class: 'back-link' do = link_to group_path(@group), title: 'Go to group', data: {placement: 'right'}, class: 'back-link' do
= icon('caret-square-o-left fw') = icon('caret-square-o-left fw')
%span %span
Back to group Go to group
%li.separate-item %li.separate-item
......
%ul.nav.nav-sidebar %ul.nav.nav-sidebar
= nav_link do = nav_link do
= link_to root_path, title: 'Back to dashboard', data: {placement: 'right'}, class: 'back-link' do = link_to root_path, title: 'Go to dashboard', data: {placement: 'right'}, class: 'back-link' do
= icon('caret-square-o-left fw') = icon('caret-square-o-left fw')
%span %span
Back to dashboard Go to dashboard
%li.separate-item %li.separate-item
......
%ul.nav.nav-sidebar %ul.nav.nav-sidebar
- if @project.group - if @project.group
= nav_link do = nav_link do
= link_to group_path(@project.group), title: 'Back to group', data: {placement: 'right'}, class: 'back-link' do = link_to group_path(@project.group), title: 'Go to group', data: {placement: 'right'}, class: 'back-link' do
= icon('caret-square-o-left fw') = icon('caret-square-o-left fw')
%span %span
Back to group Go to group
- else - else
= nav_link do = nav_link do
= link_to root_path, title: 'Back to dashboard', data: {placement: 'right'}, class: 'back-link' do = link_to root_path, title: 'Go to dashboard', data: {placement: 'right'}, class: 'back-link' do
= icon('caret-square-o-left fw') = icon('caret-square-o-left fw')
%span %span
Back to dashboard Go to dashboard
%li.separate-item %li.separate-item
......
%ul.nav.nav-sidebar %ul.nav.nav-sidebar
= nav_link do = nav_link do
= link_to project_path(@project), title: 'Back to project', data: {placement: 'right'}, class: 'back-link' do = link_to project_path(@project), title: 'Go to project', data: {placement: 'right'}, class: 'back-link' do
= icon('caret-square-o-left fw') = icon('caret-square-o-left fw')
%span %span
Back to project Go to project
%li.separate-item %li.separate-item
...@@ -81,8 +81,3 @@ ...@@ -81,8 +81,3 @@
= icon('share fw') = icon('share fw')
%span %span
CI Services CI Services
= nav_link path: 'events#index' do
= link_to ci_project_events_path(@project.gitlab_ci_project) do
= icon('book fw')
%span
CI Events
...@@ -155,7 +155,7 @@ ...@@ -155,7 +155,7 @@
- if @builds.present? - if @builds.present?
.build-widget .build-widget
%h4.title #{pluralize(@builds.count, "other build")} for #{@build.short_sha}: %h4.title #{pluralize(@builds.count(:id), "other build")} for #{@build.short_sha}:
%table.table.builds %table.table.builds
- @builds.each_with_index do |build, i| - @builds.each_with_index do |build, i|
%tr.build %tr.build
......
...@@ -20,6 +20,10 @@ ...@@ -20,6 +20,10 @@
New snippet New snippet
- if can?(current_user, :push_code, @project) - if can?(current_user, :push_code, @project)
%li.divider %li.divider
%li
= link_to namespace_project_new_blob_path(@project.namespace, @project, @project.default_branch || 'master'), title: 'New file' do
= icon('file fw')
New file
%li %li
= link_to new_namespace_project_branch_path(@project.namespace, @project) do = link_to new_namespace_project_branch_path(@project.namespace, @project) do
= icon('code-fork fw') = icon('code-fork fw')
......
...@@ -102,7 +102,7 @@ ...@@ -102,7 +102,7 @@
%code \(\d+.\d+\%\) covered %code \(\d+.\d+\%\) covered
%li %li
pytest-cov (Python) - pytest-cov (Python) -
%code \d+\%$ %code \d+\%\s*$
......
...@@ -5,4 +5,4 @@ ...@@ -5,4 +5,4 @@
You can add Specific runner for this project on Runners page You can add Specific runner for this project on Runners page
- if current_user.admin - if current_user.admin
or add Shared runner for whole application in admin are. or add Shared runner for whole application in admin area.
...@@ -18,10 +18,10 @@ ...@@ -18,10 +18,10 @@
.pull-right .pull-right
- if ci_commit - if ci_commit
= link_to ci_status_path(ci_commit), class: "c#{ci_status_color(ci_commit)}" do = render_ci_status(ci_commit)
= ci_status_icon(ci_commit)
&nbsp; &nbsp;
= link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id" = clipboard_button
= link_to commit.short_id, namespace_project_commit_path(project.namespace, project, commit), class: "commit_short_id", data: {clipboard_text: commit.id}
.notes_count .notes_count
- if note_count > 0 - if note_count > 0
......
...@@ -17,8 +17,10 @@ ...@@ -17,8 +17,10 @@
- @participants.each do |participant| - @participants.each do |participant|
= link_to_member(@project, participant, name: false, size: 24) = link_to_member(@project, participant, name: false, size: 24)
.col-md-3 .col-md-3
%span.slead.has_tooltip{title: 'Cross-project reference'} .input-group.cross-project-reference
= cross_project_reference(@project, @issue) %span.slead.has_tooltip{title: 'Cross-project reference'}
= cross_project_reference(@project, @issue)
= clipboard_button
.row .row
%section.col-md-9 %section.col-md-9
......
- if @project.labels.size == 0 - if @project.labels.size == 0
$('.labels').load(document.URL + ' .light-well').hide().fadeIn(1000) $('.labels').load(document.URL + ' .nothing-here-block').hide().fadeIn(1000)
...@@ -14,8 +14,8 @@ ...@@ -14,8 +14,8 @@
= render @labels = render @labels
= paginate @labels, theme: 'gitlab' = paginate @labels, theme: 'gitlab'
- else - else
.light-well .nothing-here-block
- if can? current_user, :admin_label, @project - if can? current_user, :admin_label, @project
.nothing-here-block Create first label or #{link_to 'generate', generate_namespace_project_labels_path(@project.namespace, @project), method: :post} default set of labels Create first label or #{link_to 'generate', generate_namespace_project_labels_path(@project.namespace, @project), method: :post} default set of labels
- else - else
.nothing-here-block No labels created No labels created
- ci_commit = merge_request.ci_commit
%li{ class: mr_css_classes(merge_request) } %li{ class: mr_css_classes(merge_request) }
.merge-request-title .merge-request-title
%span.merge-request-title-text %span.merge-request-title-text
...@@ -6,6 +7,8 @@ ...@@ -6,6 +7,8 @@
- merge_request.labels.each do |label| - merge_request.labels.each do |label|
= link_to_label(label, project: merge_request.project) = link_to_label(label, project: merge_request.project)
.pull-right.light .pull-right.light
- if ci_commit
= render_ci_status(ci_commit)
- if merge_request.merged? - if merge_request.merged?
%span %span
%i.fa.fa-check %i.fa.fa-check
......
...@@ -3,11 +3,12 @@ ...@@ -3,11 +3,12 @@
.modal-content .modal-content
.modal-header .modal-header
%a.close{href: "#", "data-dismiss" => "modal"} × %a.close{href: "#", "data-dismiss" => "modal"} ×
%h3 Check out, review and merge locally %h3 Check out, review, and merge locally
.modal-body .modal-body
%p %p
%strong Step 1. %strong Step 1.
Fetch and check out the branch for this merge request Fetch and check out the branch for this merge request
= clipboard_button
%pre.dark %pre.dark
- if @merge_request.for_fork? - if @merge_request.for_fork?
:preserve :preserve
...@@ -24,6 +25,7 @@ ...@@ -24,6 +25,7 @@
%p %p
%strong Step 3. %strong Step 3.
Merge the branch and fix any conflicts that come up Merge the branch and fix any conflicts that come up
= clipboard_button
%pre.dark %pre.dark
- if @merge_request.for_fork? - if @merge_request.for_fork?
:preserve :preserve
...@@ -36,6 +38,7 @@ ...@@ -36,6 +38,7 @@
%p %p
%strong Step 4. %strong Step 4.
Push the result of the merge to GitLab Push the result of the merge to GitLab
= clipboard_button
%pre.dark %pre.dark
:preserve :preserve
git push origin #{h @merge_request.target_branch} git push origin #{h @merge_request.target_branch}
......
- ci_commit = @merge_request.source_project.ci_commit(@merge_request.source_sha) - ci_commit = @merge_request.ci_commit
- if ci_commit - if ci_commit
- status = ci_commit.status - status = ci_commit.status
.mr-widget-heading .mr-widget-heading
......
...@@ -42,6 +42,13 @@ ...@@ -42,6 +42,13 @@
Wiki Wiki
%span.badge %span.badge
= @search_results.wiki_blobs_count = @search_results.wiki_blobs_count
%li{class: ("active" if @scope == 'commits')}
= link_to search_filter_path(scope: 'commits') do
= icon('history fw')
%span
Commits
%span.badge
= @search_results.commits_count
- elsif @show_snippets - elsif @show_snippets
%li{class: ("active" if @scope == 'snippet_blobs')} %li{class: ("active" if @scope == 'snippet_blobs')}
......
.search-result-row
= render 'projects/commits/commit', project: @project, commit: commit
...@@ -21,9 +21,7 @@ ...@@ -21,9 +21,7 @@
.project-controls .project-controls
- if ci && !project.empty_repo? && project.commit - if ci && !project.empty_repo? && project.commit
- if ci_commit = project.ci_commit(project.commit.sha) - if ci_commit = project.ci_commit(project.commit.sha)
= link_to ci_status_path(ci_commit), class: "c#{ci_status_color(ci_commit)}", = render_ci_status(ci_commit)
title: "Build status: #{ci_commit.status}", data: {toggle: 'tooltip', placement: 'left'} do
= ci_status_icon(ci_commit)
&nbsp; &nbsp;
- if stars - if stars
%span %span
......
= link_to new_snippet_path, class: 'btn btn-grouped new-snippet-link', title: "New Snippet" do = link_to new_snippet_path, class: 'btn btn-grouped new-snippet-link', title: "New Snippet" do
= icon('plus') = icon('plus')
New Snippet New Snippet
- if can?(current_user, :admin_personal_snippet, @snippet)
= link_to snippet_path(@snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-remove", title: 'Delete Snippet' do
= icon('trash-o')
Delete
- if can?(current_user, :update_personal_snippet, @snippet) - if can?(current_user, :update_personal_snippet, @snippet)
= link_to edit_snippet_path(@snippet), class: "btn btn-grouped snippable-edit" do = link_to edit_snippet_path(@snippet), class: "btn btn-grouped snippable-edit" do
= icon('pencil-square-o') = icon('pencil-square-o')
Edit Edit
- if can?(current_user, :admin_personal_snippet, @snippet)
= link_to snippet_path(@snippet), method: :delete, data: { confirm: "Are you sure?" }, class: "btn btn-grouped btn-remove", title: 'Delete Snippet' do
= icon('trash-o')
Delete
- if local_assigns.has_key?(:contributed_projects) && contributed_projects.present?
.panel.panel-default.contributed-projects
.panel-heading Projects contributed to
= render 'shared/projects/list',
projects: contributed_projects.sort_by(&:star_count).reverse,
projects_limit: 5, stars: true, avatar: false
- if local_assigns.has_key?(:projects) && projects.present?
.panel.panel-default
.panel-heading Personal projects
= render 'shared/projects/list',
projects: projects.sort_by(&:star_count).reverse,
projects_limit: 10, stars: true, avatar: false
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment