Merge branch 'master' into fixes/api
This commit is contained in:
commit
ac4a09e9cc
94 changed files with 935 additions and 731 deletions
|
@ -1,6 +1,5 @@
|
||||||
language: ruby
|
language: ruby
|
||||||
env:
|
env:
|
||||||
- DB=postgresql
|
|
||||||
- DB=mysql
|
- DB=mysql
|
||||||
before_install:
|
before_install:
|
||||||
- sudo apt-get install libicu-dev -y
|
- sudo apt-get install libicu-dev -y
|
||||||
|
|
23
CHANGELOG
23
CHANGELOG
|
@ -1,10 +1,33 @@
|
||||||
v 5.0.0
|
v 5.0.0
|
||||||
- Replaced gitolite with gitlab-shell
|
- Replaced gitolite with gitlab-shell
|
||||||
|
- Removed gitolite-related libraries
|
||||||
|
- State machine added
|
||||||
|
- Setup gitlab as git user
|
||||||
|
- Internal API
|
||||||
|
- Show team tab for empty projects
|
||||||
|
- Import repository feature
|
||||||
|
- Updated rails
|
||||||
|
- Use lambda for scopes
|
||||||
|
- Redesign admin area -> users
|
||||||
|
- Redesign admin area -> user
|
||||||
|
- Secure link to file attachments
|
||||||
|
- Add validations for Group and Team names
|
||||||
|
- Restyle team page for project
|
||||||
|
- Update capybara, rspec-rails, poltergeist to recent versions
|
||||||
|
|
||||||
v 4.2.0
|
v 4.2.0
|
||||||
- Teams
|
- Teams
|
||||||
- User show page. Via /u/username
|
- User show page. Via /u/username
|
||||||
- Show help contents on pages for better navigation
|
- Show help contents on pages for better navigation
|
||||||
|
- Async gitolite calls
|
||||||
|
- added satellites logs
|
||||||
|
- can_create_group, can_create_team booleans for User
|
||||||
|
- Process web hooks async
|
||||||
|
- GFM: Fix images escaped inside links
|
||||||
|
- Network graph improved
|
||||||
|
- Switchable branches for network graph
|
||||||
|
- API: Groups
|
||||||
|
- Fixed project download
|
||||||
|
|
||||||
v 4.1.0
|
v 4.1.0
|
||||||
- Optional Sign-Up
|
- Optional Sign-Up
|
||||||
|
|
16
Gemfile
16
Gemfile
|
@ -22,7 +22,7 @@ gem 'omniauth-twitter'
|
||||||
gem 'omniauth-github'
|
gem 'omniauth-github'
|
||||||
|
|
||||||
# GITLAB patched libs
|
# GITLAB patched libs
|
||||||
gem "grit", git: "https://github.com/gitlabhq/grit.git", ref: '7f35cb98ff17d534a07e3ce6ec3d580f67402837'
|
gem "grit", git: "https://github.com/gitlabhq/grit.git", ref: '9e98418ce2d654485b967003726aa2706a10060b'
|
||||||
gem 'grack', git: "https://github.com/gitlabhq/grack.git", ref: 'ba46f3b0845c6a09d488ae6abdce6ede37e227e8'
|
gem 'grack', git: "https://github.com/gitlabhq/grack.git", ref: 'ba46f3b0845c6a09d488ae6abdce6ede37e227e8'
|
||||||
gem 'grit_ext', git: "https://github.com/gitlabhq/grit_ext.git", ref: '8e6afc2da821354774aa4d1ee8a1aa2082f84a3e'
|
gem 'grit_ext', git: "https://github.com/gitlabhq/grit_ext.git", ref: '8e6afc2da821354774aa4d1ee8a1aa2082f84a3e'
|
||||||
|
|
||||||
|
@ -81,8 +81,8 @@ gem "draper", "~> 0.18.0"
|
||||||
|
|
||||||
# Background jobs
|
# Background jobs
|
||||||
gem 'slim'
|
gem 'slim'
|
||||||
gem 'sinatra', :require => nil
|
gem 'sinatra', require: nil
|
||||||
gem 'sidekiq', '2.6.4'
|
gem 'sidekiq', '2.7.3'
|
||||||
|
|
||||||
# HTTP requests
|
# HTTP requests
|
||||||
gem "httparty"
|
gem "httparty"
|
||||||
|
@ -134,12 +134,12 @@ end
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
gem 'rails-dev-tweaks'
|
gem 'rails-dev-tweaks'
|
||||||
gem 'spinach-rails'
|
gem 'spinach-rails', '0.2.0'
|
||||||
gem "rspec-rails"
|
gem "rspec-rails", '2.12.2'
|
||||||
gem "capybara"
|
gem "capybara", '2.0.2'
|
||||||
gem "pry"
|
gem "pry"
|
||||||
gem "awesome_print"
|
gem "awesome_print"
|
||||||
gem "database_cleaner", ref: "f89c34300e114be99532f14c115b2799a3380ac6", git: "https://github.com/bmabey/database_cleaner.git"
|
gem "database_cleaner", ref: "9f898fc50d87a5d51760f9dcf374bf5ffda21baf", git: "https://github.com/bmabey/database_cleaner.git"
|
||||||
gem "launchy"
|
gem "launchy"
|
||||||
gem 'factory_girl_rails'
|
gem 'factory_girl_rails'
|
||||||
|
|
||||||
|
@ -153,7 +153,7 @@ group :development, :test do
|
||||||
gem 'rb-inotify', require: linux_only('rb-inotify')
|
gem 'rb-inotify', require: linux_only('rb-inotify')
|
||||||
|
|
||||||
# PhantomJS driver for Capybara
|
# PhantomJS driver for Capybara
|
||||||
gem 'poltergeist', git: 'https://github.com/jonleighton/poltergeist.git', ref: '5c2e092001074a8cf09f332d3714e9ba150bc8ca'
|
gem 'poltergeist', '1.1.0'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
|
|
72
Gemfile.lock
72
Gemfile.lock
|
@ -1,7 +1,7 @@
|
||||||
GIT
|
GIT
|
||||||
remote: https://github.com/bmabey/database_cleaner.git
|
remote: https://github.com/bmabey/database_cleaner.git
|
||||||
revision: f89c34300e114be99532f14c115b2799a3380ac6
|
revision: 9f898fc50d87a5d51760f9dcf374bf5ffda21baf
|
||||||
ref: f89c34300e114be99532f14c115b2799a3380ac6
|
ref: 9f898fc50d87a5d51760f9dcf374bf5ffda21baf
|
||||||
specs:
|
specs:
|
||||||
database_cleaner (0.9.1)
|
database_cleaner (0.9.1)
|
||||||
|
|
||||||
|
@ -23,8 +23,8 @@ GIT
|
||||||
|
|
||||||
GIT
|
GIT
|
||||||
remote: https://github.com/gitlabhq/grit.git
|
remote: https://github.com/gitlabhq/grit.git
|
||||||
revision: 7f35cb98ff17d534a07e3ce6ec3d580f67402837
|
revision: 9e98418ce2d654485b967003726aa2706a10060b
|
||||||
ref: 7f35cb98ff17d534a07e3ce6ec3d580f67402837
|
ref: 9e98418ce2d654485b967003726aa2706a10060b
|
||||||
specs:
|
specs:
|
||||||
grit (2.5.0)
|
grit (2.5.0)
|
||||||
diff-lcs (~> 1.1)
|
diff-lcs (~> 1.1)
|
||||||
|
@ -54,18 +54,6 @@ GIT
|
||||||
specs:
|
specs:
|
||||||
raphael-rails (2.1.0)
|
raphael-rails (2.1.0)
|
||||||
|
|
||||||
GIT
|
|
||||||
remote: https://github.com/jonleighton/poltergeist.git
|
|
||||||
revision: 5c2e092001074a8cf09f332d3714e9ba150bc8ca
|
|
||||||
ref: 5c2e092001074a8cf09f332d3714e9ba150bc8ca
|
|
||||||
specs:
|
|
||||||
poltergeist (1.0.2)
|
|
||||||
capybara (~> 1.1)
|
|
||||||
childprocess (~> 0.3)
|
|
||||||
faye-websocket (~> 0.4, >= 0.4.4)
|
|
||||||
http_parser.rb (~> 0.5.3)
|
|
||||||
multi_json (~> 1.0)
|
|
||||||
|
|
||||||
GEM
|
GEM
|
||||||
remote: http://rubygems.org/
|
remote: http://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
|
@ -110,13 +98,13 @@ GEM
|
||||||
bootstrap-sass (2.2.1.1)
|
bootstrap-sass (2.2.1.1)
|
||||||
sass (~> 3.2)
|
sass (~> 3.2)
|
||||||
builder (3.0.4)
|
builder (3.0.4)
|
||||||
capybara (1.1.3)
|
capybara (2.0.2)
|
||||||
mime-types (>= 1.16)
|
mime-types (>= 1.16)
|
||||||
nokogiri (>= 1.3.3)
|
nokogiri (>= 1.3.3)
|
||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
rack-test (>= 0.5.4)
|
rack-test (>= 0.5.4)
|
||||||
selenium-webdriver (~> 2.0)
|
selenium-webdriver (~> 2.0)
|
||||||
xpath (~> 0.1.4)
|
xpath (~> 1.0.0)
|
||||||
carrierwave (0.7.1)
|
carrierwave (0.7.1)
|
||||||
activemodel (>= 3.2.0)
|
activemodel (>= 3.2.0)
|
||||||
activesupport (>= 3.2.0)
|
activesupport (>= 3.2.0)
|
||||||
|
@ -124,8 +112,8 @@ GEM
|
||||||
facter (>= 1.6.12)
|
facter (>= 1.6.12)
|
||||||
timers (>= 1.0.0)
|
timers (>= 1.0.0)
|
||||||
charlock_holmes (0.6.9)
|
charlock_holmes (0.6.9)
|
||||||
childprocess (0.3.6)
|
childprocess (0.3.8)
|
||||||
ffi (~> 1.0, >= 1.0.6)
|
ffi (~> 1.0, >= 1.0.11)
|
||||||
chosen-rails (0.9.8)
|
chosen-rails (0.9.8)
|
||||||
railties (~> 3.0)
|
railties (~> 3.0)
|
||||||
thor (~> 0.14)
|
thor (~> 0.14)
|
||||||
|
@ -169,10 +157,10 @@ GEM
|
||||||
railties (>= 3.0.0)
|
railties (>= 3.0.0)
|
||||||
faraday (0.8.4)
|
faraday (0.8.4)
|
||||||
multipart-post (~> 1.1)
|
multipart-post (~> 1.1)
|
||||||
faye-websocket (0.4.6)
|
faye-websocket (0.4.7)
|
||||||
eventmachine (>= 0.12.0)
|
eventmachine (>= 0.12.0)
|
||||||
ffaker (1.15.0)
|
ffaker (1.15.0)
|
||||||
ffi (1.1.5)
|
ffi (1.4.0)
|
||||||
font-awesome-sass-rails (3.0.0.1)
|
font-awesome-sass-rails (3.0.0.1)
|
||||||
railties (>= 3.1.1)
|
railties (>= 3.1.1)
|
||||||
sass-rails (>= 3.1.1)
|
sass-rails (>= 3.1.1)
|
||||||
|
@ -249,8 +237,6 @@ GEM
|
||||||
letter_opener (1.0.0)
|
letter_opener (1.0.0)
|
||||||
launchy (>= 2.0.4)
|
launchy (>= 2.0.4)
|
||||||
libv8 (3.3.10.4)
|
libv8 (3.3.10.4)
|
||||||
libwebsocket (0.1.6)
|
|
||||||
websocket
|
|
||||||
listen (0.5.3)
|
listen (0.5.3)
|
||||||
lumberjack (1.0.2)
|
lumberjack (1.0.2)
|
||||||
mail (2.4.4)
|
mail (2.4.4)
|
||||||
|
@ -261,12 +247,12 @@ GEM
|
||||||
mime-types (1.21)
|
mime-types (1.21)
|
||||||
modernizr (2.6.2)
|
modernizr (2.6.2)
|
||||||
sprockets (~> 2.0)
|
sprockets (~> 2.0)
|
||||||
multi_json (1.5.1)
|
multi_json (1.6.1)
|
||||||
multi_xml (0.5.1)
|
multi_xml (0.5.1)
|
||||||
multipart-post (1.1.5)
|
multipart-post (1.1.5)
|
||||||
mysql2 (0.3.11)
|
mysql2 (0.3.11)
|
||||||
net-ldap (0.2.2)
|
net-ldap (0.2.2)
|
||||||
nokogiri (1.5.5)
|
nokogiri (1.5.6)
|
||||||
oauth (0.4.7)
|
oauth (0.4.7)
|
||||||
oauth2 (0.8.0)
|
oauth2 (0.8.0)
|
||||||
faraday (~> 0.8)
|
faraday (~> 0.8)
|
||||||
|
@ -294,6 +280,10 @@ GEM
|
||||||
omniauth-oauth (~> 1.0)
|
omniauth-oauth (~> 1.0)
|
||||||
orm_adapter (0.4.0)
|
orm_adapter (0.4.0)
|
||||||
pg (0.14.1)
|
pg (0.14.1)
|
||||||
|
poltergeist (1.1.0)
|
||||||
|
capybara (~> 2.0, >= 2.0.1)
|
||||||
|
faye-websocket (~> 0.4, >= 0.4.4)
|
||||||
|
http_parser.rb (~> 0.5.3)
|
||||||
polyglot (0.3.3)
|
polyglot (0.3.3)
|
||||||
posix-spawn (0.3.6)
|
posix-spawn (0.3.6)
|
||||||
progressbar (0.12.0)
|
progressbar (0.12.0)
|
||||||
|
@ -364,7 +354,7 @@ GEM
|
||||||
rspec-expectations (2.12.0)
|
rspec-expectations (2.12.0)
|
||||||
diff-lcs (~> 1.1.3)
|
diff-lcs (~> 1.1.3)
|
||||||
rspec-mocks (2.12.0)
|
rspec-mocks (2.12.0)
|
||||||
rspec-rails (2.12.0)
|
rspec-rails (2.12.2)
|
||||||
actionpack (>= 3.0)
|
actionpack (>= 3.0)
|
||||||
activesupport (>= 3.0)
|
activesupport (>= 3.0)
|
||||||
railties (>= 3.0)
|
railties (>= 3.0)
|
||||||
|
@ -384,16 +374,16 @@ GEM
|
||||||
seed-fu (2.2.0)
|
seed-fu (2.2.0)
|
||||||
activerecord (~> 3.1)
|
activerecord (~> 3.1)
|
||||||
activesupport (~> 3.1)
|
activesupport (~> 3.1)
|
||||||
selenium-webdriver (2.26.0)
|
selenium-webdriver (2.30.0)
|
||||||
childprocess (>= 0.2.5)
|
childprocess (>= 0.2.5)
|
||||||
libwebsocket (~> 0.1.3)
|
|
||||||
multi_json (~> 1.0)
|
multi_json (~> 1.0)
|
||||||
rubyzip
|
rubyzip
|
||||||
|
websocket (~> 1.0.4)
|
||||||
settingslogic (2.0.8)
|
settingslogic (2.0.8)
|
||||||
sexp_processor (4.1.3)
|
sexp_processor (4.1.3)
|
||||||
shoulda-matchers (1.3.0)
|
shoulda-matchers (1.3.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
sidekiq (2.6.4)
|
sidekiq (2.7.3)
|
||||||
celluloid (~> 0.12.0)
|
celluloid (~> 0.12.0)
|
||||||
connection_pool (~> 1.0)
|
connection_pool (~> 1.0)
|
||||||
multi_json (~> 1)
|
multi_json (~> 1)
|
||||||
|
@ -412,11 +402,11 @@ GEM
|
||||||
temple (~> 0.5.5)
|
temple (~> 0.5.5)
|
||||||
tilt (~> 1.3.3)
|
tilt (~> 1.3.3)
|
||||||
slop (3.3.3)
|
slop (3.3.3)
|
||||||
spinach (0.5.2)
|
spinach (0.7.0)
|
||||||
colorize
|
colorize
|
||||||
gherkin-ruby (~> 0.2.0)
|
gherkin-ruby (~> 0.2.0)
|
||||||
spinach-rails (0.1.8)
|
spinach-rails (0.2.0)
|
||||||
capybara (~> 1)
|
capybara (~> 2.0.0)
|
||||||
railties (>= 3)
|
railties (>= 3)
|
||||||
spinach (>= 0.4)
|
spinach (>= 0.4)
|
||||||
sprockets (2.2.2)
|
sprockets (2.2.2)
|
||||||
|
@ -436,7 +426,7 @@ GEM
|
||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
thor (0.17.0)
|
thor (0.17.0)
|
||||||
tilt (1.3.3)
|
tilt (1.3.3)
|
||||||
timers (1.0.2)
|
timers (1.1.0)
|
||||||
treetop (1.4.12)
|
treetop (1.4.12)
|
||||||
polyglot
|
polyglot
|
||||||
polyglot (>= 0.3.1)
|
polyglot (>= 0.3.1)
|
||||||
|
@ -455,8 +445,8 @@ GEM
|
||||||
webmock (1.9.0)
|
webmock (1.9.0)
|
||||||
addressable (>= 2.2.7)
|
addressable (>= 2.2.7)
|
||||||
crack (>= 0.1.7)
|
crack (>= 0.1.7)
|
||||||
websocket (1.0.2)
|
websocket (1.0.7)
|
||||||
xpath (0.1.4)
|
xpath (1.0.0)
|
||||||
nokogiri (~> 1.3)
|
nokogiri (~> 1.3)
|
||||||
yajl-ruby (1.1.0)
|
yajl-ruby (1.1.0)
|
||||||
|
|
||||||
|
@ -470,7 +460,7 @@ DEPENDENCIES
|
||||||
better_errors
|
better_errors
|
||||||
binding_of_caller
|
binding_of_caller
|
||||||
bootstrap-sass (= 2.2.1.1)
|
bootstrap-sass (= 2.2.1.1)
|
||||||
capybara
|
capybara (= 2.0.2)
|
||||||
carrierwave (~> 0.7.1)
|
carrierwave (~> 0.7.1)
|
||||||
chosen-rails (= 0.9.8)
|
chosen-rails (= 0.9.8)
|
||||||
coffee-rails (~> 3.2.2)
|
coffee-rails (~> 3.2.2)
|
||||||
|
@ -512,7 +502,7 @@ DEPENDENCIES
|
||||||
omniauth-google-oauth2
|
omniauth-google-oauth2
|
||||||
omniauth-twitter
|
omniauth-twitter
|
||||||
pg
|
pg
|
||||||
poltergeist!
|
poltergeist (= 1.1.0)
|
||||||
pry
|
pry
|
||||||
pygments.rb!
|
pygments.rb!
|
||||||
quiet_assets (~> 1.0.1)
|
quiet_assets (~> 1.0.1)
|
||||||
|
@ -524,18 +514,18 @@ DEPENDENCIES
|
||||||
rb-fsevent
|
rb-fsevent
|
||||||
rb-inotify
|
rb-inotify
|
||||||
redcarpet (~> 2.2.2)
|
redcarpet (~> 2.2.2)
|
||||||
rspec-rails
|
rspec-rails (= 2.12.2)
|
||||||
sass-rails (~> 3.2.5)
|
sass-rails (~> 3.2.5)
|
||||||
sdoc
|
sdoc
|
||||||
seed-fu
|
seed-fu
|
||||||
settingslogic
|
settingslogic
|
||||||
shoulda-matchers (= 1.3.0)
|
shoulda-matchers (= 1.3.0)
|
||||||
sidekiq (= 2.6.4)
|
sidekiq (= 2.7.3)
|
||||||
simplecov
|
simplecov
|
||||||
sinatra
|
sinatra
|
||||||
six
|
six
|
||||||
slim
|
slim
|
||||||
spinach-rails
|
spinach-rails (= 0.2.0)
|
||||||
stamp
|
stamp
|
||||||
state_machine
|
state_machine
|
||||||
test_after_commit
|
test_after_commit
|
||||||
|
|
|
@ -31,7 +31,7 @@ class MergeRequest
|
||||||
|
|
||||||
if this.$('.automerge_widget').length and @opts.check_enable
|
if this.$('.automerge_widget').length and @opts.check_enable
|
||||||
$.get @opts.url_to_automerge_check, (data) =>
|
$.get @opts.url_to_automerge_check, (data) =>
|
||||||
this.showState( data.state )
|
this.showState( data.merge_status )
|
||||||
, 'json'
|
, 'json'
|
||||||
|
|
||||||
if @opts.ci_enable
|
if @opts.ci_enable
|
||||||
|
|
|
@ -24,6 +24,14 @@
|
||||||
background-image: -o-linear-gradient($from, $to);
|
background-image: -o-linear-gradient($from, $to);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin transition($transition) {
|
||||||
|
-webkit-transition: $transition;
|
||||||
|
-moz-transition: $transition;
|
||||||
|
-ms-transition: $transition;
|
||||||
|
-o-transition: $transition;
|
||||||
|
transition: $transition;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prefilled mixins
|
* Prefilled mixins
|
||||||
* Mixins with fixed values
|
* Mixins with fixed values
|
||||||
|
|
|
@ -90,6 +90,7 @@ header {
|
||||||
@include border-radius(3px);
|
@include border-radius(3px);
|
||||||
border: 1px solid #c6c6c6;
|
border: 1px solid #c6c6c6;
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
|
@include transition(all 0.15s ease-in 0s);
|
||||||
&:focus {
|
&:focus {
|
||||||
@extend .span3;
|
@extend .span3;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ class MergeRequestsLoadContext < BaseContext
|
||||||
end
|
end
|
||||||
|
|
||||||
merge_requests = merge_requests.page(params[:page]).per(20)
|
merge_requests = merge_requests.page(params[:page]).per(20)
|
||||||
merge_requests = merge_requests.includes(:author, :project).order("state, created_at desc")
|
merge_requests = merge_requests.includes(:author, :project).order("created_at desc")
|
||||||
|
|
||||||
# Filter by specific assignee_id (or lack thereof)?
|
# Filter by specific assignee_id (or lack thereof)?
|
||||||
if params[:assignee_id].present?
|
if params[:assignee_id].present?
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
class TestHookContext < BaseContext
|
class TestHookContext < BaseContext
|
||||||
def execute
|
def execute
|
||||||
hook = project.hooks.find(params[:id])
|
hook = project.hooks.find(params[:id])
|
||||||
commits = project.repository.commits(project.default_branch, nil, 3)
|
data = GitPushService.new.sample_data(project, current_user)
|
||||||
data = project.post_receive_data(commits.last.id, commits.first.id, "refs/heads/#{project.default_branch}", current_user)
|
|
||||||
hook.execute(data)
|
hook.execute(data)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
require 'gitlab/satellite/satellite'
|
||||||
|
|
||||||
class MergeRequestsController < ProjectResourceController
|
class MergeRequestsController < ProjectResourceController
|
||||||
before_filter :module_enabled
|
before_filter :module_enabled
|
||||||
before_filter :merge_request, only: [:edit, :update, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status]
|
before_filter :merge_request, only: [:edit, :update, :show, :commits, :diffs, :automerge, :automerge_check, :ci_status]
|
||||||
|
@ -73,7 +75,7 @@ class MergeRequestsController < ProjectResourceController
|
||||||
if @merge_request.unchecked?
|
if @merge_request.unchecked?
|
||||||
@merge_request.check_if_can_be_merged
|
@merge_request.check_if_can_be_merged
|
||||||
end
|
end
|
||||||
render json: {merge_status: @merge_request.human_merge_status}
|
render json: {merge_status: @merge_request.merge_status_name}
|
||||||
rescue Gitlab::SatelliteNotExistError
|
rescue Gitlab::SatelliteNotExistError
|
||||||
render json: {merge_status: :no_satellite}
|
render json: {merge_status: :no_satellite}
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
class ProfilesController < ApplicationController
|
class ProfilesController < ApplicationController
|
||||||
|
include ActionView::Helpers::SanitizeHelper
|
||||||
|
|
||||||
before_filter :user
|
before_filter :user
|
||||||
layout 'profile'
|
layout 'profile'
|
||||||
|
|
||||||
|
@ -12,7 +14,7 @@ class ProfilesController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def update
|
def update
|
||||||
if @user.update_attributes(params[:user])
|
if @user.update_attributes(user_attributes)
|
||||||
flash[:notice] = "Profile was successfully updated"
|
flash[:notice] = "Profile was successfully updated"
|
||||||
else
|
else
|
||||||
flash[:alert] = "Failed to update profile"
|
flash[:alert] = "Failed to update profile"
|
||||||
|
@ -65,4 +67,17 @@ class ProfilesController < ApplicationController
|
||||||
def user
|
def user
|
||||||
@user = current_user
|
@user = current_user
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def user_attributes
|
||||||
|
user_attributes = params[:user]
|
||||||
|
|
||||||
|
# Sanitize user input because we dont have strict
|
||||||
|
# validation for this fields
|
||||||
|
%w(name skype linkedin twitter bio).each do |attr|
|
||||||
|
value = user_attributes[attr]
|
||||||
|
user_attributes[attr] = sanitize(value) if value.present?
|
||||||
|
end
|
||||||
|
|
||||||
|
user_attributes
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -72,7 +72,7 @@ module ApplicationHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def search_autocomplete_source
|
def search_autocomplete_source
|
||||||
projects = current_user.authorized_projects.map { |p| { label: "project: #{p.name_with_namespace}", url: project_path(p) } }
|
projects = current_user.authorized_projects.map { |p| { label: "project: #{simple_sanitize(p.name_with_namespace)}", url: project_path(p) } }
|
||||||
groups = current_user.authorized_groups.map { |group| { label: "group: #{simple_sanitize(group.name)}", url: group_path(group) } }
|
groups = current_user.authorized_groups.map { |group| { label: "group: #{simple_sanitize(group.name)}", url: group_path(group) } }
|
||||||
teams = current_user.authorized_teams.map { |team| { label: "team: #{simple_sanitize(team.name)}", url: team_path(team) } }
|
teams = current_user.authorized_teams.map { |team| { label: "team: #{simple_sanitize(team.name)}", url: team_path(team) } }
|
||||||
|
|
||||||
|
@ -98,15 +98,15 @@ module ApplicationHelper
|
||||||
project_nav = []
|
project_nav = []
|
||||||
if @project && @project.repository && @project.repository.root_ref
|
if @project && @project.repository && @project.repository.root_ref
|
||||||
project_nav = [
|
project_nav = [
|
||||||
{ label: "#{@project.name_with_namespace} - Issues", url: project_issues_path(@project) },
|
{ label: "#{simple_sanitize(@project.name_with_namespace)} - Issues", url: project_issues_path(@project) },
|
||||||
{ label: "#{@project.name_with_namespace} - Commits", url: project_commits_path(@project, @ref || @project.repository.root_ref) },
|
{ label: "#{simple_sanitize(@project.name_with_namespace)} - Commits", url: project_commits_path(@project, @ref || @project.repository.root_ref) },
|
||||||
{ label: "#{@project.name_with_namespace} - Merge Requests", url: project_merge_requests_path(@project) },
|
{ label: "#{simple_sanitize(@project.name_with_namespace)} - Merge Requests", url: project_merge_requests_path(@project) },
|
||||||
{ label: "#{@project.name_with_namespace} - Milestones", url: project_milestones_path(@project) },
|
{ label: "#{simple_sanitize(@project.name_with_namespace)} - Milestones", url: project_milestones_path(@project) },
|
||||||
{ label: "#{@project.name_with_namespace} - Snippets", url: project_snippets_path(@project) },
|
{ label: "#{simple_sanitize(@project.name_with_namespace)} - Snippets", url: project_snippets_path(@project) },
|
||||||
{ label: "#{@project.name_with_namespace} - Team", url: project_team_index_path(@project) },
|
{ label: "#{simple_sanitize(@project.name_with_namespace)} - Team", url: project_team_index_path(@project) },
|
||||||
{ label: "#{@project.name_with_namespace} - Tree", url: project_tree_path(@project, @ref || @project.repository.root_ref) },
|
{ label: "#{simple_sanitize(@project.name_with_namespace)} - Tree", url: project_tree_path(@project, @ref || @project.repository.root_ref) },
|
||||||
{ label: "#{@project.name_with_namespace} - Wall", url: wall_project_path(@project) },
|
{ label: "#{simple_sanitize(@project.name_with_namespace)} - Wall", url: wall_project_path(@project) },
|
||||||
{ label: "#{@project.name_with_namespace} - Wiki", url: project_wikis_path(@project) },
|
{ label: "#{simple_sanitize(@project.name_with_namespace)} - Wiki", url: project_wikis_path(@project) },
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,31 @@ module CommitsHelper
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def each_diff_line_near(diff, index, expected_line_code)
|
||||||
|
max_number_of_lines = 16
|
||||||
|
|
||||||
|
prev_match_line = nil
|
||||||
|
prev_lines = []
|
||||||
|
|
||||||
|
each_diff_line(diff, index) do |full_line, type, line_code, line_new, line_old|
|
||||||
|
line = [full_line, type, line_code, line_new, line_old]
|
||||||
|
if line_code != expected_line_code
|
||||||
|
if type == "match"
|
||||||
|
prev_lines.clear
|
||||||
|
prev_match_line = line
|
||||||
|
else
|
||||||
|
prev_lines.push(line)
|
||||||
|
prev_lines.shift if prev_lines.length >= max_number_of_lines
|
||||||
|
end
|
||||||
|
else
|
||||||
|
yield(prev_match_line) if !prev_match_line.nil?
|
||||||
|
prev_lines.each { |ln| yield(ln) }
|
||||||
|
yield(line)
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def image_diff_class(diff)
|
def image_diff_class(diff)
|
||||||
if diff.deleted_file
|
if diff.deleted_file
|
||||||
"deleted"
|
"deleted"
|
||||||
|
|
|
@ -21,7 +21,6 @@ class Key < ActiveRecord::Base
|
||||||
attr_accessible :key, :title
|
attr_accessible :key, :title
|
||||||
|
|
||||||
before_validation :strip_white_space
|
before_validation :strip_white_space
|
||||||
before_save :set_identifier
|
|
||||||
|
|
||||||
validates :title, presence: true, length: { within: 0..255 }
|
validates :title, presence: true, length: { within: 0..255 }
|
||||||
validates :key, presence: true, length: { within: 0..5000 }, format: { :with => /ssh-.{3} / }, uniqueness: true
|
validates :key, presence: true, length: { within: 0..5000 }, format: { :with => /ssh-.{3} / }, uniqueness: true
|
||||||
|
@ -48,14 +47,6 @@ class Key < ActiveRecord::Base
|
||||||
errors.add(:key, "can't be fingerprinted") if $?.exitstatus != 0
|
errors.add(:key, "can't be fingerprinted") if $?.exitstatus != 0
|
||||||
end
|
end
|
||||||
|
|
||||||
def set_identifier
|
|
||||||
if is_deploy_key
|
|
||||||
self.identifier = "deploy_#{Digest::MD5.hexdigest(key)}"
|
|
||||||
else
|
|
||||||
self.identifier = "#{user.identifier}_#{Time.now.to_i}"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def is_deploy_key
|
def is_deploy_key
|
||||||
!!project_id
|
!!project_id
|
||||||
end
|
end
|
||||||
|
|
|
@ -24,6 +24,8 @@ require Rails.root.join("lib/static_model")
|
||||||
class MergeRequest < ActiveRecord::Base
|
class MergeRequest < ActiveRecord::Base
|
||||||
include Issuable
|
include Issuable
|
||||||
|
|
||||||
|
BROKEN_DIFF = "--broken-diff"
|
||||||
|
|
||||||
attr_accessible :title, :assignee_id, :target_branch, :source_branch, :milestone_id,
|
attr_accessible :title, :assignee_id, :target_branch, :source_branch, :milestone_id,
|
||||||
:author_id_of_changes, :state_event
|
:author_id_of_changes, :state_event
|
||||||
|
|
||||||
|
@ -51,47 +53,41 @@ class MergeRequest < ActiveRecord::Base
|
||||||
state :merged
|
state :merged
|
||||||
end
|
end
|
||||||
|
|
||||||
BROKEN_DIFF = "--broken-diff"
|
state_machine :merge_status, initial: :unchecked do
|
||||||
|
event :mark_as_unchecked do
|
||||||
|
transition [:can_be_merged, :cannot_be_merged] => :unchecked
|
||||||
|
end
|
||||||
|
|
||||||
UNCHECKED = 1
|
event :mark_as_mergeable do
|
||||||
CAN_BE_MERGED = 2
|
transition unchecked: :can_be_merged
|
||||||
CANNOT_BE_MERGED = 3
|
end
|
||||||
|
|
||||||
|
event :mark_as_unmergeable do
|
||||||
|
transition unchecked: :cannot_be_merged
|
||||||
|
end
|
||||||
|
|
||||||
|
state :unchecked
|
||||||
|
|
||||||
|
state :can_be_merged
|
||||||
|
|
||||||
|
state :cannot_be_merged
|
||||||
|
end
|
||||||
|
|
||||||
serialize :st_commits
|
serialize :st_commits
|
||||||
serialize :st_diffs
|
serialize :st_diffs
|
||||||
|
|
||||||
validates :source_branch, presence: true
|
validates :source_branch, presence: true
|
||||||
validates :target_branch, presence: true
|
validates :target_branch, presence: true
|
||||||
validate :validate_branches
|
validate :validate_branches
|
||||||
|
|
||||||
scope :merged, -> { with_state(:merged) }
|
scope :merged, -> { with_state(:merged) }
|
||||||
|
scope :by_branch, ->(branch_name) { where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name) }
|
||||||
|
scope :cared, ->(user) { where('assignee_id = :user OR author_id = :user', user: user.id) }
|
||||||
|
scope :by_milestone, ->(milestone) { where(milestone_id: milestone) }
|
||||||
|
|
||||||
class << self
|
# Closed scope for merge request should return
|
||||||
def find_all_by_branch(branch_name)
|
# both merged and closed mr's
|
||||||
where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name)
|
scope :closed, -> { with_states(:closed, :merged) }
|
||||||
end
|
|
||||||
|
|
||||||
def cared(user)
|
|
||||||
where('assignee_id = :user OR author_id = :user', user: user.id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def find_all_by_branch(branch_name)
|
|
||||||
where("source_branch LIKE :branch OR target_branch LIKE :branch", branch: branch_name)
|
|
||||||
end
|
|
||||||
|
|
||||||
def find_all_by_milestone(milestone)
|
|
||||||
where("milestone_id = :milestone_id", milestone_id: milestone)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def human_merge_status
|
|
||||||
merge_statuses = {
|
|
||||||
CAN_BE_MERGED => "can_be_merged",
|
|
||||||
CANNOT_BE_MERGED => "cannot_be_merged",
|
|
||||||
UNCHECKED => "unchecked"
|
|
||||||
}
|
|
||||||
merge_statuses[self.merge_status]
|
|
||||||
end
|
|
||||||
|
|
||||||
def validate_branches
|
def validate_branches
|
||||||
if target_branch == source_branch
|
if target_branch == source_branch
|
||||||
|
@ -104,26 +100,12 @@ class MergeRequest < ActiveRecord::Base
|
||||||
self.reloaded_diffs
|
self.reloaded_diffs
|
||||||
end
|
end
|
||||||
|
|
||||||
def unchecked?
|
|
||||||
merge_status == UNCHECKED
|
|
||||||
end
|
|
||||||
|
|
||||||
def mark_as_unchecked
|
|
||||||
self.merge_status = UNCHECKED
|
|
||||||
self.save
|
|
||||||
end
|
|
||||||
|
|
||||||
def can_be_merged?
|
|
||||||
merge_status == CAN_BE_MERGED
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_if_can_be_merged
|
def check_if_can_be_merged
|
||||||
self.merge_status = if Gitlab::Satellite::MergeAction.new(self.author, self).can_be_merged?
|
if Gitlab::Satellite::MergeAction.new(self.author, self).can_be_merged?
|
||||||
CAN_BE_MERGED
|
mark_as_mergeable
|
||||||
else
|
else
|
||||||
CANNOT_BE_MERGED
|
mark_as_unmergeable
|
||||||
end
|
end
|
||||||
self.save
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def diffs
|
def diffs
|
||||||
|
@ -178,11 +160,6 @@ class MergeRequest < ActiveRecord::Base
|
||||||
commits.any? && opened?
|
commits.any? && opened?
|
||||||
end
|
end
|
||||||
|
|
||||||
def mark_as_unmergable
|
|
||||||
self.merge_status = CANNOT_BE_MERGED
|
|
||||||
self.save
|
|
||||||
end
|
|
||||||
|
|
||||||
def reloaded_commits
|
def reloaded_commits
|
||||||
if opened? && unmerged_commits.any?
|
if opened? && unmerged_commits.any?
|
||||||
self.st_commits = unmerged_commits
|
self.st_commits = unmerged_commits
|
||||||
|
@ -217,7 +194,7 @@ class MergeRequest < ActiveRecord::Base
|
||||||
true
|
true
|
||||||
end
|
end
|
||||||
rescue
|
rescue
|
||||||
self.mark_as_unmergable
|
mark_as_unmergeable
|
||||||
false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -247,32 +247,6 @@ class Project < ActiveRecord::Base
|
||||||
users_projects.find_by_user_id(user_id)
|
users_projects.find_by_user_id(user_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def transfer(new_namespace)
|
|
||||||
Project.transaction do
|
|
||||||
old_namespace = namespace
|
|
||||||
self.namespace = new_namespace
|
|
||||||
|
|
||||||
old_dir = old_namespace.try(:path) || ''
|
|
||||||
new_dir = new_namespace.try(:path) || ''
|
|
||||||
|
|
||||||
old_repo = if old_dir.present?
|
|
||||||
File.join(old_dir, self.path)
|
|
||||||
else
|
|
||||||
self.path
|
|
||||||
end
|
|
||||||
|
|
||||||
if Project.where(path: self.path, namespace_id: new_namespace.try(:id)).present?
|
|
||||||
raise TransferError.new("Project with same path in target namespace already exists")
|
|
||||||
end
|
|
||||||
|
|
||||||
Gitlab::ProjectMover.new(self, old_dir, new_dir).execute
|
|
||||||
|
|
||||||
save!
|
|
||||||
end
|
|
||||||
rescue Gitlab::ProjectMover::ProjectMoveError => ex
|
|
||||||
raise Project::TransferError.new(ex.message)
|
|
||||||
end
|
|
||||||
|
|
||||||
def name_with_namespace
|
def name_with_namespace
|
||||||
@name_with_namespace ||= begin
|
@name_with_namespace ||= begin
|
||||||
if namespace
|
if namespace
|
||||||
|
@ -295,51 +269,8 @@ class Project < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# This method will be called after each post receive and only if the provided
|
def transfer(new_namespace)
|
||||||
# user is present in GitLab.
|
ProjectTransferService.new.transfer(self, new_namespace)
|
||||||
#
|
|
||||||
# All callbacks for post receive should be placed here.
|
|
||||||
def trigger_post_receive(oldrev, newrev, ref, user)
|
|
||||||
data = post_receive_data(oldrev, newrev, ref, user)
|
|
||||||
|
|
||||||
# Create satellite
|
|
||||||
self.satellite.create unless self.satellite.exists?
|
|
||||||
|
|
||||||
# Create push event
|
|
||||||
self.observe_push(data)
|
|
||||||
|
|
||||||
if push_to_branch? ref, oldrev
|
|
||||||
# Close merged MR
|
|
||||||
self.update_merge_requests(oldrev, newrev, ref, user)
|
|
||||||
|
|
||||||
# Execute web hooks
|
|
||||||
self.execute_hooks(data.dup)
|
|
||||||
|
|
||||||
# Execute project services
|
|
||||||
self.execute_services(data.dup)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Discover the default branch, but only if it hasn't already been set to
|
|
||||||
# something else
|
|
||||||
if repository && default_branch.nil?
|
|
||||||
update_attributes(default_branch: self.repository.discover_default_branch)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def push_to_branch? ref, oldrev
|
|
||||||
ref_parts = ref.split('/')
|
|
||||||
|
|
||||||
# Return if this is not a push to a branch (e.g. new commits)
|
|
||||||
!(ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000")
|
|
||||||
end
|
|
||||||
|
|
||||||
def observe_push(data)
|
|
||||||
Event.create(
|
|
||||||
project: self,
|
|
||||||
action: Event::PUSHED,
|
|
||||||
data: data,
|
|
||||||
author_id: data[:user_id]
|
|
||||||
)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def execute_hooks(data)
|
def execute_hooks(data)
|
||||||
|
@ -354,68 +285,12 @@ class Project < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Produce a hash of post-receive data
|
def discover_default_branch
|
||||||
#
|
# Discover the default branch, but only if it hasn't already been set to
|
||||||
# data = {
|
# something else
|
||||||
# before: String,
|
if repository && default_branch.nil?
|
||||||
# after: String,
|
update_attributes(default_branch: self.repository.discover_default_branch)
|
||||||
# ref: String,
|
|
||||||
# user_id: String,
|
|
||||||
# user_name: String,
|
|
||||||
# repository: {
|
|
||||||
# name: String,
|
|
||||||
# url: String,
|
|
||||||
# description: String,
|
|
||||||
# homepage: String,
|
|
||||||
# },
|
|
||||||
# commits: Array,
|
|
||||||
# total_commits_count: Fixnum
|
|
||||||
# }
|
|
||||||
#
|
|
||||||
def post_receive_data(oldrev, newrev, ref, user)
|
|
||||||
|
|
||||||
push_commits = repository.commits_between(oldrev, newrev)
|
|
||||||
|
|
||||||
# Total commits count
|
|
||||||
push_commits_count = push_commits.size
|
|
||||||
|
|
||||||
# Get latest 20 commits ASC
|
|
||||||
push_commits_limited = push_commits.last(20)
|
|
||||||
|
|
||||||
# Hash to be passed as post_receive_data
|
|
||||||
data = {
|
|
||||||
before: oldrev,
|
|
||||||
after: newrev,
|
|
||||||
ref: ref,
|
|
||||||
user_id: user.id,
|
|
||||||
user_name: user.name,
|
|
||||||
repository: {
|
|
||||||
name: name,
|
|
||||||
url: url_to_repo,
|
|
||||||
description: description,
|
|
||||||
homepage: web_url,
|
|
||||||
},
|
|
||||||
commits: [],
|
|
||||||
total_commits_count: push_commits_count
|
|
||||||
}
|
|
||||||
|
|
||||||
# For perfomance purposes maximum 20 latest commits
|
|
||||||
# will be passed as post receive hook data.
|
|
||||||
#
|
|
||||||
push_commits_limited.each do |commit|
|
|
||||||
data[:commits] << {
|
|
||||||
id: commit.id,
|
|
||||||
message: commit.safe_message,
|
|
||||||
timestamp: commit.date.xmlschema,
|
|
||||||
url: "#{Gitlab.config.gitlab.url}/#{path_with_namespace}/commit/#{commit.id}",
|
|
||||||
author: {
|
|
||||||
name: commit.author_name,
|
|
||||||
email: commit.author_email
|
|
||||||
}
|
|
||||||
}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
data
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_merge_requests(oldrev, newrev, ref, user)
|
def update_merge_requests(oldrev, newrev, ref, user)
|
||||||
|
@ -424,7 +299,7 @@ class Project < ActiveRecord::Base
|
||||||
c_ids = self.repository.commits_between(oldrev, newrev).map(&:id)
|
c_ids = self.repository.commits_between(oldrev, newrev).map(&:id)
|
||||||
|
|
||||||
# Update code for merge requests
|
# Update code for merge requests
|
||||||
mrs = self.merge_requests.opened.find_all_by_branch(branch_name).all
|
mrs = self.merge_requests.opened.by_branch(branch_name).all
|
||||||
mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked }
|
mrs.each { |merge_request| merge_request.reload_code; merge_request.mark_as_unchecked }
|
||||||
|
|
||||||
# Close merge requests
|
# Close merge requests
|
||||||
|
@ -446,6 +321,10 @@ class Project < ActiveRecord::Base
|
||||||
!repository || repository.empty?
|
!repository || repository.empty?
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ensure_satellite_exists
|
||||||
|
self.satellite.create unless self.satellite.exists?
|
||||||
|
end
|
||||||
|
|
||||||
def satellite
|
def satellite
|
||||||
@satellite ||= Gitlab::Satellite::Satellite.new(self)
|
@satellite ||= Gitlab::Satellite::Satellite.new(self)
|
||||||
end
|
end
|
||||||
|
|
|
@ -66,28 +66,6 @@ class ProjectTeam
|
||||||
members.masters.map(&:user)
|
members.masters.map(&:user)
|
||||||
end
|
end
|
||||||
|
|
||||||
def repository_readers
|
|
||||||
repository_members[UsersProject::REPORTER]
|
|
||||||
end
|
|
||||||
|
|
||||||
def repository_writers
|
|
||||||
repository_members[UsersProject::DEVELOPER]
|
|
||||||
end
|
|
||||||
|
|
||||||
def repository_masters
|
|
||||||
repository_members[UsersProject::MASTER]
|
|
||||||
end
|
|
||||||
|
|
||||||
def repository_members
|
|
||||||
keys = Hash.new {|h,k| h[k] = [] }
|
|
||||||
UsersProject.select("keys.identifier, project_access").
|
|
||||||
joins(user: :keys).where(project_id: project.id).
|
|
||||||
each {|row| keys[row.project_access] << [row.identifier] }
|
|
||||||
|
|
||||||
keys[UsersProject::REPORTER] += project.deploy_keys.pluck(:identifier)
|
|
||||||
keys
|
|
||||||
end
|
|
||||||
|
|
||||||
def import(source_project)
|
def import(source_project)
|
||||||
target_project = project
|
target_project = project
|
||||||
|
|
||||||
|
|
|
@ -12,13 +12,4 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
class SystemHook < WebHook
|
class SystemHook < WebHook
|
||||||
def self.all_hooks_fire(data)
|
|
||||||
SystemHook.all.each do |sh|
|
|
||||||
sh.async_execute data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def async_execute(data)
|
|
||||||
Sidekiq::Client.enqueue(SystemHookWorker, id, data)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -70,6 +70,7 @@ class User < ActiveRecord::Base
|
||||||
has_many :team_projects, through: :user_team_project_relationships
|
has_many :team_projects, through: :user_team_project_relationships
|
||||||
|
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
|
validates :email, presence: true, format: { with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/ }
|
||||||
validates :bio, length: { within: 0..255 }
|
validates :bio, length: { within: 0..255 }
|
||||||
validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider}
|
validates :extern_uid, allow_blank: true, uniqueness: {scope: :provider}
|
||||||
validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0}
|
validates :projects_limit, presence: true, numericality: {greater_than_or_equal_to: 0}
|
||||||
|
@ -215,17 +216,6 @@ class User < ActiveRecord::Base
|
||||||
UsersProject.where(project_id: authorized_projects.map(&:id), user_id: self.id)
|
UsersProject.where(project_id: authorized_projects.map(&:id), user_id: self.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a string for use as a Gitolite user identifier
|
|
||||||
#
|
|
||||||
# Note that Gitolite 2.x requires the following pattern for users:
|
|
||||||
#
|
|
||||||
# ^@?[0-9a-zA-Z][0-9a-zA-Z._\@+-]*$
|
|
||||||
def identifier
|
|
||||||
# Replace non-word chars with underscores, then make sure it starts with
|
|
||||||
# valid chars
|
|
||||||
email.gsub(/\W/, '_').gsub(/\A([\W\_])+/, '')
|
|
||||||
end
|
|
||||||
|
|
||||||
def is_admin?
|
def is_admin?
|
||||||
admin
|
admin
|
||||||
end
|
end
|
||||||
|
|
|
@ -28,10 +28,14 @@ class WebHook < ActiveRecord::Base
|
||||||
WebHook.post(url, body: data.to_json, headers: { "Content-Type" => "application/json" })
|
WebHook.post(url, body: data.to_json, headers: { "Content-Type" => "application/json" })
|
||||||
else
|
else
|
||||||
post_url = url.gsub("#{parsed_url.userinfo}@", "")
|
post_url = url.gsub("#{parsed_url.userinfo}@", "")
|
||||||
|
auth = {
|
||||||
|
username: URI.decode(parsed_url.user),
|
||||||
|
password: URI.decode(parsed_url.password),
|
||||||
|
}
|
||||||
WebHook.post(post_url,
|
WebHook.post(post_url,
|
||||||
body: data.to_json,
|
body: data.to_json,
|
||||||
headers: {"Content-Type" => "application/json"},
|
headers: {"Content-Type" => "application/json"},
|
||||||
basic_auth: {username: parsed_url.user, password: parsed_url.password})
|
basic_auth: auth)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -21,22 +21,22 @@ class ActivityObserver < ActiveRecord::Observer
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_close(record, transition)
|
def after_close(record, transition)
|
||||||
Event.create(
|
Event.create(
|
||||||
project: record.project,
|
project: record.project,
|
||||||
target_id: record.id,
|
target_id: record.id,
|
||||||
target_type: record.class.name,
|
target_type: record.class.name,
|
||||||
action: Event::CLOSED,
|
action: Event::CLOSED,
|
||||||
author_id: record.author_id_of_changes
|
author_id: record.author_id_of_changes
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_reopen(record, transition)
|
def after_reopen(record, transition)
|
||||||
Event.create(
|
Event.create(
|
||||||
project: record.project,
|
project: record.project,
|
||||||
target_id: record.id,
|
target_id: record.id,
|
||||||
target_type: record.class.name,
|
target_type: record.class.name,
|
||||||
action: Event::REOPENED,
|
action: Event::REOPENED,
|
||||||
author_id: record.author_id_of_changes
|
author_id: record.author_id_of_changes
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
class NoteObserver < ActiveRecord::Observer
|
class NoteObserver < ActiveRecord::Observer
|
||||||
|
|
||||||
def after_create(note)
|
def after_create(note)
|
||||||
send_notify_mails(note)
|
send_notify_mails(note)
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,67 +1,11 @@
|
||||||
class SystemHookObserver < ActiveRecord::Observer
|
class SystemHookObserver < ActiveRecord::Observer
|
||||||
observe :user, :project, :users_project
|
observe :user, :project, :users_project
|
||||||
|
|
||||||
def after_create(model)
|
def after_create(model)
|
||||||
if model.kind_of? Project
|
SystemHooksService.execute_hooks_for(model, :create)
|
||||||
SystemHook.all_hooks_fire({
|
|
||||||
event_name: "project_create",
|
|
||||||
name: model.name,
|
|
||||||
path: model.path,
|
|
||||||
project_id: model.id,
|
|
||||||
owner_name: model.owner.name,
|
|
||||||
owner_email: model.owner.email,
|
|
||||||
created_at: model.created_at
|
|
||||||
})
|
|
||||||
elsif model.kind_of? User
|
|
||||||
SystemHook.all_hooks_fire({
|
|
||||||
event_name: "user_create",
|
|
||||||
name: model.name,
|
|
||||||
email: model.email,
|
|
||||||
created_at: model.created_at
|
|
||||||
})
|
|
||||||
|
|
||||||
elsif model.kind_of? UsersProject
|
|
||||||
SystemHook.all_hooks_fire({
|
|
||||||
event_name: "user_add_to_team",
|
|
||||||
project_name: model.project.name,
|
|
||||||
project_path: model.project.path,
|
|
||||||
project_id: model.project_id,
|
|
||||||
user_name: model.user.name,
|
|
||||||
user_email: model.user.email,
|
|
||||||
project_access: model.repo_access_human,
|
|
||||||
created_at: model.created_at
|
|
||||||
})
|
|
||||||
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def after_destroy(model)
|
def after_destroy(model)
|
||||||
if model.kind_of? Project
|
SystemHooksService.execute_hooks_for(model, :destroy)
|
||||||
SystemHook.all_hooks_fire({
|
|
||||||
event_name: "project_destroy",
|
|
||||||
name: model.name,
|
|
||||||
path: model.path,
|
|
||||||
project_id: model.id,
|
|
||||||
owner_name: model.owner.name,
|
|
||||||
owner_email: model.owner.email,
|
|
||||||
})
|
|
||||||
elsif model.kind_of? User
|
|
||||||
SystemHook.all_hooks_fire({
|
|
||||||
event_name: "user_destroy",
|
|
||||||
name: model.name,
|
|
||||||
email: model.email
|
|
||||||
})
|
|
||||||
|
|
||||||
elsif model.kind_of? UsersProject
|
|
||||||
SystemHook.all_hooks_fire({
|
|
||||||
event_name: "user_remove_from_team",
|
|
||||||
project_name: model.project.name,
|
|
||||||
project_path: model.project.path,
|
|
||||||
project_id: model.project_id,
|
|
||||||
user_name: model.user.name,
|
|
||||||
user_email: model.user.email,
|
|
||||||
project_access: model.repo_access_human
|
|
||||||
})
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
124
app/services/git_push_service.rb
Normal file
124
app/services/git_push_service.rb
Normal file
|
@ -0,0 +1,124 @@
|
||||||
|
class GitPushService
|
||||||
|
attr_accessor :project, :user, :push_data
|
||||||
|
|
||||||
|
# This method will be called after each git update
|
||||||
|
# and only if the provided user and project is present in GitLab.
|
||||||
|
#
|
||||||
|
# All callbacks for post receive action should be placed here.
|
||||||
|
#
|
||||||
|
# Now this method do next:
|
||||||
|
# 1. Ensure project satellite exists
|
||||||
|
# 2. Update merge requests
|
||||||
|
# 3. Execute project web hooks
|
||||||
|
# 4. Execute project services
|
||||||
|
# 5. Create Push Event
|
||||||
|
#
|
||||||
|
def execute(project, user, oldrev, newrev, ref)
|
||||||
|
@project, @user = project, user
|
||||||
|
|
||||||
|
# Collect data for this git push
|
||||||
|
@push_data = post_receive_data(oldrev, newrev, ref)
|
||||||
|
|
||||||
|
project.ensure_satellite_exists
|
||||||
|
project.discover_default_branch
|
||||||
|
|
||||||
|
if push_to_branch?(ref, oldrev)
|
||||||
|
project.update_merge_requests(oldrev, newrev, ref, @user)
|
||||||
|
project.execute_hooks(@push_data.dup)
|
||||||
|
project.execute_services(@push_data.dup)
|
||||||
|
end
|
||||||
|
|
||||||
|
create_push_event
|
||||||
|
end
|
||||||
|
|
||||||
|
# This method provide a sample data
|
||||||
|
# generated with post_receive_data method
|
||||||
|
# for given project
|
||||||
|
#
|
||||||
|
def sample_data(project, user)
|
||||||
|
@project, @user = project, user
|
||||||
|
commits = project.repository.commits(project.default_branch, nil, 3)
|
||||||
|
post_receive_data(commits.last.id, commits.first.id, "refs/heads/#{project.default_branch}")
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def create_push_event
|
||||||
|
Event.create(
|
||||||
|
project: project,
|
||||||
|
action: Event::PUSHED,
|
||||||
|
data: push_data,
|
||||||
|
author_id: push_data[:user_id]
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Produce a hash of post-receive data
|
||||||
|
#
|
||||||
|
# data = {
|
||||||
|
# before: String,
|
||||||
|
# after: String,
|
||||||
|
# ref: String,
|
||||||
|
# user_id: String,
|
||||||
|
# user_name: String,
|
||||||
|
# repository: {
|
||||||
|
# name: String,
|
||||||
|
# url: String,
|
||||||
|
# description: String,
|
||||||
|
# homepage: String,
|
||||||
|
# },
|
||||||
|
# commits: Array,
|
||||||
|
# total_commits_count: Fixnum
|
||||||
|
# }
|
||||||
|
#
|
||||||
|
def post_receive_data(oldrev, newrev, ref)
|
||||||
|
push_commits = project.repository.commits_between(oldrev, newrev)
|
||||||
|
|
||||||
|
# Total commits count
|
||||||
|
push_commits_count = push_commits.size
|
||||||
|
|
||||||
|
# Get latest 20 commits ASC
|
||||||
|
push_commits_limited = push_commits.last(20)
|
||||||
|
|
||||||
|
# Hash to be passed as post_receive_data
|
||||||
|
data = {
|
||||||
|
before: oldrev,
|
||||||
|
after: newrev,
|
||||||
|
ref: ref,
|
||||||
|
user_id: user.id,
|
||||||
|
user_name: user.name,
|
||||||
|
repository: {
|
||||||
|
name: project.name,
|
||||||
|
url: project.url_to_repo,
|
||||||
|
description: project.description,
|
||||||
|
homepage: project.web_url,
|
||||||
|
},
|
||||||
|
commits: [],
|
||||||
|
total_commits_count: push_commits_count
|
||||||
|
}
|
||||||
|
|
||||||
|
# For perfomance purposes maximum 20 latest commits
|
||||||
|
# will be passed as post receive hook data.
|
||||||
|
#
|
||||||
|
push_commits_limited.each do |commit|
|
||||||
|
data[:commits] << {
|
||||||
|
id: commit.id,
|
||||||
|
message: commit.safe_message,
|
||||||
|
timestamp: commit.date.xmlschema,
|
||||||
|
url: "#{Gitlab.config.gitlab.url}/#{project.path_with_namespace}/commit/#{commit.id}",
|
||||||
|
author: {
|
||||||
|
name: commit.author_name,
|
||||||
|
email: commit.author_email
|
||||||
|
}
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
data
|
||||||
|
end
|
||||||
|
|
||||||
|
def push_to_branch? ref, oldrev
|
||||||
|
ref_parts = ref.split('/')
|
||||||
|
|
||||||
|
# Return if this is not a push to a branch (e.g. new commits)
|
||||||
|
!(ref_parts[1] !~ /heads/ || oldrev == "00000000000000000000000000000000")
|
||||||
|
end
|
||||||
|
end
|
34
app/services/project_transfer_service.rb
Normal file
34
app/services/project_transfer_service.rb
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
# ProjectTransferService class
|
||||||
|
#
|
||||||
|
# Used for transfer project to another namespace
|
||||||
|
#
|
||||||
|
class ProjectTransferService
|
||||||
|
attr_accessor :project
|
||||||
|
|
||||||
|
def transfer(project, new_namespace)
|
||||||
|
Project.transaction do
|
||||||
|
old_namespace = project.namespace
|
||||||
|
project.namespace = new_namespace
|
||||||
|
|
||||||
|
old_dir = old_namespace.try(:path) || ''
|
||||||
|
new_dir = new_namespace.try(:path) || ''
|
||||||
|
|
||||||
|
old_repo = if old_dir.present?
|
||||||
|
File.join(old_dir, project.path)
|
||||||
|
else
|
||||||
|
project.path
|
||||||
|
end
|
||||||
|
|
||||||
|
if Project.where(path: project.path, namespace_id: new_namespace.try(:id)).present?
|
||||||
|
raise TransferError.new("Project with same path in target namespace already exists")
|
||||||
|
end
|
||||||
|
|
||||||
|
Gitlab::ProjectMover.new(project, old_dir, new_dir).execute
|
||||||
|
|
||||||
|
save!
|
||||||
|
end
|
||||||
|
rescue Gitlab::ProjectMover::ProjectMoveError => ex
|
||||||
|
raise Project::TransferError.new(ex.message)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
59
app/services/system_hooks_service.rb
Normal file
59
app/services/system_hooks_service.rb
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
class SystemHooksService
|
||||||
|
def self.execute_hooks_for(model, event)
|
||||||
|
execute_hooks(build_event_data(model, event))
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def self.execute_hooks(data)
|
||||||
|
SystemHook.all.each do |sh|
|
||||||
|
async_execute_hook sh, data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.async_execute_hook(hook, data)
|
||||||
|
Sidekiq::Client.enqueue(SystemHookWorker, hook.id, data)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.build_event_data(model, event)
|
||||||
|
data = {
|
||||||
|
event_name: build_event_name(model, event),
|
||||||
|
created_at: model.created_at
|
||||||
|
}
|
||||||
|
|
||||||
|
case model
|
||||||
|
when Project
|
||||||
|
data.merge!({
|
||||||
|
name: model.name,
|
||||||
|
path: model.path,
|
||||||
|
project_id: model.id,
|
||||||
|
owner_name: model.owner.name,
|
||||||
|
owner_email: model.owner.email
|
||||||
|
})
|
||||||
|
when User
|
||||||
|
data.merge!({
|
||||||
|
name: model.name,
|
||||||
|
email: model.email
|
||||||
|
})
|
||||||
|
when UsersProject
|
||||||
|
data.merge!({
|
||||||
|
project_name: model.project.name,
|
||||||
|
project_path: model.project.path,
|
||||||
|
project_id: model.project_id,
|
||||||
|
user_name: model.user.name,
|
||||||
|
user_email: model.user.email,
|
||||||
|
project_access: model.repo_access_human
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.build_event_name(model, event)
|
||||||
|
case model
|
||||||
|
when UsersProject
|
||||||
|
return "user_add_to_team" if event == :create
|
||||||
|
return "user_remove_from_team" if event == :destroy
|
||||||
|
else
|
||||||
|
"#{model.class.name.downcase}_#{event.to_s}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -17,7 +17,7 @@
|
||||||
= link_to_project project
|
= link_to_project project
|
||||||
%ul.well-list.issues_table
|
%ul.well-list.issues_table
|
||||||
- group[1].each do |issue|
|
- group[1].each do |issue|
|
||||||
= render(partial: 'issues/show', locals: {issue: issue})
|
= render issue
|
||||||
%hr
|
%hr
|
||||||
= paginate @issues, theme: "gitlab"
|
= paginate @issues, theme: "gitlab"
|
||||||
- else
|
- else
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
= link_to_project project
|
= link_to_project project
|
||||||
%ul.well-list.issues_table
|
%ul.well-list.issues_table
|
||||||
- group[1].each do |issue|
|
- group[1].each do |issue|
|
||||||
= render(partial: 'issues/show', locals: {issue: issue})
|
= render issue
|
||||||
%hr
|
%hr
|
||||||
= paginate @issues, theme: "gitlab"
|
= paginate @issues, theme: "gitlab"
|
||||||
- else
|
- else
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
- @issues.each do |issue|
|
= render @issues
|
||||||
= render(partial: 'issues/show', locals: {issue: issue})
|
|
||||||
|
|
||||||
- if @issues.present?
|
- if @issues.present?
|
||||||
%li.bottom
|
%li.bottom
|
||||||
|
|
|
@ -6,12 +6,12 @@
|
||||||
= @issue.created_at.stamp("Aug 21, 2011")
|
= @issue.created_at.stamp("Aug 21, 2011")
|
||||||
|
|
||||||
%span.pull-right
|
%span.pull-right
|
||||||
- if can?(current_user, :admin_project, @project) || @issue.author == current_user
|
- if can?(current_user, :modify_issue, @issue)
|
||||||
- if @issue.closed?
|
- if @issue.closed?
|
||||||
= link_to 'Reopen', project_issue_path(@project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn grouped reopen_issue"
|
= link_to 'Reopen', project_issue_path(@project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn grouped reopen_issue"
|
||||||
- else
|
- else
|
||||||
= link_to 'Close', project_issue_path(@project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn grouped close_issue", title: "Close Issue"
|
= link_to 'Close', project_issue_path(@project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn grouped close_issue", title: "Close Issue"
|
||||||
- if can?(current_user, :admin_project, @project) || @issue.author == current_user
|
|
||||||
= link_to edit_project_issue_path(@project, @issue), class: "btn grouped" do
|
= link_to edit_project_issue_path(@project, @issue), class: "btn grouped" do
|
||||||
%i.icon-edit
|
%i.icon-edit
|
||||||
Edit
|
Edit
|
||||||
|
@ -55,5 +55,11 @@
|
||||||
= preserve do
|
= preserve do
|
||||||
= markdown @issue.description
|
= markdown @issue.description
|
||||||
|
|
||||||
|
- content_for :note_actions do
|
||||||
|
- if can?(current_user, :modify_issue, @issue)
|
||||||
|
- if @issue.closed?
|
||||||
|
= link_to 'Reopen Issue', project_issue_path(@project, @issue, issue: {state_event: :reopen }, status_only: true), method: :put, class: "btn grouped reopen_issue"
|
||||||
|
- else
|
||||||
|
= link_to 'Close Issue', project_issue_path(@project, @issue, issue: {state_event: :close }, status_only: true), method: :put, class: "btn grouped close_issue", title: "Close Issue"
|
||||||
|
|
||||||
.voting_notes#notes= render "notes/notes_with_form"
|
.voting_notes#notes= render "notes/notes_with_form"
|
||||||
|
|
|
@ -29,10 +29,10 @@
|
||||||
$(function(){
|
$(function(){
|
||||||
merge_request = new MergeRequest({
|
merge_request = new MergeRequest({
|
||||||
url_to_automerge_check: "#{automerge_check_project_merge_request_path(@project, @merge_request)}",
|
url_to_automerge_check: "#{automerge_check_project_merge_request_path(@project, @merge_request)}",
|
||||||
check_enable: #{@merge_request.merge_status == MergeRequest::UNCHECKED ? "true" : "false"},
|
check_enable: #{@merge_request.unchecked? ? "true" : "false"},
|
||||||
url_to_ci_check: "#{ci_status_project_merge_request_path(@project, @merge_request)}",
|
url_to_ci_check: "#{ci_status_project_merge_request_path(@project, @merge_request)}",
|
||||||
ci_enable: #{@project.gitlab_ci? ? "true" : "false"},
|
ci_enable: #{@project.gitlab_ci? ? "true" : "false"},
|
||||||
current_status: "#{@merge_request.human_merge_status}",
|
current_status: "#{@merge_request.merge_status_name}",
|
||||||
action: "#{controller.action_name}"
|
action: "#{controller.action_name}"
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
%br/
|
%br/
|
||||||
.content
|
.content
|
||||||
%table
|
%table
|
||||||
- each_diff_line(diff, note.diff_file_index) do |line, type, line_code, line_new, line_old|
|
- each_diff_line_near(diff, note.diff_file_index, note.line_code) do |line, type, line_code, line_new, line_old|
|
||||||
%tr.line_holder{ id: line_code }
|
%tr.line_holder{ id: line_code }
|
||||||
- if type == "match"
|
- if type == "match"
|
||||||
%td.old_line= "..."
|
%td.old_line= "..."
|
||||||
|
@ -22,4 +22,3 @@
|
||||||
|
|
||||||
- if line_code == note.line_code
|
- if line_code == note.line_code
|
||||||
= render "notes/diff_notes_with_reply", notes: discussion_notes
|
= render "notes/diff_notes_with_reply", notes: discussion_notes
|
||||||
- break # cut off diff after notes
|
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
.note-form-actions
|
.note-form-actions
|
||||||
.buttons
|
.buttons
|
||||||
= f.submit 'Add Comment', class: "btn comment-btn grouped js-comment-button"
|
= f.submit 'Add Comment', class: "btn comment-btn grouped js-comment-button"
|
||||||
|
= yield(:note_actions)
|
||||||
|
|
||||||
%a.btn.grouped.js-close-discussion-note-form Cancel
|
%a.btn.grouped.js-close-discussion-note-form Cancel
|
||||||
|
|
||||||
.note-form-option
|
.note-form-option
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%fieldset
|
%fieldset.update-token
|
||||||
%legend
|
%legend
|
||||||
Private token
|
Private token
|
||||||
%span.cred.pull-right
|
%span.cred.pull-right
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
%span You don`t have one yet. Click generate to fix it.
|
%span You don`t have one yet. Click generate to fix it.
|
||||||
= f.submit 'Generate', class: "btn success btn-build-token"
|
= f.submit 'Generate', class: "btn success btn-build-token"
|
||||||
|
|
||||||
%fieldset
|
%fieldset.update-password
|
||||||
%legend Password
|
%legend Password
|
||||||
= form_for @user, url: update_password_profile_path, method: :put do |f|
|
= form_for @user, url: update_password_profile_path, method: :put do |f|
|
||||||
.padded
|
.padded
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
= @snippet.title
|
= @snippet.title
|
||||||
%small= @snippet.file_name
|
%small= @snippet.file_name
|
||||||
- if can?(current_user, :admin_snippet, @project) || @snippet.author == current_user
|
- if can?(current_user, :admin_snippet, @project) || @snippet.author == current_user
|
||||||
= link_to "Edit", edit_project_snippet_path(@project, @snippet), class: "btn btn-small pull-right"
|
= link_to "Edit", edit_project_snippet_path(@project, @snippet), class: "btn btn-small pull-right", title: 'Edit Snippet'
|
||||||
|
|
||||||
%br
|
%br
|
||||||
%div= render 'blob'
|
%div= render 'blob'
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
= link_to_project @project
|
= link_to_project @project
|
||||||
%ul.well-list.issues_table
|
%ul.well-list.issues_table
|
||||||
- group[1].each do |issue|
|
- group[1].each do |issue|
|
||||||
= render(partial: 'issues/show', locals: {issue: issue})
|
= render issue
|
||||||
%hr
|
%hr
|
||||||
= paginate @issues, theme: "gitlab"
|
= paginate @issues, theme: "gitlab"
|
||||||
- else
|
- else
|
||||||
|
|
|
@ -26,5 +26,5 @@
|
||||||
- elsif user.blocked
|
- elsif user.blocked
|
||||||
%span.btn.disabled.blocked Blocked
|
%span.btn.disabled.blocked Blocked
|
||||||
- elsif allow_admin
|
- elsif allow_admin
|
||||||
= link_to team_member_path(@team, user), confirm: remove_from_user_team_message(@team, user), method: :delete, class: "btn-tiny btn btn-remove" do
|
= link_to team_member_path(@team, user), confirm: remove_from_user_team_message(@team, user), method: :delete, class: "btn-tiny btn btn-remove", title: "Remove from team" do
|
||||||
%i.icon-minus.icon-white
|
%i.icon-minus.icon-white
|
||||||
|
|
|
@ -42,6 +42,6 @@ class PostReceive
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
project.trigger_post_receive(oldrev, newrev, ref, user)
|
GitPushService.new.execute(project, user, oldrev, newrev, ref)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,16 +1,16 @@
|
||||||
class ConvertClosedToStateInMergeRequest < ActiveRecord::Migration
|
class ConvertClosedToStateInMergeRequest < ActiveRecord::Migration
|
||||||
def up
|
def up
|
||||||
MergeRequest.transaction do
|
MergeRequest.transaction do
|
||||||
MergeRequest.where("closed = 1 AND merged = 1").update_all("state = 'merged'")
|
MergeRequest.where(closed: true, merged: true).update_all("state = 'merged'")
|
||||||
MergeRequest.where("closed = 1 AND merged = 0").update_all("state = 'closed'")
|
MergeRequest.where(closed: true, merged: true).update_all("state = 'closed'")
|
||||||
MergeRequest.where("closed = 0").update_all("state = 'opened'")
|
MergeRequest.where(closed: false).update_all("state = 'opened'")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def down
|
def down
|
||||||
MergeRequest.transaction do
|
MergeRequest.transaction do
|
||||||
MergeRequest.where(state: :closed).update_all("closed = 1")
|
MergeRequest.where(state: :closed).update_all(closed: true)
|
||||||
MergeRequest.where(state: :merged).update_all("closed = 1, merged = 1")
|
MergeRequest.where(state: :merged).update_all(closed: true, merged: true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
class AddNewMergeStatusToMergeRequest < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :merge_requests, :new_merge_status, :string
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,17 @@
|
||||||
|
class ConvertMergeStatusInMergeRequest < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
MergeRequest.transaction do
|
||||||
|
MergeRequest.where(merge_status: 1).update_all("new_merge_status = 'unchecked'")
|
||||||
|
MergeRequest.where(merge_status: 2).update_all("new_merge_status = 'can_be_merged'")
|
||||||
|
MergeRequest.where(merge_status: 3).update_all("new_merge_status = 'cannot_be_merged'")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
MergeRequest.transaction do
|
||||||
|
MergeRequest.where(new_merge_status: :unchecked).update_all("merge_status = 1")
|
||||||
|
MergeRequest.where(new_merge_status: :can_be_merged).update_all("merge_status = 2")
|
||||||
|
MergeRequest.where(new_merge_status: :cannot_be_merged).update_all("merge_status = 3")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,9 @@
|
||||||
|
class RemoveMergeStatusFromMergeRequest < ActiveRecord::Migration
|
||||||
|
def up
|
||||||
|
remove_column :merge_requests, :merge_status
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
add_column :merge_requests, :merge_status, :integer
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,5 @@
|
||||||
|
class RenameNewMergeStatusToMergeStatusInMilestone < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
rename_column :merge_requests, :new_merge_status, :merge_status
|
||||||
|
end
|
||||||
|
end
|
42
db/schema.rb
42
db/schema.rb
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended to check this file into your version control system.
|
# It's strongly recommended to check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(:version => 20130218141554) do
|
ActiveRecord::Schema.define(:version => 20130220133245) do
|
||||||
|
|
||||||
create_table "events", :force => true do |t|
|
create_table "events", :force => true do |t|
|
||||||
t.string "target_type"
|
t.string "target_type"
|
||||||
|
@ -68,19 +68,19 @@ ActiveRecord::Schema.define(:version => 20130218141554) do
|
||||||
add_index "keys", ["user_id"], :name => "index_keys_on_user_id"
|
add_index "keys", ["user_id"], :name => "index_keys_on_user_id"
|
||||||
|
|
||||||
create_table "merge_requests", :force => true do |t|
|
create_table "merge_requests", :force => true do |t|
|
||||||
t.string "target_branch", :null => false
|
t.string "target_branch", :null => false
|
||||||
t.string "source_branch", :null => false
|
t.string "source_branch", :null => false
|
||||||
t.integer "project_id", :null => false
|
t.integer "project_id", :null => false
|
||||||
t.integer "author_id"
|
t.integer "author_id"
|
||||||
t.integer "assignee_id"
|
t.integer "assignee_id"
|
||||||
t.string "title"
|
t.string "title"
|
||||||
t.datetime "created_at", :null => false
|
t.datetime "created_at", :null => false
|
||||||
t.datetime "updated_at", :null => false
|
t.datetime "updated_at", :null => false
|
||||||
t.text "st_commits", :limit => 2147483647
|
t.text "st_commits", :limit => 2147483647
|
||||||
t.text "st_diffs", :limit => 2147483647
|
t.text "st_diffs", :limit => 2147483647
|
||||||
t.integer "merge_status", :default => 1, :null => false
|
|
||||||
t.integer "milestone_id"
|
t.integer "milestone_id"
|
||||||
t.string "state"
|
t.string "state"
|
||||||
|
t.string "merge_status"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "merge_requests", ["assignee_id"], :name => "index_merge_requests_on_assignee_id"
|
add_index "merge_requests", ["assignee_id"], :name => "index_merge_requests_on_assignee_id"
|
||||||
|
@ -106,11 +106,11 @@ ActiveRecord::Schema.define(:version => 20130218141554) do
|
||||||
add_index "milestones", ["project_id"], :name => "index_milestones_on_project_id"
|
add_index "milestones", ["project_id"], :name => "index_milestones_on_project_id"
|
||||||
|
|
||||||
create_table "namespaces", :force => true do |t|
|
create_table "namespaces", :force => true do |t|
|
||||||
t.string "name", :null => false
|
t.string "name", :null => false
|
||||||
t.string "path", :null => false
|
t.string "path", :null => false
|
||||||
t.integer "owner_id", :null => false
|
t.integer "owner_id", :null => false
|
||||||
t.datetime "created_at", :null => false
|
t.datetime "created_at", :null => false
|
||||||
t.datetime "updated_at", :null => false
|
t.datetime "updated_at", :null => false
|
||||||
t.string "type"
|
t.string "type"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -142,16 +142,16 @@ ActiveRecord::Schema.define(:version => 20130218141554) do
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.string "path"
|
t.string "path"
|
||||||
t.text "description"
|
t.text "description"
|
||||||
t.datetime "created_at", :null => false
|
t.datetime "created_at", :null => false
|
||||||
t.datetime "updated_at", :null => false
|
t.datetime "updated_at", :null => false
|
||||||
t.integer "creator_id"
|
t.integer "creator_id"
|
||||||
t.string "default_branch"
|
t.string "default_branch"
|
||||||
t.boolean "issues_enabled", :default => true, :null => false
|
t.boolean "issues_enabled", :default => true, :null => false
|
||||||
t.boolean "wall_enabled", :default => true, :null => false
|
t.boolean "wall_enabled", :default => true, :null => false
|
||||||
t.boolean "merge_requests_enabled", :default => true, :null => false
|
t.boolean "merge_requests_enabled", :default => true, :null => false
|
||||||
t.boolean "wiki_enabled", :default => true, :null => false
|
t.boolean "wiki_enabled", :default => true, :null => false
|
||||||
t.integer "namespace_id"
|
t.integer "namespace_id"
|
||||||
t.boolean "public", :default => false, :null => false
|
t.boolean "public", :default => false, :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "projects", ["creator_id"], :name => "index_projects_on_owner_id"
|
add_index "projects", ["creator_id"], :name => "index_projects_on_owner_id"
|
||||||
|
@ -230,8 +230,8 @@ ActiveRecord::Schema.define(:version => 20130218141554) do
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.string "path"
|
t.string "path"
|
||||||
t.integer "owner_id"
|
t.integer "owner_id"
|
||||||
t.datetime "created_at", :null => false
|
t.datetime "created_at", :null => false
|
||||||
t.datetime "updated_at", :null => false
|
t.datetime "updated_at", :null => false
|
||||||
end
|
end
|
||||||
|
|
||||||
create_table "users", :force => true do |t|
|
create_table "users", :force => true do |t|
|
||||||
|
|
|
@ -31,7 +31,6 @@ Dumping database tables:
|
||||||
- Dumping table wikis... [DONE]
|
- Dumping table wikis... [DONE]
|
||||||
Dumping repositories:
|
Dumping repositories:
|
||||||
- Dumping repository abcd... [DONE]
|
- Dumping repository abcd... [DONE]
|
||||||
- Dumping repository gitolite-admin.git... [DONE]
|
|
||||||
Creating backup archive: $TIMESTAMP_gitlab_backup.tar [DONE]
|
Creating backup archive: $TIMESTAMP_gitlab_backup.tar [DONE]
|
||||||
Deleting tmp directories...[DONE]
|
Deleting tmp directories...[DONE]
|
||||||
Deleting old backups... [SKIPPING]
|
Deleting old backups... [SKIPPING]
|
||||||
|
@ -77,6 +76,5 @@ Restoring database tables:
|
||||||
- Loading fixture wikis...[SKIPPING]
|
- Loading fixture wikis...[SKIPPING]
|
||||||
Restoring repositories:
|
Restoring repositories:
|
||||||
- Restoring repository abcd... [DONE]
|
- Restoring repository abcd... [DONE]
|
||||||
- Restoring repository gitolite-admin.git... [DONE]
|
|
||||||
Deleting tmp directories...[DONE]
|
Deleting tmp directories...[DONE]
|
||||||
```
|
```
|
||||||
|
|
|
@ -1,10 +1,4 @@
|
||||||
### Remove grabage from gitolite config and filesystem. Important! Data loss!
|
### Remove grabage from filesystem. Important! Data loss!
|
||||||
|
|
||||||
Remove projects from gitolite config if they dont exist in GitLab database
|
|
||||||
|
|
||||||
```
|
|
||||||
bundle exec rake gitlab:cleanup:config RAILS_ENV=production
|
|
||||||
```
|
|
||||||
|
|
||||||
Remove namespaces(dirs) from /home/git/repositories if they dont exist in GitLab database
|
Remove namespaces(dirs) from /home/git/repositories if they dont exist in GitLab database
|
||||||
|
|
||||||
|
|
|
@ -17,12 +17,12 @@ bundle exec rake gitlab:enable_namespaces RAILS_ENV=production
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Enable auto merge
|
### Rebuild project satellites
|
||||||
|
|
||||||
This command will enable the auto merge feature. After this you will be able to **merge a merge request** via GitLab and use the **online editor**.
|
This command will build missing satellites for projects. After this you will be able to **merge a merge request** via GitLab and use the **online editor**.
|
||||||
|
|
||||||
```
|
```
|
||||||
bundle exec rake gitlab:enable_automerge RAILS_ENV=production
|
bundle exec rake gitlab:satellites:create RAILS_ENV=production
|
||||||
```
|
```
|
||||||
|
|
||||||
Example output:
|
Example output:
|
||||||
|
|
|
@ -31,12 +31,10 @@ SSH Clone URL: git@localhost:some-project.git
|
||||||
Using LDAP: no
|
Using LDAP: no
|
||||||
Using Omniauth: no
|
Using Omniauth: no
|
||||||
|
|
||||||
Gitolite information
|
GitLab Shell
|
||||||
Version: v3.04-4-g4524f01
|
Version: 1.0.4
|
||||||
Admin URI: git@localhost:gitolite-admin
|
|
||||||
Admin Key: gitlab
|
|
||||||
Repositories: /home/git/repositories/
|
Repositories: /home/git/repositories/
|
||||||
Hooks: /home/git/.gitolite/hooks/
|
Hooks: /home/git/gitlab-shell/hooks/
|
||||||
Git: /usr/bin/git
|
Git: /usr/bin/git
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -46,8 +44,8 @@ Git: /usr/bin/git
|
||||||
Runs the following rake tasks:
|
Runs the following rake tasks:
|
||||||
|
|
||||||
* gitlab:env:check
|
* gitlab:env:check
|
||||||
* gitlab:gitolite:check
|
* gitlab:gitlab_shell:check
|
||||||
* gitlab:resque:check
|
* gitlab:sidekiq:check
|
||||||
* gitlab:app:check
|
* gitlab:app:check
|
||||||
|
|
||||||
It will check that each component was setup according to the installation guide and suggest fixes for issues found.
|
It will check that each component was setup according to the installation guide and suggest fixes for issues found.
|
||||||
|
@ -74,16 +72,12 @@ Checking Environment ... Finished
|
||||||
Checking Gitolite ...
|
Checking Gitolite ...
|
||||||
|
|
||||||
Using recommended version ... yes
|
Using recommended version ... yes
|
||||||
Repo umask is 0007 in .gitolite.rc? ... yes
|
|
||||||
Allow all Git config keys in .gitolite.rc ... yes
|
|
||||||
Config directory exists? ... yes
|
Config directory exists? ... yes
|
||||||
Config directory owned by git:git? ... yes
|
Config directory owned by git:git? ... yes
|
||||||
Config directory access is drwxr-x---? ... yes
|
Config directory access is drwxr-x---? ... yes
|
||||||
Repo base directory exists? ... yes
|
Repo base directory exists? ... yes
|
||||||
Repo base owned by git:git? ... yes
|
Repo base owned by git:git? ... yes
|
||||||
Repo base access is drwxrws---? ... yes
|
Repo base access is drwxrws---? ... yes
|
||||||
Can clone gitolite-admin? ... yes
|
|
||||||
Can commit to gitolite-admin? ... yes
|
|
||||||
post-receive hook exists? ... yes
|
post-receive hook exists? ... yes
|
||||||
post-receive hook up-to-date? ... yes
|
post-receive hook up-to-date? ... yes
|
||||||
post-receive hooks in repos are links: ...
|
post-receive hooks in repos are links: ...
|
||||||
|
@ -135,24 +129,6 @@ If necessary, remove the `tmp/repo_satellites` directory and rerun the command b
|
||||||
bundle exec rake gitlab:satellites:create RAILS_ENV=production
|
bundle exec rake gitlab:satellites:create RAILS_ENV=production
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
### Rebuild each key at gitolite config
|
|
||||||
|
|
||||||
This will send all users ssh public keys to gitolite and grant them access (based on their permission) to their projects.
|
|
||||||
|
|
||||||
```
|
|
||||||
bundle exec rake gitlab:gitolite:update_keys RAILS_ENV=production
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### Rebuild each project at gitolite config
|
|
||||||
|
|
||||||
This makes sure that all projects are present in gitolite and can be accessed.
|
|
||||||
|
|
||||||
```
|
|
||||||
bundle exec rake gitlab:gitolite:update_repos RAILS_ENV=production
|
|
||||||
```
|
|
||||||
|
|
||||||
### Import bare repositories into GitLab project instance
|
### Import bare repositories into GitLab project instance
|
||||||
|
|
||||||
Notes:
|
Notes:
|
||||||
|
|
|
@ -12,7 +12,7 @@ Feature: Project Browse files
|
||||||
Then I should see files from repository for "8470d70"
|
Then I should see files from repository for "8470d70"
|
||||||
|
|
||||||
Scenario: I browse file content
|
Scenario: I browse file content
|
||||||
Given I click on "Gemfile" file in repo
|
Given I click on "Gemfile.lock" file in repo
|
||||||
Then I should see it content
|
Then I should see it content
|
||||||
|
|
||||||
Scenario: I browse raw file
|
Scenario: I browse raw file
|
||||||
|
@ -22,6 +22,6 @@ Feature: Project Browse files
|
||||||
|
|
||||||
@javascript
|
@javascript
|
||||||
Scenario: I can edit file
|
Scenario: I can edit file
|
||||||
Given I click on "Gemfile" file in repo
|
Given I click on "Gemfile.lock" file in repo
|
||||||
And I click button "edit"
|
And I click button "edit"
|
||||||
Then I can edit code
|
Then I can edit code
|
||||||
|
|
|
@ -5,6 +5,6 @@ Feature: Project Browse git repo
|
||||||
Given I visit project source page
|
Given I visit project source page
|
||||||
|
|
||||||
Scenario: I blame file
|
Scenario: I blame file
|
||||||
Given I click on "Gemfile" file in repo
|
Given I click on "Gemfile.lock" file in repo
|
||||||
And I click blame button
|
And I click blame button
|
||||||
Then I should see git file blame
|
Then I should see git file blame
|
||||||
|
|
|
@ -9,7 +9,7 @@ class AdminTeams < Spinach::FeatureSteps
|
||||||
end
|
end
|
||||||
|
|
||||||
And 'Create gitlab user "John"' do
|
And 'Create gitlab user "John"' do
|
||||||
@user = create(:user, :name => "John")
|
@user = create(:user, name: "John")
|
||||||
end
|
end
|
||||||
|
|
||||||
And 'I click new team link' do
|
And 'I click new team link' do
|
||||||
|
@ -50,8 +50,8 @@ class AdminTeams < Spinach::FeatureSteps
|
||||||
When 'I select user "John" from user list as "Developer"' do
|
When 'I select user "John" from user list as "Developer"' do
|
||||||
@user ||= User.find_by_name("John")
|
@user ||= User.find_by_name("John")
|
||||||
within "#team_members" do
|
within "#team_members" do
|
||||||
select @user.name, :from => "user_ids"
|
select "#{@user.name} (#{@user.email})", from: "user_ids"
|
||||||
select "Developer", :from => "default_project_access"
|
select "Developer", from: "default_project_access"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -89,8 +89,8 @@ class AdminTeams < Spinach::FeatureSteps
|
||||||
When 'I select project "Shop" with max access "Reporter"' do
|
When 'I select project "Shop" with max access "Reporter"' do
|
||||||
@project ||= Project.find_by_name("Shop")
|
@project ||= Project.find_by_name("Shop")
|
||||||
within "#assign_projects" do
|
within "#assign_projects" do
|
||||||
select @project.name, :from => "project_ids"
|
select @project.name, from: "project_ids"
|
||||||
select "Reporter", :from => "greatest_project_access"
|
select "Reporter", from: "greatest_project_access"
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -127,8 +127,8 @@ class AdminTeams < Spinach::FeatureSteps
|
||||||
When 'I select user "Jimm" ub team members list as "Master"' do
|
When 'I select user "Jimm" ub team members list as "Master"' do
|
||||||
user = User.find_by_name("Jimm")
|
user = User.find_by_name("Jimm")
|
||||||
within "#team_members" do
|
within "#team_members" do
|
||||||
select user.name, :from => "user_ids"
|
select "#{user.name} (#{user.email})", from: "user_ids"
|
||||||
select "Developer", :from => "default_project_access"
|
select "Developer", from: "default_project_access"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -23,15 +23,19 @@ class Profile < Spinach::FeatureSteps
|
||||||
end
|
end
|
||||||
|
|
||||||
Then 'I change my password' do
|
Then 'I change my password' do
|
||||||
fill_in "user_password", :with => "222333"
|
within '.update-password' do
|
||||||
fill_in "user_password_confirmation", :with => "222333"
|
fill_in "user_password", :with => "222333"
|
||||||
click_button "Save"
|
fill_in "user_password_confirmation", :with => "222333"
|
||||||
|
click_button "Save"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
When 'I unsuccessfully change my password' do
|
When 'I unsuccessfully change my password' do
|
||||||
fill_in "user_password", with: "password"
|
within '.update-password' do
|
||||||
fill_in "user_password_confirmation", with: "confirmation"
|
fill_in "user_password", with: "password"
|
||||||
click_button "Save"
|
fill_in "user_password_confirmation", with: "confirmation"
|
||||||
|
click_button "Save"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
Then "I should see a password error message" do
|
Then "I should see a password error message" do
|
||||||
|
@ -43,8 +47,10 @@ class Profile < Spinach::FeatureSteps
|
||||||
end
|
end
|
||||||
|
|
||||||
Then 'I reset my token' do
|
Then 'I reset my token' do
|
||||||
@old_token = @user.private_token
|
within '.update-token' do
|
||||||
click_button "Reset"
|
@old_token = @user.private_token
|
||||||
|
click_button "Reset"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
And 'I should see new token' do
|
And 'I should see new token' do
|
||||||
|
|
|
@ -16,12 +16,12 @@ class ProjectBrowseFiles < Spinach::FeatureSteps
|
||||||
page.should have_content "Gemfile"
|
page.should have_content "Gemfile"
|
||||||
end
|
end
|
||||||
|
|
||||||
Given 'I click on "Gemfile" file in repo' do
|
Given 'I click on "Gemfile.lock" file in repo' do
|
||||||
click_link "Gemfile"
|
click_link "Gemfile.lock"
|
||||||
end
|
end
|
||||||
|
|
||||||
Then 'I should see it content' do
|
Then 'I should see it content' do
|
||||||
page.should have_content "rubygems.org"
|
page.should have_content "DEPENDENCIES"
|
||||||
end
|
end
|
||||||
|
|
||||||
And 'I click link "raw"' do
|
And 'I click link "raw"' do
|
||||||
|
|
|
@ -3,8 +3,8 @@ class ProjectBrowseGitRepo < Spinach::FeatureSteps
|
||||||
include SharedProject
|
include SharedProject
|
||||||
include SharedPaths
|
include SharedPaths
|
||||||
|
|
||||||
Given 'I click on "Gemfile" file in repo' do
|
Given 'I click on "Gemfile.lock" file in repo' do
|
||||||
click_link "Gemfile"
|
click_link "Gemfile.lock"
|
||||||
end
|
end
|
||||||
|
|
||||||
And 'I click blame button' do
|
And 'I click blame button' do
|
||||||
|
@ -12,7 +12,7 @@ class ProjectBrowseGitRepo < Spinach::FeatureSteps
|
||||||
end
|
end
|
||||||
|
|
||||||
Then 'I should see git file blame' do
|
Then 'I should see git file blame' do
|
||||||
page.should have_content "rubygems.org"
|
page.should have_content "DEPENDENCIES"
|
||||||
page.should have_content "Dmitriy Zaporozhets"
|
page.should have_content "Dmitriy Zaporozhets"
|
||||||
page.should have_content "Moving to rails 3.2"
|
page.should have_content "Moving to rails 3.2"
|
||||||
end
|
end
|
||||||
|
|
|
@ -53,7 +53,7 @@ class ProjectTeamManagement < Spinach::FeatureSteps
|
||||||
end
|
end
|
||||||
|
|
||||||
Given 'I click link "Sam"' do
|
Given 'I click link "Sam"' do
|
||||||
click_link "Sam"
|
first(:link, "Sam").click
|
||||||
end
|
end
|
||||||
|
|
||||||
Then 'I should see "Sam" team profile' do
|
Then 'I should see "Sam" team profile' do
|
||||||
|
|
|
@ -22,7 +22,7 @@ module SharedDiffNote
|
||||||
|
|
||||||
Given 'I leave a diff comment like "Typo, please fix"' do
|
Given 'I leave a diff comment like "Typo, please fix"' do
|
||||||
find("#586fb7c4e1add2d4d24e27566ed7064680098646_29_14.line_holder .js-add-diff-note-button").trigger("click")
|
find("#586fb7c4e1add2d4d24e27566ed7064680098646_29_14.line_holder .js-add-diff-note-button").trigger("click")
|
||||||
within(".file") do
|
within(".file form[rel$='586fb7c4e1add2d4d24e27566ed7064680098646_29_14']") do
|
||||||
fill_in "note[note]", with: "Typo, please fix"
|
fill_in "note[note]", with: "Typo, please fix"
|
||||||
#click_button("Add Comment")
|
#click_button("Add Comment")
|
||||||
find(".js-comment-button").trigger("click")
|
find(".js-comment-button").trigger("click")
|
||||||
|
@ -32,7 +32,7 @@ module SharedDiffNote
|
||||||
|
|
||||||
Given 'I preview a diff comment text like "Should fix it :smile:"' do
|
Given 'I preview a diff comment text like "Should fix it :smile:"' do
|
||||||
find("#586fb7c4e1add2d4d24e27566ed7064680098646_29_14.line_holder .js-add-diff-note-button").trigger("click")
|
find("#586fb7c4e1add2d4d24e27566ed7064680098646_29_14.line_holder .js-add-diff-note-button").trigger("click")
|
||||||
within(".file") do
|
within(".file form[rel$='586fb7c4e1add2d4d24e27566ed7064680098646_29_14']") do
|
||||||
fill_in "note[note]", with: "Should fix it :smile:"
|
fill_in "note[note]", with: "Should fix it :smile:"
|
||||||
find(".js-note-preview-button").trigger("click")
|
find(".js-note-preview-button").trigger("click")
|
||||||
end
|
end
|
||||||
|
@ -40,7 +40,7 @@ module SharedDiffNote
|
||||||
|
|
||||||
Given 'I preview another diff comment text like "DRY this up"' do
|
Given 'I preview another diff comment text like "DRY this up"' do
|
||||||
find("#586fb7c4e1add2d4d24e27566ed7064680098646_57_41.line_holder .js-add-diff-note-button").trigger("click")
|
find("#586fb7c4e1add2d4d24e27566ed7064680098646_57_41.line_holder .js-add-diff-note-button").trigger("click")
|
||||||
within(".file") do
|
within(".file form[rel$='586fb7c4e1add2d4d24e27566ed7064680098646_57_41']") do
|
||||||
fill_in "note[note]", with: "DRY this up"
|
fill_in "note[note]", with: "DRY this up"
|
||||||
find(".js-note-preview-button").trigger("click")
|
find(".js-note-preview-button").trigger("click")
|
||||||
end
|
end
|
||||||
|
|
|
@ -173,12 +173,10 @@ module SharedPaths
|
||||||
# ----------------------------------------
|
# ----------------------------------------
|
||||||
|
|
||||||
And 'I visit project "Shop" page' do
|
And 'I visit project "Shop" page' do
|
||||||
project = Project.find_by_name("Shop")
|
|
||||||
visit project_path(project)
|
visit project_path(project)
|
||||||
end
|
end
|
||||||
|
|
||||||
When 'I visit edit project "Shop" page' do
|
When 'I visit edit project "Shop" page' do
|
||||||
project = Project.find_by_name("Shop")
|
|
||||||
visit edit_project_path(project)
|
visit edit_project_path(project)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -219,7 +217,7 @@ module SharedPaths
|
||||||
end
|
end
|
||||||
|
|
||||||
And 'I visit project "Shop" issues page' do
|
And 'I visit project "Shop" issues page' do
|
||||||
visit project_issues_path(Project.find_by_name("Shop"))
|
visit project_issues_path(project)
|
||||||
end
|
end
|
||||||
|
|
||||||
Given 'I visit issue page "Release 0.4"' do
|
Given 'I visit issue page "Release 0.4"' do
|
||||||
|
@ -228,7 +226,7 @@ module SharedPaths
|
||||||
end
|
end
|
||||||
|
|
||||||
Given 'I visit project "Shop" labels page' do
|
Given 'I visit project "Shop" labels page' do
|
||||||
visit project_labels_path(Project.find_by_name("Shop"))
|
visit project_labels_path(project)
|
||||||
end
|
end
|
||||||
|
|
||||||
Given 'I visit merge request page "Bug NS-04"' do
|
Given 'I visit merge request page "Bug NS-04"' do
|
||||||
|
@ -242,20 +240,18 @@ module SharedPaths
|
||||||
end
|
end
|
||||||
|
|
||||||
And 'I visit project "Shop" merge requests page' do
|
And 'I visit project "Shop" merge requests page' do
|
||||||
visit project_merge_requests_path(Project.find_by_name("Shop"))
|
visit project_merge_requests_path(project)
|
||||||
end
|
end
|
||||||
|
|
||||||
Given 'I visit project "Shop" milestones page' do
|
Given 'I visit project "Shop" milestones page' do
|
||||||
@project = Project.find_by_name("Shop")
|
visit project_milestones_path(project)
|
||||||
visit project_milestones_path(@project)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
Then 'I visit project "Shop" team page' do
|
Then 'I visit project "Shop" team page' do
|
||||||
visit project_team_index_path(Project.find_by_name("Shop"))
|
visit project_team_index_path(project)
|
||||||
end
|
end
|
||||||
|
|
||||||
Then 'I visit project "Shop" wall page' do
|
Then 'I visit project "Shop" wall page' do
|
||||||
project = Project.find_by_name("Shop")
|
|
||||||
visit wall_project_path(project)
|
visit wall_project_path(project)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -266,4 +262,8 @@ module SharedPaths
|
||||||
def root_ref
|
def root_ref
|
||||||
@project.repository.root_ref
|
@project.repository.root_ref
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def project
|
||||||
|
project = Project.find_by_name!("Shop")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -177,8 +177,8 @@ class Userteams < Spinach::FeatureSteps
|
||||||
And 'I select user "John" from list with role "Reporter"' do
|
And 'I select user "John" from list with role "Reporter"' do
|
||||||
user = User.find_by_name("John")
|
user = User.find_by_name("John")
|
||||||
within "#team_members" do
|
within "#team_members" do
|
||||||
select user.name, :from => "user_ids"
|
select "#{user.name} (#{user.email})", from: "user_ids"
|
||||||
select "Reporter", :from => "default_project_access"
|
select "Reporter", from: "default_project_access"
|
||||||
end
|
end
|
||||||
click_button "Add"
|
click_button "Add"
|
||||||
end
|
end
|
||||||
|
@ -213,8 +213,8 @@ class Userteams < Spinach::FeatureSteps
|
||||||
|
|
||||||
When 'I submit form with selected project and max access' do
|
When 'I submit form with selected project and max access' do
|
||||||
within "#assign_projects" do
|
within "#assign_projects" do
|
||||||
select @project.name_with_namespace, :from => "project_ids"
|
select @project.name_with_namespace, from: "project_ids"
|
||||||
select "Reporter", :from => "greatest_project_access"
|
select "Reporter", from: "greatest_project_access"
|
||||||
end
|
end
|
||||||
click_button "Add"
|
click_button "Add"
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,6 +5,12 @@ module Gitlab
|
||||||
#
|
#
|
||||||
# Check if ssh key has access to project code
|
# Check if ssh key has access to project code
|
||||||
#
|
#
|
||||||
|
# Params:
|
||||||
|
# key_id - SSH Key id
|
||||||
|
# project - project path with namespace
|
||||||
|
# action - git action (git-upload-pack or git-receive-pack)
|
||||||
|
# ref - branch name
|
||||||
|
#
|
||||||
get "/allowed" do
|
get "/allowed" do
|
||||||
key = Key.find(params[:key_id])
|
key = Key.find(params[:key_id])
|
||||||
project = Project.find_with_namespace(params[:project])
|
project = Project.find_with_namespace(params[:project])
|
||||||
|
|
|
@ -255,7 +255,6 @@ namespace :gitlab do
|
||||||
warn_user_is_not_gitlab
|
warn_user_is_not_gitlab
|
||||||
start_checking "Environment"
|
start_checking "Environment"
|
||||||
|
|
||||||
check_issue_1059_shell_profile_error
|
|
||||||
check_gitlab_git_config
|
check_gitlab_git_config
|
||||||
check_python2_exists
|
check_python2_exists
|
||||||
check_python2_version
|
check_python2_version
|
||||||
|
@ -294,30 +293,6 @@ namespace :gitlab do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# see https://github.com/gitlabhq/gitlabhq/issues/1059
|
|
||||||
def check_issue_1059_shell_profile_error
|
|
||||||
gitlab_shell_ssh_user = Gitlab.config.gitlab_shell.ssh_user
|
|
||||||
print "Has no \"-e\" in ~#{gitlab_shell_ssh_user}/.profile ... "
|
|
||||||
|
|
||||||
profile_file = File.join(gitlab_shell_user_home, ".profile")
|
|
||||||
|
|
||||||
unless File.read(profile_file) =~ /^-e PATH/
|
|
||||||
puts "yes".green
|
|
||||||
else
|
|
||||||
puts "no".red
|
|
||||||
try_fixing_it(
|
|
||||||
"Open #{profile_file}",
|
|
||||||
"Find the line starting with \"-e PATH\"",
|
|
||||||
"Remove \"-e \" so the line starts with PATH"
|
|
||||||
)
|
|
||||||
for_more_information(
|
|
||||||
see_installation_guide_section("Gitlab Shell"),
|
|
||||||
"https://github.com/gitlabhq/gitlabhq/issues/1059"
|
|
||||||
)
|
|
||||||
fix_and_rerun
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def check_python2_exists
|
def check_python2_exists
|
||||||
print "Has python2? ... "
|
print "Has python2? ... "
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,6 @@ describe "Admin::Users" do
|
||||||
it "should have user info" do
|
it "should have user info" do
|
||||||
page.should have_content(@user.email)
|
page.should have_content(@user.email)
|
||||||
page.should have_content(@user.name)
|
page.should have_content(@user.name)
|
||||||
page.should have_content(@user.projects_limit)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -169,32 +169,40 @@ describe "Gitlab Flavored Markdown" do
|
||||||
describe "for notes" do
|
describe "for notes" do
|
||||||
it "should render in commits#show", js: true do
|
it "should render in commits#show", js: true do
|
||||||
visit project_commit_path(project, commit)
|
visit project_commit_path(project, commit)
|
||||||
fill_in "note_note", with: "see ##{issue.id}"
|
within ".new_note.js-main-target-form" do
|
||||||
click_button "Add Comment"
|
fill_in "note_note", with: "see ##{issue.id}"
|
||||||
|
click_button "Add Comment"
|
||||||
|
end
|
||||||
|
|
||||||
page.should have_link("##{issue.id}")
|
page.should have_link("##{issue.id}")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should render in issue#show", js: true do
|
it "should render in issue#show", js: true do
|
||||||
visit project_issue_path(project, issue)
|
visit project_issue_path(project, issue)
|
||||||
fill_in "note_note", with: "see ##{issue.id}"
|
within ".new_note.js-main-target-form" do
|
||||||
click_button "Add Comment"
|
fill_in "note_note", with: "see ##{issue.id}"
|
||||||
|
click_button "Add Comment"
|
||||||
|
end
|
||||||
|
|
||||||
page.should have_link("##{issue.id}")
|
page.should have_link("##{issue.id}")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should render in merge_request#show", js: true do
|
it "should render in merge_request#show", js: true do
|
||||||
visit project_merge_request_path(project, merge_request)
|
visit project_merge_request_path(project, merge_request)
|
||||||
fill_in "note_note", with: "see ##{issue.id}"
|
within ".new_note.js-main-target-form" do
|
||||||
click_button "Add Comment"
|
fill_in "note_note", with: "see ##{issue.id}"
|
||||||
|
click_button "Add Comment"
|
||||||
|
end
|
||||||
|
|
||||||
page.should have_link("##{issue.id}")
|
page.should have_link("##{issue.id}")
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should render in projects#wall", js: true do
|
it "should render in projects#wall", js: true do
|
||||||
visit wall_project_path(project)
|
visit wall_project_path(project)
|
||||||
fill_in "note_note", with: "see ##{issue.id}"
|
within ".new_note.js-main-target-form" do
|
||||||
click_button "Add Comment"
|
fill_in "note_note", with: "see ##{issue.id}"
|
||||||
|
click_button "Add Comment"
|
||||||
|
end
|
||||||
|
|
||||||
page.should have_link("##{issue.id}")
|
page.should have_link("##{issue.id}")
|
||||||
end
|
end
|
|
@ -18,7 +18,7 @@ describe "On a merge request", js: true do
|
||||||
it { should have_css(".js-main-target-form", visible: true, count: 1) }
|
it { should have_css(".js-main-target-form", visible: true, count: 1) }
|
||||||
|
|
||||||
# button initalization
|
# button initalization
|
||||||
it { within(".js-main-target-form") { should have_button("Add Comment") } }
|
it { find(".js-main-target-form input[type=submit]").value.should == "Add Comment" }
|
||||||
it { within(".js-main-target-form") { should_not have_link("Cancel") } }
|
it { within(".js-main-target-form") { should_not have_link("Cancel") } }
|
||||||
|
|
||||||
# notifiactions
|
# notifiactions
|
||||||
|
@ -67,7 +67,7 @@ describe "On a merge request", js: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
# note added
|
# note added
|
||||||
it { within(".js-main-target-form") { should have_content("This is awsome!") } }
|
it { should have_content("This is awsome!") }
|
||||||
|
|
||||||
# reset form
|
# reset form
|
||||||
it { within(".js-main-target-form") { should have_no_field("note[note]", with: "This is awesome!") } }
|
it { within(".js-main-target-form") { should have_no_field("note[note]", with: "This is awesome!") } }
|
||||||
|
@ -97,7 +97,9 @@ describe "On a merge request diff", js: true, focus: true do
|
||||||
|
|
||||||
visit diffs_project_merge_request_path(project, merge_request)
|
visit diffs_project_merge_request_path(project, merge_request)
|
||||||
|
|
||||||
click_link("Diff")
|
within '.diffs-tab' do
|
||||||
|
click_link("Diff")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
subject { page }
|
subject { page }
|
||||||
|
@ -134,7 +136,9 @@ describe "On a merge request diff", js: true, focus: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should be removed when canceled" do
|
it "should be removed when canceled" do
|
||||||
find(".js-close-discussion-note-form").trigger("click")
|
within(".file form[rel$='4735dfc552ad7bf15ca468adc3cad9d05b624490_185_185']") do
|
||||||
|
find(".js-close-discussion-note-form").trigger("click")
|
||||||
|
end
|
||||||
|
|
||||||
should have_no_css(".js-temp-notes-holder")
|
should have_no_css(".js-temp-notes-holder")
|
||||||
end
|
end
|
|
@ -17,7 +17,7 @@ describe "On the project wall", js: true do
|
||||||
it { should have_css(".js-main-target-form", visible: true, count: 1) }
|
it { should have_css(".js-main-target-form", visible: true, count: 1) }
|
||||||
|
|
||||||
# button initalization
|
# button initalization
|
||||||
it { within(".js-main-target-form") { should have_button("Add Comment") } }
|
it { find(".js-main-target-form input[type=submit]").value.should == "Add Comment" }
|
||||||
it { within(".js-main-target-form") { should_not have_link("Cancel") } }
|
it { within(".js-main-target-form") { should_not have_link("Cancel") } }
|
||||||
|
|
||||||
# notifiactions
|
# notifiactions
|
||||||
|
@ -66,7 +66,7 @@ describe "On the project wall", js: true do
|
||||||
end
|
end
|
||||||
|
|
||||||
# note added
|
# note added
|
||||||
it { within(".js-main-target-form") { should have_content("This is awsome!") } }
|
it { should have_content("This is awsome!") }
|
||||||
|
|
||||||
# reset form
|
# reset form
|
||||||
it { within(".js-main-target-form") { should have_no_field("note[note]", with: "This is awesome!") } }
|
it { within(".js-main-target-form") { should have_no_field("note[note]", with: "This is awesome!") } }
|
|
@ -6,8 +6,11 @@ describe "Search" do
|
||||||
@project = create(:project)
|
@project = create(:project)
|
||||||
@project.team << [@user, :reporter]
|
@project.team << [@user, :reporter]
|
||||||
visit search_path
|
visit search_path
|
||||||
fill_in "search", with: @project.name[0..3]
|
|
||||||
click_button "Search"
|
within '.search-holder' do
|
||||||
|
fill_in "search", with: @project.name[0..3]
|
||||||
|
click_button "Search"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should show project in search results" do
|
it "should show project in search results" do
|
|
@ -72,7 +72,7 @@ describe "Snippets" do
|
||||||
author: @user,
|
author: @user,
|
||||||
project: project)
|
project: project)
|
||||||
visit project_snippet_path(project, @snippet)
|
visit project_snippet_path(project, @snippet)
|
||||||
click_link "Edit"
|
click_link "Edit Snippet"
|
||||||
end
|
end
|
||||||
|
|
||||||
it "should open edit page" do
|
it "should open edit page" do
|
19
spec/features/users_spec.rb
Normal file
19
spec/features/users_spec.rb
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe 'Users' do
|
||||||
|
describe "GET /users/sign_up" do
|
||||||
|
before do
|
||||||
|
Gitlab.config.gitlab.stub(:signup_enabled).and_return(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should create a new user account" do
|
||||||
|
visit new_user_registration_path
|
||||||
|
fill_in "user_name", with: "Name Surname"
|
||||||
|
fill_in "user_username", with: "Great"
|
||||||
|
fill_in "user_email", with: "name@mail.com"
|
||||||
|
fill_in "user_password", with: "password1234"
|
||||||
|
fill_in "user_password_confirmation", with: "password1234"
|
||||||
|
expect { click_button "Sign up" }.to change {User.count}.by(1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
29
spec/lib/popen_spec.rb
Normal file
29
spec/lib/popen_spec.rb
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe 'Gitlab::Popen', no_db: true do
|
||||||
|
let (:path) { Rails.root.join('tmp').to_s }
|
||||||
|
|
||||||
|
before do
|
||||||
|
@klass = Class.new(Object)
|
||||||
|
@klass.send(:include, Gitlab::Popen)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'zero status' do
|
||||||
|
before do
|
||||||
|
@output, @status = @klass.new.popen('ls', path)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { @status.should be_zero }
|
||||||
|
it { @output.should include('cache') }
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'non-zero status' do
|
||||||
|
before do
|
||||||
|
@output, @status = @klass.new.popen('cat NOTHING', path)
|
||||||
|
end
|
||||||
|
|
||||||
|
it { @status.should == 1 }
|
||||||
|
it { @output.should include('No such file or directory') }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -32,6 +32,12 @@ describe MergeRequest do
|
||||||
it { should_not allow_mass_assignment_of(:project_id) }
|
it { should_not allow_mass_assignment_of(:project_id) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "Respond to" do
|
||||||
|
it { should respond_to(:unchecked?) }
|
||||||
|
it { should respond_to(:can_be_merged?) }
|
||||||
|
it { should respond_to(:cannot_be_merged?) }
|
||||||
|
end
|
||||||
|
|
||||||
describe 'modules' do
|
describe 'modules' do
|
||||||
it { should include_module(Issuable) }
|
it { should include_module(Issuable) }
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,128 +0,0 @@
|
||||||
require 'spec_helper'
|
|
||||||
|
|
||||||
describe Project, "Hooks" do
|
|
||||||
let(:project) { create(:project) }
|
|
||||||
|
|
||||||
before do
|
|
||||||
@key = create(:key, user: project.owner)
|
|
||||||
@user = @key.user
|
|
||||||
@key_id = @key.identifier
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "Post Receive Event" do
|
|
||||||
it "should create push event" do
|
|
||||||
oldrev, newrev, ref = '00000000000000000000000000000000', 'newrev', 'refs/heads/master'
|
|
||||||
data = project.post_receive_data(oldrev, newrev, ref, @user)
|
|
||||||
|
|
||||||
project.observe_push(data)
|
|
||||||
event = Event.last
|
|
||||||
|
|
||||||
event.should_not be_nil
|
|
||||||
event.project.should == project
|
|
||||||
event.action.should == Event::PUSHED
|
|
||||||
event.data.should == data
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "Project hooks" do
|
|
||||||
context "with no web hooks" do
|
|
||||||
it "raises no errors" do
|
|
||||||
lambda {
|
|
||||||
project.execute_hooks({})
|
|
||||||
}.should_not raise_error
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "with web hooks" do
|
|
||||||
before do
|
|
||||||
@project_hook = create(:project_hook)
|
|
||||||
@project_hook_2 = create(:project_hook)
|
|
||||||
project.hooks << [@project_hook, @project_hook_2]
|
|
||||||
|
|
||||||
stub_request(:post, @project_hook.url)
|
|
||||||
stub_request(:post, @project_hook_2.url)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "executes multiple web hook" do
|
|
||||||
@project_hook.should_receive(:async_execute).once
|
|
||||||
@project_hook_2.should_receive(:async_execute).once
|
|
||||||
|
|
||||||
project.trigger_post_receive('oldrev', 'newrev', 'refs/heads/master', @user)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "does not execute web hooks" do
|
|
||||||
before do
|
|
||||||
@project_hook = create(:project_hook)
|
|
||||||
project.hooks << [@project_hook]
|
|
||||||
end
|
|
||||||
|
|
||||||
it "when pushing a branch for the first time" do
|
|
||||||
@project_hook.should_not_receive(:execute)
|
|
||||||
project.trigger_post_receive('00000000000000000000000000000000', 'newrev', 'refs/heads/master', @user)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "when pushing tags" do
|
|
||||||
@project_hook.should_not_receive(:execute)
|
|
||||||
project.trigger_post_receive('oldrev', 'newrev', 'refs/tags/v1.0.0', @user)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when pushing new branches" do
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
context "when gathering commit data" do
|
|
||||||
before do
|
|
||||||
@oldrev, @newrev, @ref = project.repository.fresh_commits(2).last.sha,
|
|
||||||
project.repository.fresh_commits(2).first.sha, 'refs/heads/master'
|
|
||||||
@commit = project.repository.fresh_commits(2).first
|
|
||||||
|
|
||||||
# Fill nil/empty attributes
|
|
||||||
project.description = "This is a description"
|
|
||||||
|
|
||||||
@data = project.post_receive_data(@oldrev, @newrev, @ref, @user)
|
|
||||||
end
|
|
||||||
|
|
||||||
subject { @data }
|
|
||||||
|
|
||||||
it { should include(before: @oldrev) }
|
|
||||||
it { should include(after: @newrev) }
|
|
||||||
it { should include(ref: @ref) }
|
|
||||||
it { should include(user_id: project.owner.id) }
|
|
||||||
it { should include(user_name: project.owner.name) }
|
|
||||||
|
|
||||||
context "with repository data" do
|
|
||||||
subject { @data[:repository] }
|
|
||||||
|
|
||||||
it { should include(name: project.name) }
|
|
||||||
it { should include(url: project.url_to_repo) }
|
|
||||||
it { should include(description: project.description) }
|
|
||||||
it { should include(homepage: project.web_url) }
|
|
||||||
end
|
|
||||||
|
|
||||||
context "with commits" do
|
|
||||||
subject { @data[:commits] }
|
|
||||||
|
|
||||||
it { should be_an(Array) }
|
|
||||||
it { should have(1).element }
|
|
||||||
|
|
||||||
context "the commit" do
|
|
||||||
subject { @data[:commits].first }
|
|
||||||
|
|
||||||
it { should include(id: @commit.id) }
|
|
||||||
it { should include(message: @commit.safe_message) }
|
|
||||||
it { should include(timestamp: @commit.date.xmlschema) }
|
|
||||||
it { should include(url: "#{Gitlab.config.gitlab.url}/#{project.code}/commit/#{@commit.id}") }
|
|
||||||
|
|
||||||
context "with a author" do
|
|
||||||
subject { @data[:commits].first[:author] }
|
|
||||||
|
|
||||||
it { should include(name: @commit.author_name) }
|
|
||||||
it { should include(email: @commit.author_email) }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -72,11 +72,8 @@ describe Project do
|
||||||
it { should respond_to(:url_to_repo) }
|
it { should respond_to(:url_to_repo) }
|
||||||
it { should respond_to(:repo_exists?) }
|
it { should respond_to(:repo_exists?) }
|
||||||
it { should respond_to(:satellite) }
|
it { should respond_to(:satellite) }
|
||||||
it { should respond_to(:observe_push) }
|
|
||||||
it { should respond_to(:update_merge_requests) }
|
it { should respond_to(:update_merge_requests) }
|
||||||
it { should respond_to(:execute_hooks) }
|
it { should respond_to(:execute_hooks) }
|
||||||
it { should respond_to(:post_receive_data) }
|
|
||||||
it { should respond_to(:trigger_post_receive) }
|
|
||||||
it { should respond_to(:transfer) }
|
it { should respond_to(:transfer) }
|
||||||
it { should respond_to(:name_with_namespace) }
|
it { should respond_to(:name_with_namespace) }
|
||||||
it { should respond_to(:namespace_owner) }
|
it { should respond_to(:namespace_owner) }
|
||||||
|
|
|
@ -10,9 +10,6 @@ describe ProjectTeam do
|
||||||
it { should respond_to(:masters) }
|
it { should respond_to(:masters) }
|
||||||
it { should respond_to(:reporters) }
|
it { should respond_to(:reporters) }
|
||||||
it { should respond_to(:guests) }
|
it { should respond_to(:guests) }
|
||||||
it { should respond_to(:repository_writers) }
|
|
||||||
it { should respond_to(:repository_masters) }
|
|
||||||
it { should respond_to(:repository_readers) }
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -69,28 +69,10 @@ describe User do
|
||||||
|
|
||||||
describe "Respond to" do
|
describe "Respond to" do
|
||||||
it { should respond_to(:is_admin?) }
|
it { should respond_to(:is_admin?) }
|
||||||
it { should respond_to(:identifier) }
|
|
||||||
it { should respond_to(:name) }
|
it { should respond_to(:name) }
|
||||||
it { should respond_to(:private_token) }
|
it { should respond_to(:private_token) }
|
||||||
end
|
end
|
||||||
|
|
||||||
describe '#identifier' do
|
|
||||||
it "should return valid identifier" do
|
|
||||||
user = build(:user, email: "test@mail.com")
|
|
||||||
user.identifier.should == "test_mail_com"
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should return identifier without + sign" do
|
|
||||||
user = build(:user, email: "test+foo@mail.com")
|
|
||||||
user.identifier.should == "test_foo_mail_com"
|
|
||||||
end
|
|
||||||
|
|
||||||
it "should conform to Gitolite's required identifier pattern" do
|
|
||||||
user = build(:user, email: "_test@example.com")
|
|
||||||
user.identifier.should == 'test_example_com'
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe '#generate_password' do
|
describe '#generate_password' do
|
||||||
it "should execute callback when force_random_password specified" do
|
it "should execute callback when force_random_password specified" do
|
||||||
user = build(:user, force_random_password: true)
|
user = build(:user, force_random_password: true)
|
||||||
|
|
103
spec/requests/api/internal_spec.rb
Normal file
103
spec/requests/api/internal_spec.rb
Normal file
|
@ -0,0 +1,103 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe Gitlab::API do
|
||||||
|
include ApiHelpers
|
||||||
|
|
||||||
|
let(:user) { create(:user) }
|
||||||
|
let(:key) { create(:key, user: user) }
|
||||||
|
let(:project) { create(:project) }
|
||||||
|
|
||||||
|
describe "GET /internal/check", no_db: true do
|
||||||
|
it do
|
||||||
|
get api("/internal/check")
|
||||||
|
|
||||||
|
response.status.should == 200
|
||||||
|
json_response['api_version'].should == Gitlab::API.version
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "GET /internal/discover" do
|
||||||
|
it do
|
||||||
|
get(api("/internal/discover"), key_id: key.id)
|
||||||
|
|
||||||
|
response.status.should == 200
|
||||||
|
|
||||||
|
json_response['email'].should == user.email
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "GET /internal/allowed" do
|
||||||
|
context "access granted" do
|
||||||
|
before do
|
||||||
|
project.team << [user, :developer]
|
||||||
|
end
|
||||||
|
|
||||||
|
context "git pull" do
|
||||||
|
it do
|
||||||
|
get(
|
||||||
|
api("/internal/allowed"),
|
||||||
|
ref: 'master',
|
||||||
|
key_id: key.id,
|
||||||
|
project: project.path_with_namespace,
|
||||||
|
action: 'git-upload-pack'
|
||||||
|
)
|
||||||
|
|
||||||
|
response.status.should == 200
|
||||||
|
response.body.should == 'true'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "git push" do
|
||||||
|
it do
|
||||||
|
get(
|
||||||
|
api("/internal/allowed"),
|
||||||
|
ref: 'master',
|
||||||
|
key_id: key.id,
|
||||||
|
project: project.path_with_namespace,
|
||||||
|
action: 'git-receive-pack'
|
||||||
|
)
|
||||||
|
|
||||||
|
response.status.should == 200
|
||||||
|
response.body.should == 'true'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "access denied" do
|
||||||
|
before do
|
||||||
|
project.team << [user, :guest]
|
||||||
|
end
|
||||||
|
|
||||||
|
context "git pull" do
|
||||||
|
it do
|
||||||
|
get(
|
||||||
|
api("/internal/allowed"),
|
||||||
|
ref: 'master',
|
||||||
|
key_id: key.id,
|
||||||
|
project: project.path_with_namespace,
|
||||||
|
action: 'git-upload-pack'
|
||||||
|
)
|
||||||
|
|
||||||
|
response.status.should == 200
|
||||||
|
response.body.should == 'false'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "git push" do
|
||||||
|
it do
|
||||||
|
get(
|
||||||
|
api("/internal/allowed"),
|
||||||
|
ref: 'master',
|
||||||
|
key_id: key.id,
|
||||||
|
project: project.path_with_namespace,
|
||||||
|
action: 'git-receive-pack'
|
||||||
|
)
|
||||||
|
|
||||||
|
response.status.should == 200
|
||||||
|
response.body.should == 'false'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
|
@ -97,32 +97,27 @@ describe Gitlab::API do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "GET /users/sign_up" do
|
describe "GET /users/sign_up" do
|
||||||
before do
|
context 'enabled' do
|
||||||
Gitlab.config.gitlab.stub(:signup_enabled).and_return(false)
|
before do
|
||||||
end
|
Gitlab.config.gitlab.stub(:signup_enabled).and_return(true)
|
||||||
it "should redirect to sign in page if signup is disabled" do
|
end
|
||||||
get "/users/sign_up"
|
|
||||||
response.status.should == 302
|
|
||||||
response.should redirect_to(new_user_session_path)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
describe "GET /users/sign_up" do
|
it "should return sign up page if signup is enabled" do
|
||||||
before do
|
get "/users/sign_up"
|
||||||
Gitlab.config.gitlab.stub(:signup_enabled).and_return(true)
|
response.status.should == 200
|
||||||
|
end
|
||||||
end
|
end
|
||||||
it "should return sign up page if signup is enabled" do
|
|
||||||
get "/users/sign_up"
|
context 'disabled' do
|
||||||
response.status.should == 200
|
before do
|
||||||
end
|
Gitlab.config.gitlab.stub(:signup_enabled).and_return(false)
|
||||||
it "should create a new user account" do
|
end
|
||||||
visit new_user_registration_path
|
|
||||||
fill_in "user_name", with: "Name Surname"
|
it "should redirect to sign in page if signup is disabled" do
|
||||||
fill_in "user_username", with: "Great"
|
get "/users/sign_up"
|
||||||
fill_in "user_email", with: "name@mail.com"
|
response.status.should == 302
|
||||||
fill_in "user_password", with: "password1234"
|
response.should redirect_to(new_user_session_path)
|
||||||
fill_in "user_password_confirmation", with: "password1234"
|
end
|
||||||
expect { click_button "Sign up" }.to change {User.count}.by(1)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
111
spec/services/git_push_service.rb
Normal file
111
spec/services/git_push_service.rb
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe GitPushService do
|
||||||
|
let (:user) { create :user }
|
||||||
|
let (:project) { create :project }
|
||||||
|
let (:service) { GitPushService.new }
|
||||||
|
|
||||||
|
before do
|
||||||
|
@oldrev = 'b98a310def241a6fd9c9a9a3e7934c48e498fe81'
|
||||||
|
@newrev = 'b19a04f53caeebf4fe5ec2327cb83e9253dc91bb'
|
||||||
|
@ref = 'refs/heads/master'
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Git Push Data" do
|
||||||
|
before do
|
||||||
|
service.execute(project, user, @oldrev, @newrev, @ref)
|
||||||
|
@push_data = service.push_data
|
||||||
|
@commit = project.repository.commit(@newrev)
|
||||||
|
end
|
||||||
|
|
||||||
|
subject { @push_data }
|
||||||
|
|
||||||
|
it { should include(before: @oldrev) }
|
||||||
|
it { should include(after: @newrev) }
|
||||||
|
it { should include(ref: @ref) }
|
||||||
|
it { should include(user_id: user.id) }
|
||||||
|
it { should include(user_name: user.name) }
|
||||||
|
|
||||||
|
context "with repository data" do
|
||||||
|
subject { @push_data[:repository] }
|
||||||
|
|
||||||
|
it { should include(name: project.name) }
|
||||||
|
it { should include(url: project.url_to_repo) }
|
||||||
|
it { should include(description: project.description) }
|
||||||
|
it { should include(homepage: project.web_url) }
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with commits" do
|
||||||
|
subject { @push_data[:commits] }
|
||||||
|
|
||||||
|
it { should be_an(Array) }
|
||||||
|
it { should have(1).element }
|
||||||
|
|
||||||
|
context "the commit" do
|
||||||
|
subject { @push_data[:commits].first }
|
||||||
|
|
||||||
|
it { should include(id: @commit.id) }
|
||||||
|
it { should include(message: @commit.safe_message) }
|
||||||
|
it { should include(timestamp: @commit.date.xmlschema) }
|
||||||
|
it { should include(url: "#{Gitlab.config.gitlab.url}/#{project.code}/commit/#{@commit.id}") }
|
||||||
|
|
||||||
|
context "with a author" do
|
||||||
|
subject { @push_data[:commits].first[:author] }
|
||||||
|
|
||||||
|
it { should include(name: @commit.author_name) }
|
||||||
|
it { should include(email: @commit.author_email) }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Push Event" do
|
||||||
|
before do
|
||||||
|
service.execute(project, user, @oldrev, @newrev, @ref)
|
||||||
|
@event = Event.last
|
||||||
|
end
|
||||||
|
|
||||||
|
it { @event.should_not be_nil }
|
||||||
|
it { @event.project.should == project }
|
||||||
|
it { @event.action.should == Event::PUSHED }
|
||||||
|
it { @event.data.should == service.push_data }
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "Web Hooks" do
|
||||||
|
context "with web hooks" do
|
||||||
|
before do
|
||||||
|
@project_hook = create(:project_hook)
|
||||||
|
@project_hook_2 = create(:project_hook)
|
||||||
|
project.hooks << [@project_hook, @project_hook_2]
|
||||||
|
|
||||||
|
stub_request(:post, @project_hook.url)
|
||||||
|
stub_request(:post, @project_hook_2.url)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "executes multiple web hook" do
|
||||||
|
@project_hook.should_receive(:async_execute).once
|
||||||
|
@project_hook_2.should_receive(:async_execute).once
|
||||||
|
|
||||||
|
service.execute(project, user, @oldrev, @newrev, @ref)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "does not execute web hooks" do
|
||||||
|
before do
|
||||||
|
@project_hook = create(:project_hook)
|
||||||
|
project.hooks << [@project_hook]
|
||||||
|
end
|
||||||
|
|
||||||
|
it "when pushing a branch for the first time" do
|
||||||
|
@project_hook.should_not_receive(:execute)
|
||||||
|
service.execute(project, user, '00000000000000000000000000000000', 'newrev', 'refs/heads/master')
|
||||||
|
end
|
||||||
|
|
||||||
|
it "when pushing tags" do
|
||||||
|
@project_hook.should_not_receive(:execute)
|
||||||
|
service.execute(project, user, 'newrev', 'newrev', 'refs/tags/v1.0.0')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
41
spec/services/system_hooks_service_spec.rb
Normal file
41
spec/services/system_hooks_service_spec.rb
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
describe SystemHooksService do
|
||||||
|
let (:user) { create :user }
|
||||||
|
let (:project) { create :project }
|
||||||
|
let (:users_project) { create :users_project }
|
||||||
|
|
||||||
|
context 'it should build event data' do
|
||||||
|
it 'should build event data for user' do
|
||||||
|
SystemHooksService.build_event_data(user, :create).should include(:event_name, :name, :created_at, :email)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should build event data for project' do
|
||||||
|
SystemHooksService.build_event_data(project, :create).should include(:event_name, :name, :created_at, :path, :project_id, :owner_name, :owner_email)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should build event data for users project' do
|
||||||
|
SystemHooksService.build_event_data(users_project, :create).should include(:event_name, :created_at, :project_name, :project_path, :project_id, :user_name, :user_email, :project_access)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'it should build event names' do
|
||||||
|
it 'should build event names for user' do
|
||||||
|
SystemHooksService.build_event_name(user, :create).should eq "user_create"
|
||||||
|
|
||||||
|
SystemHooksService.build_event_name(user, :destroy).should eq "user_destroy"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should build event names for project' do
|
||||||
|
SystemHooksService.build_event_name(project, :create).should eq "project_create"
|
||||||
|
|
||||||
|
SystemHooksService.build_event_name(project, :destroy).should eq "project_destroy"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should build event names for users project' do
|
||||||
|
SystemHooksService.build_event_name(users_project, :create).should eq "user_add_to_team"
|
||||||
|
|
||||||
|
SystemHooksService.build_event_name(users_project, :destroy).should eq "user_remove_from_team"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -10,19 +10,19 @@ require 'capybara/rspec'
|
||||||
require 'webmock/rspec'
|
require 'webmock/rspec'
|
||||||
require 'email_spec'
|
require 'email_spec'
|
||||||
require 'sidekiq/testing/inline'
|
require 'sidekiq/testing/inline'
|
||||||
|
require 'capybara/poltergeist'
|
||||||
|
Capybara.javascript_driver = :poltergeist
|
||||||
|
|
||||||
# Requires supporting ruby files with custom matchers and macros, etc,
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
||||||
# in spec/support/ and its subdirectories.
|
# in spec/support/ and its subdirectories.
|
||||||
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
|
Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
|
||||||
|
|
||||||
require 'capybara/poltergeist'
|
|
||||||
Capybara.javascript_driver = :poltergeist
|
|
||||||
|
|
||||||
WebMock.disable_net_connect!(allow_localhost: true)
|
WebMock.disable_net_connect!(allow_localhost: true)
|
||||||
|
|
||||||
RSpec.configure do |config|
|
RSpec.configure do |config|
|
||||||
config.mock_with :rspec
|
config.mock_with :rspec
|
||||||
|
|
||||||
|
config.include LoginHelpers, type: :feature
|
||||||
config.include LoginHelpers, type: :request
|
config.include LoginHelpers, type: :request
|
||||||
config.include FactoryGirl::Syntax::Methods
|
config.include FactoryGirl::Syntax::Methods
|
||||||
config.include Devise::TestHelpers, type: :controller
|
config.include Devise::TestHelpers, type: :controller
|
||||||
|
|
|
@ -9,10 +9,14 @@ RSpec.configure do |config|
|
||||||
DatabaseCleaner.strategy = :transaction
|
DatabaseCleaner.strategy = :transaction
|
||||||
end
|
end
|
||||||
|
|
||||||
DatabaseCleaner.start
|
unless example.metadata[:no_db]
|
||||||
|
DatabaseCleaner.start
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
config.after do
|
config.after do
|
||||||
DatabaseCleaner.clean
|
unless example.metadata[:no_db]
|
||||||
|
DatabaseCleaner.clean
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
require "repository"
|
require "repository"
|
||||||
require "project"
|
require "project"
|
||||||
|
require "merge_request"
|
||||||
require "shell"
|
require "shell"
|
||||||
|
|
||||||
# Stubs out all Git repository access done by models so that specs can run
|
# Stubs out all Git repository access done by models so that specs can run
|
||||||
|
@ -32,6 +33,12 @@ class Project
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class MergeRequest
|
||||||
|
def check_if_can_be_merged
|
||||||
|
true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
class GitLabTestRepo < Repository
|
class GitLabTestRepo < Repository
|
||||||
def repo
|
def repo
|
||||||
@repo ||= Grit::Repo.new(Rails.root.join('tmp', 'repositories', 'gitlabhq'))
|
@repo ||= Grit::Repo.new(Rails.root.join('tmp', 'repositories', 'gitlabhq'))
|
||||||
|
|
|
@ -21,7 +21,6 @@ describe PostReceive do
|
||||||
it "does not run if the author is not in the project" do
|
it "does not run if the author is not in the project" do
|
||||||
Key.stub(find_by_id: nil)
|
Key.stub(find_by_id: nil)
|
||||||
|
|
||||||
project.should_not_receive(:observe_push)
|
|
||||||
project.should_not_receive(:execute_hooks)
|
project.should_not_receive(:execute_hooks)
|
||||||
|
|
||||||
PostReceive.new.perform(pwd(project), 'sha-old', 'sha-new', 'refs/heads/master', key_id).should be_false
|
PostReceive.new.perform(pwd(project), 'sha-old', 'sha-new', 'refs/heads/master', key_id).should be_false
|
||||||
|
@ -32,7 +31,6 @@ describe PostReceive do
|
||||||
project.should_receive(:execute_hooks)
|
project.should_receive(:execute_hooks)
|
||||||
project.should_receive(:execute_services)
|
project.should_receive(:execute_services)
|
||||||
project.should_receive(:update_merge_requests)
|
project.should_receive(:update_merge_requests)
|
||||||
project.should_receive(:observe_push)
|
|
||||||
|
|
||||||
PostReceive.new.perform(pwd(project), 'sha-old', 'sha-new', 'refs/heads/master', key_id)
|
PostReceive.new.perform(pwd(project), 'sha-old', 'sha-new', 'refs/heads/master', key_id)
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue