diff --git a/CHANGELOG b/CHANGELOG
index 6702ba2ba4..deda7ffc32 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,8 +1,12 @@
+Please view this file on the master branch, on stable branches it's out of date.
+
v 7.9.0 (unreleased)
- Move labels/milestones tabs to sidebar
- Upgrade Rails gem to version 4.1.9.
+ - Improve error messages for file edit failures
- Improve UI for commits, issues and merge request lists
- 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
- Fix access control and protection against XSS for note attachments and other uploads.
diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION
index aedc15bb0c..fe16b348d9 100644
--- a/GITLAB_SHELL_VERSION
+++ b/GITLAB_SHELL_VERSION
@@ -1 +1 @@
-2.5.3
+2.5.4
diff --git a/Gemfile b/Gemfile
index 233b8c8cd7..093f7bacc0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -247,8 +247,8 @@ group :development, :test do
gem 'jasmine', '2.0.2'
- gem "spring", '1.1.3'
- gem "spring-commands-rspec", '1.0.1'
+ gem "spring", '1.3.1'
+ gem "spring-commands-rspec", '1.0.4'
gem "spring-commands-spinach", '1.0.0'
end
diff --git a/Gemfile.lock b/Gemfile.lock
index 34dd709d6b..4bc47836e7 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -78,7 +78,7 @@ GEM
json (>= 1.7)
celluloid (0.16.0)
timers (~> 4.0.0)
- charlock_holmes (0.6.9.4)
+ charlock_holmes (0.7.3)
cliver (0.3.2)
coderay (1.1.0)
coercible (1.0.0)
@@ -543,8 +543,8 @@ GEM
capybara (>= 2.0.0)
railties (>= 3)
spinach (>= 0.4)
- spring (1.1.3)
- spring-commands-rspec (1.0.1)
+ spring (1.3.1)
+ spring-commands-rspec (1.0.4)
spring (>= 0.9.1)
spring-commands-spinach (1.0.0)
spring (>= 0.9.1)
@@ -742,8 +742,8 @@ DEPENDENCIES
slack-notifier (~> 1.0.0)
slim
spinach-rails
- spring (= 1.1.3)
- spring-commands-rspec (= 1.0.1)
+ spring (= 1.3.1)
+ spring-commands-rspec (= 1.0.4)
spring-commands-spinach (= 1.0.0)
stamp
state_machine
diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee
index e9042b5641..c7acde2afe 100644
--- a/app/assets/javascripts/application.js.coffee
+++ b/app/assets/javascripts/application.js.coffee
@@ -16,6 +16,7 @@
#= require jquery.scrollTo
#= require jquery.blockUI
#= require jquery.turbolinks
+#= require jquery.sticky-kit.min
#= require turbolinks
#= require autosave
#= require bootstrap
diff --git a/app/assets/javascripts/diff.js.coffee b/app/assets/javascripts/diff.js.coffee
index 52b4208524..b0b312e774 100644
--- a/app/assets/javascripts/diff.js.coffee
+++ b/app/assets/javascripts/diff.js.coffee
@@ -36,6 +36,8 @@ class @Diff
)
)
+ $('.diff-header').stick_in_parent(offset_top: $('.navbar').height())
+
lineNumbers: (line) ->
return ([0, 0]) unless line.children().length
lines = line.children().slice(0, 2)
diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee
index 1643ca941f..ed1bdd6ca3 100644
--- a/app/assets/javascripts/dispatcher.js.coffee
+++ b/app/assets/javascripts/dispatcher.js.coffee
@@ -26,7 +26,7 @@ class Dispatcher
new ZenMode()
when 'projects:milestones:show'
new Milestone()
- when 'projects:milestones:new'
+ when 'projects:milestones:new', 'projects:milestones:edit'
new ZenMode()
when 'projects:issues:new','projects:issues:edit'
GitLab.GfmAutoComplete.setup()
@@ -54,6 +54,7 @@ class Dispatcher
when 'projects:commit:show'
new Commit()
new Diff()
+ new ZenMode()
shortcut_handler = new ShortcutsNavigation()
when 'projects:commits:show'
shortcut_handler = new ShortcutsNavigation()
diff --git a/app/assets/stylesheets/sections/nav_sidebar.scss b/app/assets/stylesheets/sections/nav_sidebar.scss
index 17923ca499..8e02b37507 100644
--- a/app/assets/stylesheets/sections/nav_sidebar.scss
+++ b/app/assets/stylesheets/sections/nav_sidebar.scss
@@ -47,7 +47,7 @@
border-left: 3px solid $style_color;
&.no-highlight {
- background: none;
+ background: none !important;
border: none;
}
diff --git a/app/assets/stylesheets/sections/tree.scss b/app/assets/stylesheets/sections/tree.scss
index ff9464e217..60a1c00b04 100644
--- a/app/assets/stylesheets/sections/tree.scss
+++ b/app/assets/stylesheets/sections/tree.scss
@@ -120,13 +120,13 @@
}
.readme-holder {
- border-top: 1px dashed #CCC;
- padding-top: 10px;
-
.readme-file-title {
font-size: 14px;
+ font-weight: bold;
margin-bottom: 20px;
color: #777;
+ border-bottom: 1px solid #DDD;
+ padding: 10px 0;
}
}
diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb
index 9671245d3f..a130bcba9c 100644
--- a/app/controllers/files_controller.rb
+++ b/app/controllers/files_controller.rb
@@ -1,4 +1,6 @@
class FilesController < ApplicationController
+ skip_before_filter :authenticate_user!, :reject_blocked
+
def download
note = Note.find(params[:id])
uploader = note.attachment
diff --git a/app/controllers/uploads_controller.rb b/app/controllers/uploads_controller.rb
index d587797725..73b124bb34 100644
--- a/app/controllers/uploads_controller.rb
+++ b/app/controllers/uploads_controller.rb
@@ -1,4 +1,7 @@
class UploadsController < ApplicationController
+ skip_before_filter :authenticate_user!, :reject_blocked
+ before_filter :authorize_access
+
def show
model = params[:model].camelize.constantize.find(params[:id])
uploader = model.send(params[:mounted_as])
@@ -14,4 +17,10 @@ class UploadsController < ApplicationController
redirect_to uploader.url
end
end
+
+ def authorize_access
+ unless params[:mounted_as] == 'avatar'
+ authenticate_user! && reject_blocked
+ end
+ end
end
diff --git a/app/models/project_services/gitlab_issue_tracker_service.rb b/app/models/project_services/gitlab_issue_tracker_service.rb
index 782cf42ce5..05c048e4e4 100644
--- a/app/models/project_services/gitlab_issue_tracker_service.rb
+++ b/app/models/project_services/gitlab_issue_tracker_service.rb
@@ -27,14 +27,20 @@ class GitlabIssueTrackerService < IssueTrackerService
end
def project_url
- namespace_project_issues_path(project.namespace, project)
+ "#{gitlab_url}#{namespace_project_issues_path(project.namespace, project)}"
end
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
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
diff --git a/app/models/user.rb b/app/models/user.rb
index 21ccc76978..08ad619a90 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -45,6 +45,7 @@
# last_credential_check_at :datetime
# github_access_token :string(255)
# notification_email :string(255)
+# password_automatically_set :boolean default(FALSE)
#
require 'carrierwave/orm/activerecord'
@@ -350,6 +351,10 @@ class User < ActiveRecord::Base
keys.count == 0
end
+ def require_password?
+ password_automatically_set? && !ldap_user?
+ end
+
def can_change_username?
gitlab_config.username_changing_enabled
end
diff --git a/app/services/base_service.rb b/app/services/base_service.rb
index bb51795df7..52ab29f149 100644
--- a/app/services/base_service.rb
+++ b/app/services/base_service.rb
@@ -37,11 +37,14 @@ class BaseService
private
- def error(message)
- {
+ def error(message, http_status = nil)
+ result = {
message: message,
status: :error
}
+
+ result[:http_status] = http_status if http_status
+ result
end
def success
diff --git a/app/services/files/update_service.rb b/app/services/files/update_service.rb
index b4986e1c5c..bcf0e7f3ce 100644
--- a/app/services/files/update_service.rb
+++ b/app/services/files/update_service.rb
@@ -20,17 +20,19 @@ module Files
end
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[:commit_message],
params[:encoding]
)
- if created_successfully
- success
- else
- error("Your changes could not be committed. Maybe the file was changed by another process or there was nothing to commit?")
- end
+ success
+ rescue Gitlab::Satellite::CheckoutFailed => ex
+ error("Your changes could not be committed because ref '#{ref}' could not be checked out", 400)
+ 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
diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb
index a6705de61f..96761bec99 100644
--- a/app/services/merge_requests/refresh_service.rb
+++ b/app/services/merge_requests/refresh_service.rb
@@ -53,7 +53,7 @@ module MergeRequests
if merge_request.source_branch == @branch_name || force_push?
merge_request.reload_code
- merge_request.mark_as_unchecked
+ update_merge_request(merge_request)
else
mr_commit_ids = merge_request.commits.map(&:id)
push_commit_ids = @commits.map(&:id)
@@ -61,14 +61,20 @@ module MergeRequests
if matches.any?
merge_request.reload_code
- merge_request.mark_as_unchecked
+ update_merge_request(merge_request)
else
- merge_request.mark_as_unchecked
+ update_merge_request(merge_request)
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
def comment_mr_with_commits
merge_requests = @project.origin_merge_requests.opened.where(source_branch: @branch_name).to_a
diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml
index 77bfe4f996..d5928d2ed2 100644
--- a/app/views/layouts/_head_panel.html.haml
+++ b/app/views/layouts/_head_panel.html.haml
@@ -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
%i.fa.fa-sign-out
%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'
= render 'shared/outdated_browser'
diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml
index 4d859e817a..15b489c7d9 100644
--- a/app/views/layouts/nav/_project.html.haml
+++ b/app/views/layouts/nav/_project.html.haml
@@ -6,12 +6,7 @@
%span
Back to project
- = nav_link(html_options: {class: "#{project_tab_class} separate-item"}) do
- = 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
+ %li.separate-item
= render 'projects/settings_nav'
@@ -98,4 +93,3 @@
%i.fa.fa-cogs
%span
Settings
- %i.fa.fa-angle-down
diff --git a/app/views/shared/_clone_panel.html.haml b/app/views/shared/_clone_panel.html.haml
index df0bde7698..a1121750ca 100644
--- a/app/views/shared/_clone_panel.html.haml
+++ b/app/views/shared/_clone_panel.html.haml
@@ -9,7 +9,7 @@
:"data-container" => "body"}
SSH
%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-title" => "Set a password on your account
to pull or push via #{gitlab_config.protocol.upcase}",
:"data-html" => "true",
diff --git a/app/views/shared/_no_password.html.haml b/app/views/shared/_no_password.html.haml
index 022097cda1..a43bf33751 100644
--- a/app/views/shared/_no_password.html.haml
+++ b/app/views/shared/_no_password.html.haml
@@ -1,4 +1,4 @@
-- 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
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
diff --git a/config/environments/test.rb b/config/environments/test.rb
index 25b082b98d..2d5e7addcd 100644
--- a/config/environments/test.rb
+++ b/config/environments/test.rb
@@ -5,7 +5,7 @@ Gitlab::Application.configure do
# 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
# 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
config.serve_static_assets = true
diff --git a/config/routes.rb b/config/routes.rb
index f0979eac90..ecd439aece 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -86,9 +86,9 @@ Gitlab::Application.routes.draw do
constraints: { model: /note|user|group|project/, mounted_as: /avatar|attachment/, filename: /.+/ }
# Project markdown uploads
- get ":id/:secret/:filename",
- to: "projects/uploads#show",
- constraints: { id: /[a-zA-Z.0-9_\-]+\/[a-zA-Z.0-9_\-]+/, filename: /.+/ }
+ get ":namespace_id/:id/:secret/:filename",
+ to: "projects/uploads#show",
+ constraints: { namespace_id: /[a-zA-Z.0-9_\-]+/, id: /[a-zA-Z.0-9_\-]+/, filename: /.+/ }
end
#
@@ -269,16 +269,23 @@ Gitlab::Application.routes.draw do
post '/preview/*id', to: 'blob#preview', constraints: { id: /.+/ }, as: 'preview_blob'
scope do
- get('/blob/*id/diff',
- to: 'blob#diff',
- constraints: { id: /.+/, format: false },
- as: :blob_diff)
- get('/blob/*id',
- to: 'blob#show',
- constraints: { id: /.+/, format: false }, as: :blob)
- delete('/blob/*id',
- to: 'blob#destroy',
- constraints: { id: /.+/, format: false })
+ get(
+ '/blob/*id/diff',
+ to: 'blob#diff',
+ constraints: { id: /.+/, format: false },
+ as: :blob_diff
+ )
+ get(
+ '/blob/*id',
+ to: 'blob#show',
+ constraints: { id: /.+/, format: false },
+ as: :blob
+ )
+ delete(
+ '/blob/*id',
+ to: 'blob#destroy',
+ constraints: { id: /.+/, format: false }
+ )
end
scope do
diff --git a/db/migrate/20140907220153_serialize_service_properties.rb b/db/migrate/20140907220153_serialize_service_properties.rb
index bd75ab1eac..d45a10465b 100644
--- a/db/migrate/20140907220153_serialize_service_properties.rb
+++ b/db/migrate/20140907220153_serialize_service_properties.rb
@@ -1,6 +1,9 @@
class SerializeServiceProperties < ActiveRecord::Migration
def change
- add_column :services, :properties, :text
+ unless column_exists?(:services, :properties)
+ add_column :services, :properties, :text
+ end
+
Service.reset_column_information
associations =
@@ -19,18 +22,21 @@ class SerializeServiceProperties < ActiveRecord::Migration
: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|
service.send("#{attribute}=", service.attributes[attribute.to_s])
end
- service.save
+
+ service.save(validate: false)
end
- remove_column :services, :project_url, :string
- remove_column :services, :subdomain, :string
- remove_column :services, :room, :string
- remove_column :services, :recipients, :text
- remove_column :services, :api_key, :string
- remove_column :services, :token, :string
+ if column_exists?(:services, :project_url)
+ remove_column :services, :project_url, :string
+ remove_column :services, :subdomain, :string
+ remove_column :services, :room, :string
+ remove_column :services, :recipients, :text
+ remove_column :services, :api_key, :string
+ remove_column :services, :token, :string
+ end
end
end
diff --git a/doc/install/installation.md b/doc/install/installation.md
index f5dcec2f61..28597fd39d 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -141,7 +141,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
# Try connecting to the new database with the new user
sudo -u git -H psql -d gitlabhq_production
-
+
# Quit the database session
gitlabhq_production> \q
@@ -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.
# 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.
# You can review (and modify) the gitlab-shell config as follows:
diff --git a/doc/update/6.x-or-7.x-to-7.8.md b/doc/update/6.x-or-7.x-to-7.8.md
index 859f4c1a6d..673d9253d6 100644
--- a/doc/update/6.x-or-7.x-to-7.8.md
+++ b/doc/update/6.x-or-7.x-to-7.8.md
@@ -123,7 +123,7 @@ sudo apt-get install libkrb5-dev
```bash
cd /home/git/gitlab-shell
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.
@@ -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/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
```bash
@@ -179,7 +179,7 @@ sudo cp lib/support/logrotate/gitlab /etc/logrotate.d/gitlab
### 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.
-* 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.
## 9. Start application
diff --git a/doc/update/7.7-to-7.8.md b/doc/update/7.7-to-7.8.md
index a8a5c7f66c..46ca163c1b 100644
--- a/doc/update/7.7-to-7.8.md
+++ b/doc/update/7.7-to-7.8.md
@@ -37,7 +37,7 @@ sudo -u git -H git checkout 7-8-stable-ee
```bash
cd /home/git/gitlab-shell
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.
@@ -102,7 +102,7 @@ If all items are green, then congratulations upgrade is complete!
### 8. GitHub settings (if applicable)
-If you are using GitHub as an OAuth provider for authentication, you should change the callback URL so that it
+If you are using GitHub as an OAuth provider for authentication, you should change the callback URL so that it
only contains a root URL (ex. `https://gitlab.example.com/`)
## Things went south? Revert to previous version (7.7)
diff --git a/features/steps/shared/project_tab.rb b/features/steps/shared/project_tab.rb
index 6aa4f1b20d..c5aed19331 100644
--- a/features/steps/shared/project_tab.rb
+++ b/features/steps/shared/project_tab.rb
@@ -41,6 +41,8 @@ module SharedProjectTab
end
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
diff --git a/lib/api/files.rb b/lib/api/files.rb
index e6e71bac36..3176ef0e25 100644
--- a/lib/api/files.rb
+++ b/lib/api/files.rb
@@ -117,7 +117,8 @@ module API
branch_name: branch_name
}
else
- render_api_error!(result[:message], 400)
+ http_status = result[:http_status] || 400
+ render_api_error!(result[:message], http_status)
end
end
diff --git a/lib/gitlab/satellite/files/edit_file_action.rb b/lib/gitlab/satellite/files/edit_file_action.rb
index 2834b722b2..82d71ab990 100644
--- a/lib/gitlab/satellite/files/edit_file_action.rb
+++ b/lib/gitlab/satellite/files/edit_file_action.rb
@@ -15,7 +15,11 @@ module Gitlab
prepare_satellite!(repo)
# create target branch in satellite at the corresponding commit from bare repo
- repo.git.checkout({ raise: true, timeout: true, b: true }, ref, "origin/#{ref}")
+ begin
+ 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
file_path_in_satellite = File.join(repo.working_dir, file_path)
@@ -31,19 +35,31 @@ module Gitlab
# commit the changes
# will raise CommandFailed when commit fails
- repo.git.commit(raise: true, timeout: true, a: true, m: commit_message)
+ begin
+ 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
# will raise CommandFailed when push fails
- repo.git.push({ raise: true, timeout: true }, :origin, ref)
+ begin
+ repo.git.push({ raise: true, timeout: true }, :origin, ref)
+ rescue Grit::Git::CommandFailed => ex
+ log_and_raise(PushFailed, ex.message)
+ end
# everything worked
true
end
- rescue Grit::Git::CommandFailed => ex
- Gitlab::GitLogger.error(ex.message)
- false
+ end
+
+ private
+
+ def log_and_raise(errorClass, message)
+ Gitlab::GitLogger.error(message)
+ raise(errorClass, message)
end
end
end
diff --git a/lib/gitlab/satellite/satellite.rb b/lib/gitlab/satellite/satellite.rb
index 62d1bb364d..70125d539d 100644
--- a/lib/gitlab/satellite/satellite.rb
+++ b/lib/gitlab/satellite/satellite.rb
@@ -1,5 +1,9 @@
module Gitlab
module Satellite
+ class CheckoutFailed < StandardError; end
+ class CommitFailed < StandardError; end
+ class PushFailed < StandardError; end
+
class Satellite
include Gitlab::Popen
diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb
index 68269ad25a..76fcf888a6 100644
--- a/spec/helpers/gitlab_markdown_helper_spec.rb
+++ b/spec/helpers/gitlab_markdown_helper_spec.rb
@@ -474,7 +474,7 @@ describe GitlabMarkdownHelper do
# First issue link
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}$/)
# Internal commit link
@@ -483,7 +483,7 @@ describe GitlabMarkdownHelper do
# Second issue link
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}$/)
# Trailing commit link
@@ -611,7 +611,7 @@ describe GitlabMarkdownHelper do
end
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
it "should generate absolute urls for emoji" do
diff --git a/spec/models/project_services/gitlab_issue_tracker_service_spec.rb b/spec/models/project_services/gitlab_issue_tracker_service_spec.rb
new file mode 100644
index 0000000000..c474f4a2d9
--- /dev/null
+++ b/spec/models/project_services/gitlab_issue_tracker_service_spec.rb
@@ -0,0 +1,60 @@
+# == 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
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index cfac7d289e..bab8888a63 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -98,13 +98,33 @@ describe API::API, api: true do
expect(response.status).to eq(400)
end
- it "should return a 400 if satellite fails to create file" do
- Gitlab::Satellite::EditFileAction.any_instance.stub(
- commit!: false,
- )
+ it 'should return a 400 if the checkout fails' do
+ Gitlab::Satellite::EditFileAction.any_instance.stub(:commit!)
+ .and_raise(Gitlab::Satellite::CheckoutFailed)
put api("/projects/#{project.id}/repository/files", user), valid_params
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
diff --git a/vendor/assets/javascripts/jquery.sticky-kit.min.js b/vendor/assets/javascripts/jquery.sticky-kit.min.js
new file mode 100644
index 0000000000..e8bb207c5a
--- /dev/null
+++ b/vendor/assets/javascripts/jquery.sticky-kit.min.js
@@ -0,0 +1,9 @@
+/*
+ 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("