Commit f7aafd8f authored by Douglas Barbosa Alexandre's avatar Douglas Barbosa Alexandre

Merge branch 'master' into fix-merge-request-that-removes-submodule

parents 7d836a0c e02940e3
Please view this file on the master branch, on stable branches it's out of date. Please view this file on the master branch, on stable branches it's out of date.
v 8.3.0 (unreleased) v 8.3.0 (unreleased)
- Fix API setting of 'public' attribute to false will make a project private (Stan Hu)
- Handle and report SSL errors in Web hook test (Stan Hu)
- Fix: Assignee selector is empty when 'Unassigned' is selected (Jose Corcuera) - Fix: Assignee selector is empty when 'Unassigned' is selected (Jose Corcuera)
- Fix 500 error when update group member permission - Fix 500 error when update group member permission
- Trim leading and trailing whitespace of milestone and issueable titles (Jose Corcuera) - Trim leading and trailing whitespace of milestone and issueable titles (Jose Corcuera)
...@@ -15,6 +17,7 @@ v 8.3.0 (unreleased) ...@@ -15,6 +17,7 @@ v 8.3.0 (unreleased)
- Fix: Ensure "Remove Source Branch" button is not shown when branch is being deleted. #3583 - Fix: Ensure "Remove Source Branch" button is not shown when branch is being deleted. #3583
- Fix 500 error when creating a merge request that removes a submodule - Fix 500 error when creating a merge request that removes a submodule
- Run custom Git hooks when branch is created or deleted. - Run custom Git hooks when branch is created or deleted.
- Fix bug when simultaneously accepting multiple MRs results in MRs that are of "merged" status, but not merged to the target branch
v 8.2.3 v 8.2.3
- Fix application settings cache not expiring after changes (Stan Hu) - Fix application settings cache not expiring after changes (Stan Hu)
......
...@@ -120,8 +120,8 @@ gem 'acts-as-taggable-on', '~> 3.4' ...@@ -120,8 +120,8 @@ gem 'acts-as-taggable-on', '~> 3.4'
# Background jobs # Background jobs
gem 'sinatra', '~> 1.4.4', require: nil gem 'sinatra', '~> 1.4.4', require: nil
gem 'sidekiq', '3.3.0' gem 'sidekiq', '~> 3.5.0'
gem 'sidetiq', '~> 0.6.3' gem 'sidekiq-cron', '~> 0.3.0'
# HTTP requests # HTTP requests
gem "httparty", '~> 0.13.3' gem "httparty", '~> 0.13.3'
......
...@@ -117,8 +117,23 @@ GEM ...@@ -117,8 +117,23 @@ GEM
activemodel (>= 3.2.0) activemodel (>= 3.2.0)
activesupport (>= 3.2.0) activesupport (>= 3.2.0)
json (>= 1.7) json (>= 1.7)
celluloid (0.16.0) celluloid (0.17.2)
timers (~> 4.0.0) celluloid-essentials
celluloid-extras
celluloid-fsm
celluloid-pool
celluloid-supervision
timers (>= 4.1.1)
celluloid-essentials (0.20.5)
timers (>= 4.1.1)
celluloid-extras (0.20.5)
timers (>= 4.1.1)
celluloid-fsm (0.20.5)
timers (>= 4.1.1)
celluloid-pool (0.20.5)
timers (>= 4.1.1)
celluloid-supervision (0.20.5)
timers (>= 4.1.1)
charlock_holmes (0.7.3) charlock_holmes (0.7.3)
chunky_png (1.3.5) chunky_png (1.3.5)
cliver (0.3.2) cliver (0.3.2)
...@@ -370,7 +385,6 @@ GEM ...@@ -370,7 +385,6 @@ GEM
multi_xml (>= 0.5.2) multi_xml (>= 0.5.2)
httpclient (2.7.0.1) httpclient (2.7.0.1)
i18n (0.7.0) i18n (0.7.0)
ice_cube (0.11.1)
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)
...@@ -641,6 +655,7 @@ GEM ...@@ -641,6 +655,7 @@ GEM
sexp_processor (~> 4.1) sexp_processor (~> 4.1)
rubyntlm (0.5.2) rubyntlm (0.5.2)
rubypants (0.2.0) rubypants (0.2.0)
rufus-scheduler (3.1.10)
rugged (0.23.3) rugged (0.23.3)
safe_yaml (1.0.4) safe_yaml (1.0.4)
sanitize (2.1.0) sanitize (2.1.0)
...@@ -668,16 +683,15 @@ GEM ...@@ -668,16 +683,15 @@ GEM
rack rack
shoulda-matchers (2.8.0) shoulda-matchers (2.8.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
sidekiq (3.3.0) sidekiq (3.5.3)
celluloid (>= 0.16.0) celluloid (~> 0.17.2)
connection_pool (>= 2.0.0) connection_pool (~> 2.2, >= 2.2.0)
json json (~> 1.0)
redis (>= 3.0.6) redis (~> 3.2, >= 3.2.1)
redis-namespace (>= 1.3.1) redis-namespace (~> 1.5, >= 1.5.2)
sidetiq (0.6.3) sidekiq-cron (0.3.1)
celluloid (>= 0.14.1) rufus-scheduler (>= 2.0.24)
ice_cube (= 0.11.1) sidekiq (>= 2.17.3)
sidekiq (>= 3.0.0)
simple_oauth (0.1.9) simple_oauth (0.1.9)
simplecov (0.10.0) simplecov (0.10.0)
docile (~> 1.1.0) docile (~> 1.1.0)
...@@ -743,7 +757,7 @@ GEM ...@@ -743,7 +757,7 @@ GEM
thor (0.19.1) thor (0.19.1)
thread_safe (0.3.5) thread_safe (0.3.5)
tilt (1.4.1) tilt (1.4.1)
timers (4.0.4) timers (4.1.1)
hitimes hitimes
timfel-krb5-auth (0.8.3) timfel-krb5-auth (0.8.3)
tinder (1.10.1) tinder (1.10.1)
...@@ -938,8 +952,8 @@ DEPENDENCIES ...@@ -938,8 +952,8 @@ DEPENDENCIES
settingslogic (~> 2.0.9) settingslogic (~> 2.0.9)
sham_rack sham_rack
shoulda-matchers (~> 2.8.0) shoulda-matchers (~> 2.8.0)
sidekiq (= 3.3.0) sidekiq (~> 3.5.0)
sidetiq (~> 0.6.3) sidekiq-cron (~> 0.3.0)
simplecov (~> 0.10.0) simplecov (~> 0.10.0)
sinatra (~> 1.4.4) sinatra (~> 1.4.4)
six (~> 0.2.0) six (~> 0.2.0)
......
...@@ -80,7 +80,7 @@ There are a lot of [third-party applications integrating with GitLab](https://ab ...@@ -80,7 +80,7 @@ There are a lot of [third-party applications integrating with GitLab](https://ab
## GitLab release cycle ## GitLab release cycle
Since 2011 a minor or major version of GitLab is released on the 22nd of every month. Patch and security releases are published when needed. New features are detailed on the [blog](https://about.gitlab.com/blog/) and in the [changelog](CHANGELOG). For more information about the release process see the [release documentation](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/release). Features that will likely be in the next releases can be found on the [feature request forum](http://feedback.gitlab.com/forums/176466-general) with the status [started](http://feedback.gitlab.com/forums/176466-general/status/796456) and [completed](http://feedback.gitlab.com/forums/176466-general/status/796457). For more information about the release process see the [release documentation](http://doc.gitlab.com/ce/release/).
## Upgrading ## Upgrading
......
...@@ -369,8 +369,8 @@ class @Notes ...@@ -369,8 +369,8 @@ class @Notes
note = $(this).closest(".note") note = $(this).closest(".note")
note.find(".note-attachment").remove() note.find(".note-attachment").remove()
note.find(".note-body > .note-text").show() note.find(".note-body > .note-text").show()
note.find(".js-note-attachment-delete").hide() note.find(".note-header").show()
note.find(".note-edit-form").hide() note.find(".current-note-edit-form").remove()
### ###
Called when clicking on the "reply" button for a diff line. Called when clicking on the "reply" button for a diff line.
......
...@@ -25,13 +25,12 @@ class Projects::HooksController < Projects::ApplicationController ...@@ -25,13 +25,12 @@ class Projects::HooksController < Projects::ApplicationController
def test def test
if !@project.empty_repo? if !@project.empty_repo?
status = TestHookService.new.execute(hook, current_user) status, message = TestHookService.new.execute(hook, current_user)
if status if status
flash[:notice] = 'Hook successfully executed.' flash[:notice] = 'Hook successfully executed.'
else else
flash[:alert] = 'Hook execution failed. '\ flash[:alert] = "Hook execution failed: #{message}"
'Ensure hook URL is correct and service is up.'
end end
else else
flash[:alert] = 'Hook execution failed. Ensure the project has commits.' flash[:alert] = 'Hook execution failed. Ensure the project has commits.'
......
...@@ -209,7 +209,7 @@ module ApplicationHelper ...@@ -209,7 +209,7 @@ module ApplicationHelper
title: time.in_time_zone.stamp('Aug 21, 2011 9:23pm'), title: time.in_time_zone.stamp('Aug 21, 2011 9:23pm'),
data: { toggle: 'tooltip', placement: placement, container: 'body' } data: { toggle: 'tooltip', placement: placement, container: 'body' }
element += javascript_tag "$('.js-timeago').timeago()" unless skip_js element += javascript_tag "$('.js-timeago').last().timeago()" unless skip_js
element element
end end
......
...@@ -37,31 +37,33 @@ class WebHook < ActiveRecord::Base ...@@ -37,31 +37,33 @@ class WebHook < ActiveRecord::Base
def execute(data, hook_name) def execute(data, hook_name)
parsed_url = URI.parse(url) parsed_url = URI.parse(url)
if parsed_url.userinfo.blank? if parsed_url.userinfo.blank?
WebHook.post(url, response = WebHook.post(url,
body: data.to_json, body: data.to_json,
headers: { headers: {
"Content-Type" => "application/json", "Content-Type" => "application/json",
"X-Gitlab-Event" => hook_name.singularize.titleize "X-Gitlab-Event" => hook_name.singularize.titleize
}, },
verify: enable_ssl_verification) verify: enable_ssl_verification)
else else
post_url = url.gsub("#{parsed_url.userinfo}@", "") post_url = url.gsub("#{parsed_url.userinfo}@", "")
auth = { auth = {
username: URI.decode(parsed_url.user), username: URI.decode(parsed_url.user),
password: URI.decode(parsed_url.password), password: URI.decode(parsed_url.password),
} }
WebHook.post(post_url, response = WebHook.post(post_url,
body: data.to_json, body: data.to_json,
headers: { headers: {
"Content-Type" => "application/json", "Content-Type" => "application/json",
"X-Gitlab-Event" => hook_name.singularize.titleize "X-Gitlab-Event" => hook_name.singularize.titleize
}, },
verify: enable_ssl_verification, verify: enable_ssl_verification,
basic_auth: auth) basic_auth: auth)
end end
rescue SocketError, Errno::ECONNRESET, Errno::ECONNREFUSED, Net::OpenTimeout => e
[response.code == 200, ActionView::Base.full_sanitizer.sanitize(response.to_s)]
rescue SocketError, OpenSSL::SSL::SSLError, Errno::ECONNRESET, Errno::ECONNREFUSED, Net::OpenTimeout => e
logger.error("WebHook Error => #{e}") logger.error("WebHook Error => #{e}")
false [false, e.to_s]
end end
def async_execute(data, hook_name) def async_execute(data, hook_name)
......
...@@ -100,11 +100,11 @@ class Repository ...@@ -100,11 +100,11 @@ class Repository
end end
def find_branch(name) def find_branch(name)
branches.find { |branch| branch.name == name } raw_repository.branches.find { |branch| branch.name == name }
end end
def find_tag(name) def find_tag(name)
tags.find { |tag| tag.name == name } raw_repository.tags.find { |tag| tag.name == name }
end end
def add_branch(user, branch_name, target) def add_branch(user, branch_name, target)
......
class StuckCiBuildsWorker class StuckCiBuildsWorker
include Sidekiq::Worker include Sidekiq::Worker
include Sidetiq::Schedulable
BUILD_STUCK_TIMEOUT = 1.day BUILD_STUCK_TIMEOUT = 1.day
recurrence { daily }
def perform def perform
Rails.logger.info 'Cleaning stuck builds' Rails.logger.info 'Cleaning stuck builds'
......
...@@ -17,6 +17,12 @@ Sidekiq.configure_server do |config| ...@@ -17,6 +17,12 @@ Sidekiq.configure_server do |config|
chain.add Gitlab::SidekiqMiddleware::ArgumentsLogger if ENV['SIDEKIQ_LOG_ARGUMENTS'] chain.add Gitlab::SidekiqMiddleware::ArgumentsLogger if ENV['SIDEKIQ_LOG_ARGUMENTS']
chain.add Gitlab::SidekiqMiddleware::MemoryKiller if ENV['SIDEKIQ_MEMORY_KILLER_MAX_RSS'] chain.add Gitlab::SidekiqMiddleware::MemoryKiller if ENV['SIDEKIQ_MEMORY_KILLER_MAX_RSS']
end end
# Sidekiq-cron: load recurring jobs from schedule.yml
schedule_file = 'config/schedule.yml'
if File.exists?(schedule_file)
Sidekiq::Cron::Job.load_from_hash YAML.load_file(schedule_file)
end
end end
Sidekiq.configure_client do |config| Sidekiq.configure_client do |config|
......
require 'sidekiq/web' require 'sidekiq/web'
require 'sidekiq/cron/web'
require 'api/api' require 'api/api'
Rails.application.routes.draw do Rails.application.routes.draw do
......
# Here is a list of jobs that are scheduled to run periodically.
# We use a UNIX cron notation to specify execution schedule.
#
# Please read here for more information:
# https://github.com/ondrejbartas/sidekiq-cron#adding-cron-job
stuck_ci_builds_worker:
cron: "0 0 * * *"
class: "StuckCiBuildsWorker"
queue: "default"
...@@ -190,7 +190,7 @@ This will create two service containers (MySQL and PostgreSQL). ...@@ -190,7 +190,7 @@ This will create two service containers (MySQL and PostgreSQL).
1. Create a build container and execute script in its context: 1. Create a build container and execute script in its context:
``` ```
$ cat build_script | docker run -n build -i -l mysql:service-mysql -l postgres:service-postgres ruby:2.1 /bin/bash $ docker run --name build -i --link=service-mysql:mysql --link=service-postgres:postgres ruby:2.1 /bin/bash < build_script
``` ```
This will create build container that has two service containers linked. This will create build container that has two service containers linked.
The build_script is piped using STDIN to bash interpreter which executes the build script in container. The build_script is piped using STDIN to bash interpreter which executes the build script in container.
......
GitLab has the following updates: ## Release cycle
Since 2011 a minor or major version of GitLab is released on the 22nd of every month. Patch and security releases are published when needed. New features are detailed on the [blog](https://about.gitlab.com/blog/) and in the [changelog](CHANGELOG). Features that will likely be in the next releases can be found on the [direction page](https://about.gitlab.com/direction/).
## Release process documentation
- [Monthly release](monthly.md), every month on the 22nd. - [Monthly release](monthly.md), every month on the 22nd.
- [Patch release](patch.md), if there are serious regressions. - [Patch release](patch.md), if there are serious regressions.
......
...@@ -8,10 +8,12 @@ Feature: Project Merge Requests Acceptance ...@@ -8,10 +8,12 @@ Feature: Project Merge Requests Acceptance
Given I am on the Merge Request detail page Given I am on the Merge Request detail page
When I click on "Remove source branch" option When I click on "Remove source branch" option
And I click on Accept Merge Request And I click on Accept Merge Request
Then I should not see the Remove Source Branch button Then I should see merge request merged
And I should not see the Remove Source Branch button
@javascript @javascript
Scenario: Accepting the Merge Request without removing the source branch Scenario: Accepting the Merge Request without removing the source branch
Given I am on the Merge Request detail page Given I am on the Merge Request detail page
When I click on Accept Merge Request When I click on Accept Merge Request
Then I should see the Remove Source Branch button Then I should see merge request merged
And I should see the Remove Source Branch button
...@@ -70,8 +70,6 @@ class Spinach::Features::ProjectHooks < Spinach::FeatureSteps ...@@ -70,8 +70,6 @@ class Spinach::Features::ProjectHooks < Spinach::FeatureSteps
step 'I should see hook service down error message' do step 'I should see hook service down error message' do
expect(page).to have_selector '.flash-alert', expect(page).to have_selector '.flash-alert',
text: 'Hook execution failed. '\ text: 'Hook execution failed: Exception from'
'Ensure hook URL is correct and '\
'service is up.'
end end
end end
...@@ -32,4 +32,8 @@ class Spinach::Features::ProjectMergeRequestsAcceptance < Spinach::FeatureSteps ...@@ -32,4 +32,8 @@ class Spinach::Features::ProjectMergeRequestsAcceptance < Spinach::FeatureSteps
step 'I am signed in as a developer of the project' do step 'I am signed in as a developer of the project' do
login_as(@user) login_as(@user)
end end
step 'I should see merge request merged' do
expect(page).to have_content('The changes were merged into')
end
end end
...@@ -7,8 +7,12 @@ module API ...@@ -7,8 +7,12 @@ module API
helpers do helpers do
def map_public_to_visibility_level(attrs) def map_public_to_visibility_level(attrs)
publik = attrs.delete(:public) publik = attrs.delete(:public)
publik = parse_boolean(publik) if publik.present? && !attrs[:visibility_level].present?
attrs[:visibility_level] = Gitlab::VisibilityLevel::PUBLIC if !attrs[:visibility_level].present? && publik == true publik = parse_boolean(publik)
# Since setting the public attribute to private could mean either
# private or internal, use the more conservative option, private.
attrs[:visibility_level] = (publik == true) ? Gitlab::VisibilityLevel::PUBLIC : Gitlab::VisibilityLevel::PRIVATE
end
attrs attrs
end end
end end
......
...@@ -2,6 +2,7 @@ require 'spec_helper' ...@@ -2,6 +2,7 @@ require 'spec_helper'
describe 'Comments', feature: true do describe 'Comments', feature: true do
include RepoHelpers include RepoHelpers
include WaitForAjax
describe 'On a merge request', js: true, feature: true do describe 'On a merge request', js: true, feature: true do
let!(:merge_request) { create(:merge_request) } let!(:merge_request) { create(:merge_request) }
...@@ -123,8 +124,8 @@ describe 'Comments', feature: true do ...@@ -123,8 +124,8 @@ describe 'Comments', feature: true do
it 'removes the attachment div and resets the edit form' do it 'removes the attachment div and resets the edit form' do
find('.js-note-attachment-delete').click find('.js-note-attachment-delete').click
is_expected.not_to have_css('.note-attachment') is_expected.not_to have_css('.note-attachment')
expect(find('.current-note-edit-form', visible: false)). is_expected.not_to have_css('.current-note-edit-form')
not_to be_visible wait_for_ajax
end end
end end
end end
......
...@@ -278,7 +278,7 @@ describe ApplicationHelper do ...@@ -278,7 +278,7 @@ describe ApplicationHelper do
el = element.next_element el = element.next_element
expect(el.name).to eq 'script' expect(el.name).to eq 'script'
expect(el.text).to include "$('.js-timeago').timeago()" expect(el.text).to include "$('.js-timeago').last().timeago()"
end end
it 'allows the script tag to be excluded' do it 'allows the script tag to be excluded' do
......
...@@ -71,5 +71,11 @@ describe ProjectHook do ...@@ -71,5 +71,11 @@ describe ProjectHook do
expect { @project_hook.execute(@data, 'push_hooks') }.to raise_error(RuntimeError) expect { @project_hook.execute(@data, 'push_hooks') }.to raise_error(RuntimeError)
end end
it "handles SSL exceptions" do
expect(WebHook).to receive(:post).and_raise(OpenSSL::SSL::SSLError.new('SSL error'))
expect(@project_hook.execute(@data, 'push_hooks')).to eq([false, 'SSL error'])
end
end end
end end
...@@ -742,6 +742,18 @@ describe API::API, api: true do ...@@ -742,6 +742,18 @@ describe API::API, api: true do
end end
end end
it 'should update visibility_level from public to private' do
project3.update_attributes({ visibility_level: Gitlab::VisibilityLevel::PUBLIC })
project_param = { public: false }
put api("/projects/#{project3.id}", user), project_param
expect(response.status).to eq(200)
project_param.each_pair do |k, v|
expect(json_response[k.to_s]).to eq(v)
end
expect(json_response['visibility_level']).to eq(Gitlab::VisibilityLevel::PRIVATE)
end
it 'should not update name to existing name' do it 'should not update name to existing name' do
project_param = { name: project3.name } project_param = { name: project3.name }
put api("/projects/#{project.id}", user), project_param put api("/projects/#{project.id}", user), project_param
......
module WaitForAjax
def wait_for_ajax
Timeout.timeout(Capybara.default_wait_time) do
loop until finished_all_ajax_requests?
end
end
def finished_all_ajax_requests?
page.evaluate_script('jQuery.active').zero?
end
end
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