Commit 7f200b7d authored by Sabba Petri's avatar Sabba Petri

Merge branch 'master' of dev.gitlab.org:gitlab/gitlabhq into sidebar_state_toggle

parents b3fd0ca0 428df28c
Please view this file on the master branch, on stable branches it's out of date.
v 7.9.0 (unreleased) v 7.9.0 (unreleased)
- Move labels/milestones tabs to sidebar - Move labels/milestones tabs to sidebar
- Upgrade Rails gem to version 4.1.9. - Upgrade Rails gem to version 4.1.9.
- Improve error messages for file edit failures
- Improve UI for commits, issues and merge request lists - Improve UI for commits, issues and merge request lists
- Fix commit comments on first line of diff not rendering in Merge Request Discussion view. - Fix commit comments on first line of diff not rendering in Merge Request Discussion view.
- Improve trigger merge request hook when source project branch has been updated (Kirill Zaitsev)
v 7.8.0 v 7.8.0
- Fix access control and protection against XSS for note attachments and other uploads. - Fix access control and protection against XSS for note attachments and other uploads.
......
...@@ -247,8 +247,8 @@ group :development, :test do ...@@ -247,8 +247,8 @@ group :development, :test do
gem 'jasmine', '2.0.2' gem 'jasmine', '2.0.2'
gem "spring", '1.1.3' gem "spring", '1.3.1'
gem "spring-commands-rspec", '1.0.1' gem "spring-commands-rspec", '1.0.4'
gem "spring-commands-spinach", '1.0.0' gem "spring-commands-spinach", '1.0.0'
end end
......
...@@ -78,7 +78,7 @@ GEM ...@@ -78,7 +78,7 @@ GEM
json (>= 1.7) json (>= 1.7)
celluloid (0.16.0) celluloid (0.16.0)
timers (~> 4.0.0) timers (~> 4.0.0)
charlock_holmes (0.6.9.4) charlock_holmes (0.7.3)
cliver (0.3.2) cliver (0.3.2)
coderay (1.1.0) coderay (1.1.0)
coercible (1.0.0) coercible (1.0.0)
...@@ -543,8 +543,8 @@ GEM ...@@ -543,8 +543,8 @@ GEM
capybara (>= 2.0.0) capybara (>= 2.0.0)
railties (>= 3) railties (>= 3)
spinach (>= 0.4) spinach (>= 0.4)
spring (1.1.3) spring (1.3.1)
spring-commands-rspec (1.0.1) spring-commands-rspec (1.0.4)
spring (>= 0.9.1) spring (>= 0.9.1)
spring-commands-spinach (1.0.0) spring-commands-spinach (1.0.0)
spring (>= 0.9.1) spring (>= 0.9.1)
...@@ -742,8 +742,8 @@ DEPENDENCIES ...@@ -742,8 +742,8 @@ DEPENDENCIES
slack-notifier (~> 1.0.0) slack-notifier (~> 1.0.0)
slim slim
spinach-rails spinach-rails
spring (= 1.1.3) spring (= 1.3.1)
spring-commands-rspec (= 1.0.1) spring-commands-rspec (= 1.0.4)
spring-commands-spinach (= 1.0.0) spring-commands-spinach (= 1.0.0)
stamp stamp
state_machine state_machine
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#= require jquery.scrollTo #= require jquery.scrollTo
#= require jquery.blockUI #= require jquery.blockUI
#= require jquery.turbolinks #= require jquery.turbolinks
#= require jquery.sticky-kit.min
#= require turbolinks #= require turbolinks
#= require autosave #= require autosave
#= require bootstrap #= require bootstrap
......
...@@ -36,6 +36,8 @@ class @Diff ...@@ -36,6 +36,8 @@ class @Diff
) )
) )
$('.diff-header').stick_in_parent(offset_top: $('.navbar').height())
lineNumbers: (line) -> lineNumbers: (line) ->
return ([0, 0]) unless line.children().length return ([0, 0]) unless line.children().length
lines = line.children().slice(0, 2) lines = line.children().slice(0, 2)
......
...@@ -26,7 +26,7 @@ class Dispatcher ...@@ -26,7 +26,7 @@ class Dispatcher
new ZenMode() new ZenMode()
when 'projects:milestones:show' when 'projects:milestones:show'
new Milestone() new Milestone()
when 'projects:milestones:new' when 'projects:milestones:new', 'projects:milestones:edit'
new ZenMode() new ZenMode()
when 'projects:issues:new','projects:issues:edit' when 'projects:issues:new','projects:issues:edit'
GitLab.GfmAutoComplete.setup() GitLab.GfmAutoComplete.setup()
...@@ -54,6 +54,7 @@ class Dispatcher ...@@ -54,6 +54,7 @@ class Dispatcher
when 'projects:commit:show' when 'projects:commit:show'
new Commit() new Commit()
new Diff() new Diff()
new ZenMode()
shortcut_handler = new ShortcutsNavigation() shortcut_handler = new ShortcutsNavigation()
when 'projects:commits:show' when 'projects:commits:show'
shortcut_handler = new ShortcutsNavigation() shortcut_handler = new ShortcutsNavigation()
......
...@@ -47,7 +47,7 @@ ...@@ -47,7 +47,7 @@
border-left: 3px solid $style_color; border-left: 3px solid $style_color;
&.no-highlight { &.no-highlight {
background: none; background: none !important;
border: none; border: none;
} }
......
...@@ -111,6 +111,8 @@ ...@@ -111,6 +111,8 @@
color: $link_color; color: $link_color;
&.active { &.active {
background-color: #f5f5f5;
border: 1px solid rgba(0,0,0,0.195);
color: #333; color: #333;
font-weight: bold; font-weight: bold;
} }
......
...@@ -120,13 +120,13 @@ ...@@ -120,13 +120,13 @@
} }
.readme-holder { .readme-holder {
border-top: 1px dashed #CCC;
padding-top: 10px;
.readme-file-title { .readme-file-title {
font-size: 14px; font-size: 14px;
font-weight: bold;
margin-bottom: 20px; margin-bottom: 20px;
color: #777; color: #777;
border-bottom: 1px solid #DDD;
padding: 10px 0;
} }
} }
......
class FilesController < ApplicationController class FilesController < ApplicationController
skip_before_filter :authenticate_user!, :reject_blocked
def download def download
note = Note.find(params[:id]) note = Note.find(params[:id])
uploader = note.attachment uploader = note.attachment
......
class UploadsController < ApplicationController class UploadsController < ApplicationController
skip_before_filter :authenticate_user!, :reject_blocked
before_filter :authorize_access
def show def show
model = params[:model].camelize.constantize.find(params[:id]) model = params[:model].camelize.constantize.find(params[:id])
uploader = model.send(params[:mounted_as]) uploader = model.send(params[:mounted_as])
...@@ -14,4 +17,10 @@ class UploadsController < ApplicationController ...@@ -14,4 +17,10 @@ class UploadsController < ApplicationController
redirect_to uploader.url redirect_to uploader.url
end end
end end
def authorize_access
unless params[:mounted_as] == 'avatar'
authenticate_user! && reject_blocked
end
end
end end
...@@ -27,14 +27,20 @@ class GitlabIssueTrackerService < IssueTrackerService ...@@ -27,14 +27,20 @@ class GitlabIssueTrackerService < IssueTrackerService
end end
def project_url def project_url
namespace_project_issues_path(project.namespace, project) "#{gitlab_url}#{namespace_project_issues_path(project.namespace, project)}"
end end
def new_issue_url def new_issue_url
new_namespace_project_issue_path namespace_id: project.namespace, project_id: project "#{gitlab_url}#{new_namespace_project_issue_path(namespace_id: project.namespace, project_id: project)}"
end end
def issue_url(iid) def issue_url(iid)
"#{Gitlab.config.gitlab.url}#{namespace_project_issue_path(namespace_id: project.namespace, project_id: project, id: iid)}" "#{gitlab_url}#{namespace_project_issue_path(namespace_id: project.namespace, project_id: project, id: iid)}"
end
private
def gitlab_url
Gitlab.config.gitlab.relative_url_root.chomp("/") if Gitlab.config.gitlab.relative_url_root
end end
end end
...@@ -45,6 +45,7 @@ ...@@ -45,6 +45,7 @@
# last_credential_check_at :datetime # last_credential_check_at :datetime
# github_access_token :string(255) # github_access_token :string(255)
# notification_email :string(255) # notification_email :string(255)
# password_automatically_set :boolean default(FALSE)
# #
require 'carrierwave/orm/activerecord' require 'carrierwave/orm/activerecord'
...@@ -350,6 +351,10 @@ class User < ActiveRecord::Base ...@@ -350,6 +351,10 @@ class User < ActiveRecord::Base
keys.count == 0 keys.count == 0
end end
def require_password?
password_automatically_set? && !ldap_user?
end
def can_change_username? def can_change_username?
gitlab_config.username_changing_enabled gitlab_config.username_changing_enabled
end end
......
...@@ -37,11 +37,14 @@ class BaseService ...@@ -37,11 +37,14 @@ class BaseService
private private
def error(message) def error(message, http_status = nil)
{ result = {
message: message, message: message,
status: :error status: :error
} }
result[:http_status] = http_status if http_status
result
end end
def success def success
......
...@@ -20,17 +20,19 @@ module Files ...@@ -20,17 +20,19 @@ module Files
end end
edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, project, ref, path) edit_file_action = Gitlab::Satellite::EditFileAction.new(current_user, project, ref, path)
created_successfully = edit_file_action.commit!( edit_file_action.commit!(
params[:content], params[:content],
params[:commit_message], params[:commit_message],
params[:encoding] params[:encoding]
) )
if created_successfully
success success
else rescue Gitlab::Satellite::CheckoutFailed => ex
error("Your changes could not be committed. Maybe the file was changed by another process or there was nothing to commit?") error("Your changes could not be committed because ref '#{ref}' could not be checked out", 400)
end rescue Gitlab::Satellite::CommitFailed => ex
error("Your changes could not be committed. Maybe there was nothing to commit?", 409)
rescue Gitlab::Satellite::PushFailed => ex
error("Your changes could not be committed. Maybe the file was changed by another process?", 409)
end end
end end
end end
...@@ -53,7 +53,7 @@ module MergeRequests ...@@ -53,7 +53,7 @@ module MergeRequests
if merge_request.source_branch == @branch_name || force_push? if merge_request.source_branch == @branch_name || force_push?
merge_request.reload_code merge_request.reload_code
merge_request.mark_as_unchecked update_merge_request(merge_request)
else else
mr_commit_ids = merge_request.commits.map(&:id) mr_commit_ids = merge_request.commits.map(&:id)
push_commit_ids = @commits.map(&:id) push_commit_ids = @commits.map(&:id)
...@@ -61,14 +61,20 @@ module MergeRequests ...@@ -61,14 +61,20 @@ module MergeRequests
if matches.any? if matches.any?
merge_request.reload_code merge_request.reload_code
merge_request.mark_as_unchecked update_merge_request(merge_request)
else else
merge_request.mark_as_unchecked update_merge_request(merge_request)
end end
end end
end end
end end
def update_merge_request(merge_request)
MergeRequests::UpdateService.new(
merge_request.target_project,
@current_user, merge_status: 'unchecked').execute(merge_request)
end
# Add comment about pushing new commits to merge requests # Add comment about pushing new commits to merge requests
def comment_mr_with_commits def comment_mr_with_commits
merge_requests = @project.origin_merge_requests.opened.where(source_branch: @branch_name).to_a merge_requests = @project.origin_merge_requests.opened.where(source_branch: @branch_name).to_a
......
...@@ -42,7 +42,7 @@ ...@@ -42,7 +42,7 @@
= link_to destroy_user_session_path, class: "logout", method: :delete, title: "Logout", class: 'has_bottom_tooltip', 'data-original-title' => 'Logout' do = link_to destroy_user_session_path, class: "logout", method: :delete, title: "Logout", class: 'has_bottom_tooltip', 'data-original-title' => 'Logout' do
%i.fa.fa-sign-out %i.fa.fa-sign-out
%li.hidden-xs %li.hidden-xs
= link_to current_user, class: "profile-pic", id: 'profile-pic' do = link_to current_user, class: "profile-pic has_bottom_tooltip", id: 'profile-pic', 'data-original-title' => 'Your profile' do
= image_tag avatar_icon(current_user.email, 60), alt: 'User activity' = image_tag avatar_icon(current_user.email, 60), alt: 'User activity'
= render 'shared/outdated_browser' = render 'shared/outdated_browser'
...@@ -6,12 +6,7 @@ ...@@ -6,12 +6,7 @@
%span %span
Back to project Back to project
= nav_link(html_options: {class: "#{project_tab_class} separate-item"}) do %li.separate-item
= link_to edit_namespace_project_path(@project.namespace, @project), title: 'Settings', class: "stat-tab tab no-highlight" do
%i.fa.fa-cogs
%span
Settings
%i.fa.fa-angle-down
= render 'projects/settings_nav' = render 'projects/settings_nav'
...@@ -98,4 +93,3 @@ ...@@ -98,4 +93,3 @@
%i.fa.fa-cogs %i.fa.fa-cogs
%span %span
Settings Settings
%i.fa.fa-angle-down
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
:"data-container" => "body"} :"data-container" => "body"}
SSH SSH
%button{ | %button{ |
class: "btn #{ 'active' if default_clone_protocol == 'http' }#{ ' has_tooltip' if current_user && current_user.password_automatically_set? }", | class: "btn #{ 'active' if default_clone_protocol == 'http' }#{ ' has_tooltip' if current_user && current_user.require_password? }", |
:"data-clone" => project.http_url_to_repo, | :"data-clone" => project.http_url_to_repo, |
:"data-title" => "Set a password on your account<br> to pull or push via #{gitlab_config.protocol.upcase}", :"data-title" => "Set a password on your account<br> to pull or push via #{gitlab_config.protocol.upcase}",
:"data-html" => "true", :"data-html" => "true",
......
- if cookies[:hide_no_password_message].blank? && !current_user.hide_no_password && current_user.password_automatically_set? - if cookies[:hide_no_password_message].blank? && !current_user.hide_no_password && current_user.require_password?
.no-password-message.alert.alert-warning.hidden-xs .no-password-message.alert.alert-warning.hidden-xs
You won't be able to pull or push project code via #{gitlab_config.protocol.upcase} until you #{link_to 'set a password', edit_profile_password_path} on your account You won't be able to pull or push project code via #{gitlab_config.protocol.upcase} until you #{link_to 'set a password', edit_profile_password_path} on your account
......
...@@ -5,7 +5,7 @@ Gitlab::Application.configure do ...@@ -5,7 +5,7 @@ Gitlab::Application.configure do
# test suite. You never need to work with it otherwise. Remember that # test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped # your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there! # and recreated between test runs. Don't rely on the data there!
config.cache_classes = true config.cache_classes = false
# Configure static asset server for tests with Cache-Control for performance # Configure static asset server for tests with Cache-Control for performance
config.serve_static_assets = true config.serve_static_assets = true
......
...@@ -86,9 +86,9 @@ Gitlab::Application.routes.draw do ...@@ -86,9 +86,9 @@ Gitlab::Application.routes.draw do
constraints: { model: /note|user|group|project/, mounted_as: /avatar|attachment/, filename: /.+/ } constraints: { model: /note|user|group|project/, mounted_as: /avatar|attachment/, filename: /.+/ }
# Project markdown uploads # Project markdown uploads
get ":id/:secret/:filename", get ":namespace_id/:id/:secret/:filename",
to: "projects/uploads#show", to: "projects/uploads#show",
constraints: { id: /[a-zA-Z.0-9_\-]+\/[a-zA-Z.0-9_\-]+/, filename: /.+/ } constraints: { namespace_id: /[a-zA-Z.0-9_\-]+/, id: /[a-zA-Z.0-9_\-]+/, filename: /.+/ }
end end
# #
...@@ -148,7 +148,8 @@ Gitlab::Application.routes.draw do ...@@ -148,7 +148,8 @@ Gitlab::Application.routes.draw do
resources :namespaces, path: '/projects', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: [] do resources :namespaces, path: '/projects', constraints: { id: /[a-zA-Z.0-9_\-]+/ }, only: [] do
root to: 'projects#index', as: :projects root to: 'projects#index', as: :projects
resources(:projects, path: '/', resources(:projects,
path: '/',
constraints: { id: /[a-zA-Z.0-9_\-]+/ }, constraints: { id: /[a-zA-Z.0-9_\-]+/ },
only: [:index, :show]) do only: [:index, :show]) do
root to: 'projects#show' root to: 'projects#show'
...@@ -268,13 +269,23 @@ Gitlab::Application.routes.draw do ...@@ -268,13 +269,23 @@ Gitlab::Application.routes.draw do
post '/preview/*id', to: 'blob#preview', constraints: { id: /.+/ }, as: 'preview_blob' post '/preview/*id', to: 'blob#preview', constraints: { id: /.+/ }, as: 'preview_blob'
scope do scope do
get('/blob/*id/diff', to: 'blob#diff', get(
'/blob/*id/diff',
to: 'blob#diff',
constraints: { id: /.+/, format: false },
as: :blob_diff
)
get(
'/blob/*id',
to: 'blob#show',
constraints: { id: /.+/, format: false }, constraints: { id: /.+/, format: false },
as: :blob_diff) as: :blob
get('/blob/*id', to: 'blob#show', )
constraints: { id: /.+/, format: false }, as: :blob) delete(
delete('/blob/*id', to: 'blob#destroy', '/blob/*id',
constraints: { id: /.+/, format: false }) to: 'blob#destroy',
constraints: { id: /.+/, format: false }
)
end end
scope do scope do
......
class SerializeServiceProperties < ActiveRecord::Migration class SerializeServiceProperties < ActiveRecord::Migration
def change def change
unless column_exists?(:services, :properties)
add_column :services, :properties, :text add_column :services, :properties, :text
end
Service.reset_column_information Service.reset_column_information
associations = associations =
...@@ -19,13 +22,15 @@ class SerializeServiceProperties < ActiveRecord::Migration ...@@ -19,13 +22,15 @@ class SerializeServiceProperties < ActiveRecord::Migration
:api_version, :jira_issue_transition_id], :api_version, :jira_issue_transition_id],
} }
Service.all.each do |service| Service.find_each(batch_size: 500).each do |service|
associations[service.type.to_sym].each do |attribute| associations[service.type.to_sym].each do |attribute|
service.send("#{attribute}=", service.attributes[attribute.to_s]) service.send("#{attribute}=", service.attributes[attribute.to_s])
end end
service.save
service.save(validate: false)
end end
if column_exists?(:services, :project_url)
remove_column :services, :project_url, :string remove_column :services, :project_url, :string
remove_column :services, :subdomain, :string remove_column :services, :subdomain, :string
remove_column :services, :room, :string remove_column :services, :room, :string
...@@ -33,4 +38,5 @@ class SerializeServiceProperties < ActiveRecord::Migration ...@@ -33,4 +38,5 @@ class SerializeServiceProperties < ActiveRecord::Migration
remove_column :services, :api_key, :string remove_column :services, :api_key, :string
remove_column :services, :token, :string remove_column :services, :token, :string
end end
end
end end
...@@ -280,7 +280,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da ...@@ -280,7 +280,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
GitLab Shell is an SSH access and repository management software developed specially for GitLab. GitLab Shell is an SSH access and repository management software developed specially for GitLab.
# Run the installation task for gitlab-shell (replace `REDIS_URL` if needed): # Run the installation task for gitlab-shell (replace `REDIS_URL` if needed):
sudo -u git -H bundle exec rake gitlab:shell:install[v2.4.3] REDIS_URL=unix:/var/run/redis/redis.sock RAILS_ENV=production sudo -u git -H bundle exec rake gitlab:shell:install[v2.5.4] REDIS_URL=unix:/var/run/redis/redis.sock RAILS_ENV=production
# By default, the gitlab-shell config is generated from your main GitLab config. # By default, the gitlab-shell config is generated from your main GitLab config.
# You can review (and modify) the gitlab-shell config as follows: # You can review (and modify) the gitlab-shell config as follows:
......
...@@ -123,7 +123,7 @@ sudo apt-get install libkrb5-dev ...@@ -123,7 +123,7 @@ sudo apt-get install libkrb5-dev
```bash ```bash
cd /home/git/gitlab-shell cd /home/git/gitlab-shell
sudo -u git -H git fetch sudo -u git -H git fetch
sudo -u git -H git checkout v2.4.3 sudo -u git -H git checkout v2.5.4
``` ```
## 7. Install libs, migrations, etc. ## 7. Install libs, migrations, etc.
...@@ -163,7 +163,7 @@ git diff 6-0-stable:config/gitlab.yml.example 7-8-stable:config/gitlab.yml.examp ...@@ -163,7 +163,7 @@ git diff 6-0-stable:config/gitlab.yml.example 7-8-stable:config/gitlab.yml.examp
* Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-8-stable/config/gitlab.yml.example but with your settings. * Make `/home/git/gitlab/config/gitlab.yml` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-8-stable/config/gitlab.yml.example but with your settings.
* Make `/home/git/gitlab/config/unicorn.rb` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-8-stable/config/unicorn.rb.example but with your settings. * Make `/home/git/gitlab/config/unicorn.rb` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-8-stable/config/unicorn.rb.example but with your settings.
* Make `/home/git/gitlab-shell/config.yml` the same as https://gitlab.com/gitlab-org/gitlab-shell/blob/v2.4.3/config.yml.example but with your settings. * Make `/home/git/gitlab-shell/config.yml` the same as https://gitlab.com/gitlab-org/gitlab-shell/blob/v2.5.4/config.yml.example but with your settings.
* Copy rack attack middleware config * Copy rack attack middleware config
```bash ```bash
...@@ -179,7 +179,7 @@ sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab ...@@ -179,7 +179,7 @@ sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab
### Change Nginx settings ### Change Nginx settings
* HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-8-stable/lib/support/nginx/gitlab but with your settings. * HTTP setups: Make `/etc/nginx/sites-available/gitlab` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-8-stable/lib/support/nginx/gitlab but with your settings.
* HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-8-stablef/lib/support/nginx/gitlab-ssl but with your settings. * HTTPS setups: Make `/etc/nginx/sites-available/gitlab-ssl` the same as https://gitlab.com/gitlab-org/gitlab-ce/blob/7-8-stable/lib/support/nginx/gitlab-ssl but with your settings.
* A new `location /uploads/` section has been added that needs to have the same content as the existing `location @gitlab` section. * A new `location /uploads/` section has been added that needs to have the same content as the existing `location @gitlab` section.
## 9. Start application ## 9. Start application
......
...@@ -37,7 +37,7 @@ sudo -u git -H git checkout 7-8-stable-ee ...@@ -37,7 +37,7 @@ sudo -u git -H git checkout 7-8-stable-ee
```bash ```bash
cd /home/git/gitlab-shell cd /home/git/gitlab-shell
sudo -u git -H git fetch sudo -u git -H git fetch
sudo -u git -H git checkout v2.5.3 sudo -u git -H git checkout v2.5.4
``` ```
### 4. Install libs, migrations, etc. ### 4. Install libs, migrations, etc.
......
...@@ -41,6 +41,8 @@ module SharedProjectTab ...@@ -41,6 +41,8 @@ module SharedProjectTab
end end
step 'the active main tab should be Settings' do step 'the active main tab should be Settings' do
ensure_active_main_tab('Settings') within '.nav-sidebar' do
page.should have_content('Back to project')
end
end end
end end
...@@ -117,7 +117,8 @@ module API ...@@ -117,7 +117,8 @@ module API
branch_name: branch_name branch_name: branch_name
} }
else else
render_api_error!(result[:message], 400) http_status = result[:http_status] || 400
render_api_error!(result[:message], http_status)
end end
end end
......
...@@ -15,7 +15,11 @@ module Gitlab ...@@ -15,7 +15,11 @@ module Gitlab
prepare_satellite!(repo) prepare_satellite!(repo)
# create target branch in satellite at the corresponding commit from bare repo # create target branch in satellite at the corresponding commit from bare repo
begin
repo.git.checkout({ raise: true, timeout: true, b: true }, ref, "origin/#{ref}") repo.git.checkout({ raise: true, timeout: true, b: true }, ref, "origin/#{ref}")
rescue Grit::Git::CommandFailed => ex
log_and_raise(CheckoutFailed, ex.message)
end
# update the file in the satellite's working dir # update the file in the satellite's working dir
file_path_in_satellite = File.join(repo.working_dir, file_path) file_path_in_satellite = File.join(repo.working_dir, file_path)
...@@ -31,19 +35,31 @@ module Gitlab ...@@ -31,19 +35,31 @@ module Gitlab
# commit the changes # commit the changes
# will raise CommandFailed when commit fails # will raise CommandFailed when commit fails
begin
repo.git.commit(raise: true, timeout: true, a: true, m: commit_message) repo.git.commit(raise: true, timeout: true, a: true, m: commit_message)
rescue Grit::Git::CommandFailed => ex
log_and_raise(CommitFailed, ex.message)
end
# push commit back to bare repo # push commit back to bare repo
# will raise CommandFailed when push fails # will raise CommandFailed when push fails
begin
repo.git.push({ raise: true, timeout: true }, :origin, ref) repo.git.push({ raise: true, timeout: true }, :origin, ref)
rescue Grit::Git::CommandFailed => ex
log_and_raise(PushFailed, ex.message)
end
# everything worked # everything worked
true true
end end
rescue Grit::Git::CommandFailed => ex end
Gitlab::GitLogger.error(ex.message)
false private
def log_and_raise(errorClass, message)
Gitlab::GitLogger.error(message)
raise(errorClass, message)
end end
end end
end end
......
module Gitlab module Gitlab
module Satellite module Satellite
class CheckoutFailed < StandardError; end
class CommitFailed < StandardError; end
class PushFailed < StandardError; end
class Satellite class Satellite
include Gitlab::Popen include Gitlab::Popen
......
...@@ -474,7 +474,7 @@ describe GitlabMarkdownHelper do ...@@ -474,7 +474,7 @@ describe GitlabMarkdownHelper do
# First issue link # First issue link
expect(groups[1]). expect(groups[1]).
to match(/href="#{namespace_project_issue_url(project.namespace, project, issues[0])}"/) to match(/href="#{namespace_project_issue_path(project.namespace, project, issues[0])}"/)
expect(groups[1]).to match(/##{issues[0].iid}$/) expect(groups[1]).to match(/##{issues[0].iid}$/)
# Internal commit link # Internal commit link
...@@ -483,7 +483,7 @@ describe GitlabMarkdownHelper do ...@@ -483,7 +483,7 @@ describe GitlabMarkdownHelper do
# Second issue link # Second issue link
expect(groups[3]). expect(groups[3]).
to match(/href="#{namespace_project_issue_url(project.namespace, project, issues[1])}"/) to match(/href="#{namespace_project_issue_path(project.namespace, project, issues[1])}"/)
expect(groups[3]).to match(/##{issues[1].iid}$/) expect(groups[3]).to match(/##{issues[1].iid}$/)
# Trailing commit link # Trailing commit link
...@@ -611,7 +611,7 @@ describe GitlabMarkdownHelper do ...@@ -611,7 +611,7 @@ describe GitlabMarkdownHelper do
end end
it "should generate absolute urls for refs" do it "should generate absolute urls for refs" do
expect(markdown("##{issue.iid}")).to include(namespace_project_issue_url(project.namespace, project, issue)) expect(markdown("##{issue.iid}")).to include(namespace_project_issue_path(project.namespace, project, issue))
end end
it "should generate absolute urls for emoji" do it "should generate absolute urls for emoji" do
......
# == Schema Information
#
# Table name: services
#
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# project_id :integer
# created_at :datetime
# updated_at :datetime
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
#
require 'spec_helper'
describe GitlabIssueTrackerService do
describe "Associations" do
it { is_expected.to belong_to :project }
it { is_expected.to have_one :service_hook }
end
describe 'project and issue urls' do
let(:project) { create(:project) }
context 'with absolute urls' do
before do
@service = project.create_gitlab_issue_tracker_service(active: true)
end
after do
@service.destroy!
end
it 'should give the correct path' do
expect(@service.project_url).to eq("/#{project.path_with_namespace}/issues")
expect(@service.new_issue_url).to eq("/#{project.path_with_namespace}/issues/new")
expect(@service.issue_url(432)).to eq("/#{project.path_with_namespace}/issues/432")
end
end
context 'with enabled relative urls' do
before do
Settings.gitlab.stub(:relative_url_root).and_return("/gitlab/root")
@service = project.create_gitlab_issue_tracker_service(active: true)
end
after do
@service.destroy!
end
it 'should give the correct path' do
expect(@service.project_url).to eq("/gitlab/root/#{project.path_with_namespace}/issues")
expect(@service.new_issue_url).to eq("/gitlab/root/#{project.path_with_namespace}/issues/new")
expect(@service.issue_url(432)).to eq("/gitlab/root/#{project.path_with_namespace}/issues/432")
end
end
end
end
...@@ -98,13 +98,33 @@ describe API::API, api: true do ...@@ -98,13 +98,33 @@ describe API::API, api: true do
expect(response.status).to eq(400) expect(response.status).to eq(400)
end end
it "should return a 400 if satellite fails to create file" do it 'should return a 400 if the checkout fails' do
Gitlab::Satellite::EditFileAction.any_instance.stub( Gitlab::Satellite::EditFileAction.any_instance.stub(:commit!)
commit!: false, .and_raise(Gitlab::Satellite::CheckoutFailed)
)
put api("/projects/#{project.id}/repository/files", user), valid_params put api("/projects/#{project.id}/repository/files", user), valid_params
expect(response.status).to eq(400) expect(response.status).to eq(400)
ref = valid_params[:branch_name]
expect(response.body).to match("ref '#{ref}' could not be checked out")
end
it 'should return a 409 if the file was not modified' do
Gitlab::Satellite::EditFileAction.any_instance.stub(:commit!)
.and_raise(Gitlab::Satellite::CommitFailed)
put api("/projects/#{project.id}/repository/files", user), valid_params
expect(response.status).to eq(409)
expect(response.body).to match("Maybe there was nothing to commit?")
end
it 'should return a 409 if the push fails' do
Gitlab::Satellite::EditFileAction.any_instance.stub(:commit!)
.and_raise(Gitlab::Satellite::PushFailed)
put api("/projects/#{project.id}/repository/files", user), valid_params
expect(response.status).to eq(409)
expect(response.body).to match("Maybe the file was changed by another process?")
end end
end end
......
/*
Sticky-kit v1.1.1 | WTFPL | Leaf Corcoran 2014 | http://leafo.net
*/
(function(){var k,e;k=this.jQuery||window.jQuery;e=k(window);k.fn.stick_in_parent=function(d){var v,y,n,p,h,C,s,G,q,H;null==d&&(d={});s=d.sticky_class;y=d.inner_scrolling;C=d.recalc_every;h=d.parent;p=d.offset_top;n=d.spacer;v=d.bottoming;null==p&&(p=0);null==h&&(h=void 0);null==y&&(y=!0);null==s&&(s="is_stuck");null==v&&(v=!0);G=function(a,d,q,z,D,t,r,E){var u,F,m,A,c,f,B,w,x,g,b;if(!a.data("sticky_kit")){a.data("sticky_kit",!0);f=a.parent();null!=h&&(f=f.closest(h));if(!f.length)throw"failed to find stick parent";
u=m=!1;(g=null!=n?n&&a.closest(n):k("<div />"))&&g.css("position",a.css("position"));B=function(){var c,e,l;if(!E&&(c=parseInt(f.css("border-top-width"),10),e=parseInt(f.css("padding-top"),10),d=parseInt(f.css("padding-bottom"),10),q=f.offset().top+c+e,z=f.height(),m&&(u=m=!1,null==n&&(a.insertAfter(g),g.detach()),a.css({position:"",top:"",width:"",bottom:""}).removeClass(s),l=!0),D=a.offset().top-parseInt(a.css("margin-top"),10)-p,t=a.outerHeight(!0),r=a.css("float"),g&&g.css({width:a.outerWidth(!0),
height:t,display:a.css("display"),"vertical-align":a.css("vertical-align"),"float":r}),l))return b()};B();if(t!==z)return A=void 0,c=p,x=C,b=function(){var b,k,l,h;if(!E&&(null!=x&&(--x,0>=x&&(x=C,B())),l=e.scrollTop(),null!=A&&(k=l-A),A=l,m?(v&&(h=l+t+c>z+q,u&&!h&&(u=!1,a.css({position:"fixed",bottom:"",top:c}).trigger("sticky_kit:unbottom"))),l<D&&(m=!1,c=p,null==n&&("left"!==r&&"right"!==r||a.insertAfter(g),g.detach()),b={position:"",width:"",top:""},a.css(b).removeClass(s).trigger("sticky_kit:unstick")),
y&&(b=e.height(),t+p>b&&!u&&(c-=k,c=Math.max(b-t,c),c=Math.min(p,c),m&&a.css({top:c+"px"})))):l>D&&(m=!0,b={position:"fixed",top:c},b.width="border-box"===a.css("box-sizing")?a.outerWidth()+"px":a.width()+"px",a.css(b).addClass(s),null==n&&(a.after(g),"left"!==r&&"right"!==r||g.append(a)),a.trigger("sticky_kit:stick")),m&&v&&(null==h&&(h=l+t+c>z+q),!u&&h)))return u=!0,"static"===f.css("position")&&f.css({position:"relative"}),a.css({position:"absolute",bottom:d,top:"auto"}).trigger("sticky_kit:bottom")},
w=function(){B();return b()},F=function(){E=!0;e.off("touchmove",b);e.off("scroll",b);e.off("resize",w);k(document.body).off("sticky_kit:recalc",w);a.off("sticky_kit:detach",F);a.removeData("sticky_kit");a.css({position:"",bottom:"",top:"",width:""});f.position("position","");if(m)return null==n&&("left"!==r&&"right"!==r||a.insertAfter(g),g.remove()),a.removeClass(s)},e.on("touchmove",b),e.on("scroll",b),e.on("resize",w),k(document.body).on("sticky_kit:recalc",w),a.on("sticky_kit:detach",F),setTimeout(b,
0)}};q=0;for(H=this.length;q<H;q++)d=this[q],G(k(d));return this}}).call(this);
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