Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--CHANGELOG11
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--Gemfile12
-rw-r--r--Gemfile.lock76
-rw-r--r--README.md26
-rw-r--r--VERSION2
-rw-r--r--app/assets/javascripts/main.js.coffee3
-rw-r--r--app/assets/javascripts/wall.js.coffee4
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/files.scss9
-rw-r--r--app/assets/stylesheets/gitlab_bootstrap/typography.scss4
-rw-r--r--app/controllers/application_controller.rb2
-rw-r--r--app/controllers/profiles_controller.rb15
-rw-r--r--app/controllers/projects_controller.rb4
-rw-r--r--app/controllers/services_controller.rb19
-rw-r--r--app/helpers/application_helper.rb4
-rw-r--r--app/helpers/oauth_helper.rb13
-rw-r--r--app/helpers/projects_helper.rb4
-rw-r--r--app/helpers/user_teams_helper.rb1
-rw-r--r--app/models/campfire_service.rb76
-rw-r--r--app/models/gitlab_ci_service.rb19
-rw-r--r--app/models/hipchat_service.rb73
-rw-r--r--app/models/merge_request.rb20
-rw-r--r--app/models/project.rb41
-rw-r--r--app/models/service.rb23
-rw-r--r--app/models/user.rb4
-rw-r--r--app/observers/project_observer.rb1
-rw-r--r--app/services/system_hooks_service.rb1
-rw-r--r--app/views/admin/projects/index.html.haml2
-rw-r--r--app/views/devise/sessions/_new_base.html.haml13
-rw-r--r--app/views/devise/sessions/_new_ldap.html.haml28
-rw-r--r--app/views/devise/sessions/_oauth_providers.html.haml10
-rw-r--r--app/views/devise/sessions/new.html.haml59
-rw-r--r--app/views/edit_tree/show.html.haml2
-rw-r--r--app/views/help/index.html.haml2
-rw-r--r--app/views/layouts/_google_analytics.html.haml2
-rw-r--r--app/views/layouts/_head.html.haml2
-rw-r--r--app/views/merge_requests/show/_diffs.html.haml2
-rw-r--r--app/views/milestones/index.html.haml8
-rw-r--r--app/views/profiles/account.html.haml63
-rw-r--r--app/views/projects/edit.html.haml22
-rw-r--r--app/views/projects/empty.html.haml2
-rw-r--r--app/views/services/_form.html.haml48
-rw-r--r--app/views/services/_gitlab_ci.html.haml46
-rw-r--r--app/views/services/edit.html.haml2
-rw-r--r--app/views/services/index.html.haml38
-rw-r--r--config/gitlab.yml.example2
-rw-r--r--config/initializers/secret_token.rb18
-rw-r--r--db/migrate/20130522141856_add_more_fields_to_service.rb6
-rw-r--r--db/schema.rb4
-rw-r--r--doc/api/README.md20
-rw-r--r--doc/install/installation.md32
-rw-r--r--doc/raketasks/maintenance.md9
-rw-r--r--features/project/service.feature6
-rw-r--r--features/project/source/search_code.feature6
-rw-r--r--features/steps/project/project_search_code.rb8
-rw-r--r--features/steps/project/project_services.rb25
-rw-r--r--lib/api/api.rb1
-rw-r--r--lib/api/projects.rb115
-rw-r--r--lib/api/repositories.rb133
-rw-r--r--lib/gitlab/auth.rb19
-rw-r--r--lib/gitlab/backend/grack_auth.rb61
-rw-r--r--lib/support/init.d/gitlab2
-rw-r--r--lib/tasks/gitlab/check.rake20
-rw-r--r--lib/tasks/gitlab/import.rake47
-rw-r--r--spec/features/gitlab_flavored_markdown_spec.rb2
-rw-r--r--spec/helpers/gitlab_markdown_helper_spec.rb2
-rw-r--r--spec/models/project_spec.rb4
-rw-r--r--spec/requests/api/projects_spec.rb120
-rw-r--r--spec/requests/api/repositories_spec.rb135
70 files changed, 1043 insertions, 575 deletions
diff --git a/.gitignore b/.gitignore
index 2a7e605a350..1210ac3b44a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,3 +29,4 @@ db/data.yml
vendor/bundle/*
rails_best_practices_output.html
doc/code/*
+.secret
diff --git a/CHANGELOG b/CHANGELOG
index f21a9e8a943..8ef925702c6 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,14 @@
+v 5.3.0
+ - Refactored services
+ - Campfire service added
+ - HipChat service added
+ - Fixed bug with LDAP + git over http
+ - Fixed bug with google analytics code being ignored
+ - Improve sign-in page if ldap enabled
+ - Respect newlines in wall messages
+ - Generate the Rails secret token on first run
+ - Rename repo feature
+
v 5.2.0
- Turbolinks
- Git over http with ldap credentials
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 5d13909b8a0..7038f76ff88 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -8,7 +8,7 @@ Issues and pull requests not in line with the guidelines listed in this document
## Issue tracker
-The [issue tracker](https://github.com/gitlabhq/gitlabhq/issues) is only for obvious bugs or misbehavior in the master branch of GitLab. When submitting an issue please conform to the issue submission guidelines listed below.
+The [issue tracker](https://github.com/gitlabhq/gitlabhq/issues) is only for obvious bugs or misbehavior in the latest [stable or development release of GitLab](MAINTENANCE.md). When submitting an issue please conform to the issue submission guidelines listed below.
Do not use the issue tracker for feature requests. We have a specific
[feedback and suggestions forum](http://feedback.gitlab.com) for this purpose.
diff --git a/Gemfile b/Gemfile
index 2bc55bfa1cd..924d8a27254 100644
--- a/Gemfile
+++ b/Gemfile
@@ -101,6 +101,12 @@ gem "foreman"
# Cache
gem "redis-rails"
+# Campfire integration
+gem 'tinder', '~> 1.9.2'
+
+# HipChat integration
+gem "hipchat", "~> 0.9.0"
+
group :assets do
gem "sass-rails"
gem "coffee-rails"
@@ -116,7 +122,7 @@ group :assets do
gem "jquery-ui-rails", "2.0.2"
gem "modernizr", "2.6.2"
gem "raphael-rails", git: "https://github.com/gitlabhq/raphael-rails.git"
- gem 'bootstrap-sass', "2.2.1.1"
+ gem 'bootstrap-sass'
gem "font-awesome-sass-rails", "~> 3.0.0"
gem "gemoji", "~> 1.2.1", require: 'emoji/railtie'
gem "gon"
@@ -168,14 +174,14 @@ group :development, :test do
gem 'rb-inotify', require: linux_only('rb-inotify')
# PhantomJS driver for Capybara
- gem 'poltergeist', git: 'https://github.com/jonleighton/poltergeist.git', ref: '9645b52009e258921b860d3b7601d00008b22c45'
+ gem 'poltergeist', '~> 1.3.0'
gem 'spork', '~> 1.0rc'
end
group :test do
gem "simplecov", require: false
- gem "shoulda-matchers", "1.3.0"
+ gem "shoulda-matchers", "~> 2.1.0"
gem 'email_spec'
gem "webmock"
gem 'test_after_commit'
diff --git a/Gemfile.lock b/Gemfile.lock
index 93798439d8c..48be954c0c5 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -12,16 +12,6 @@ GIT
specs:
raphael-rails (2.1.0)
-GIT
- remote: https://github.com/jonleighton/poltergeist.git
- revision: 9645b52009e258921b860d3b7601d00008b22c45
- ref: 9645b52009e258921b860d3b7601d00008b22c45
- specs:
- poltergeist (1.1.0)
- capybara (~> 2.0, >= 2.0.1)
- faye-websocket (~> 0.4, >= 0.4.4)
- http_parser.rb (~> 0.5.3)
-
GEM
remote: https://rubygems.org/
specs:
@@ -64,7 +54,7 @@ GEM
erubis (>= 2.6.6)
binding_of_caller (0.7.1)
debug_inspector (>= 0.0.1)
- bootstrap-sass (2.2.1.1)
+ bootstrap-sass (2.3.1.0)
sass (~> 3.2)
builder (3.0.4)
capybara (2.1.0)
@@ -76,7 +66,7 @@ GEM
carrierwave (0.8.0)
activemodel (>= 3.2.0)
activesupport (>= 3.2.0)
- celluloid (0.13.0)
+ celluloid (0.14.0)
timers (>= 1.0.0)
charlock_holmes (0.6.9.4)
chosen-rails (0.9.8)
@@ -103,10 +93,10 @@ GEM
thor
crack (0.3.2)
daemons (1.1.9)
- database_cleaner (0.9.1)
+ database_cleaner (1.0.1)
debug_inspector (0.0.2)
descendants_tracker (0.0.1)
- devise (2.2.3)
+ devise (2.2.4)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.1)
railties (~> 3.1)
@@ -130,6 +120,8 @@ GEM
railties (>= 3.0.0)
faraday (0.8.7)
multipart-post (~> 1.1)
+ faraday_middleware (0.9.0)
+ faraday (>= 0.7.4, < 0.9)
faye-websocket (0.4.7)
eventmachine (>= 0.12.0)
ffaker (1.16.0)
@@ -201,7 +193,7 @@ GEM
lumberjack (>= 1.0.2)
pry (>= 0.9.10)
thor (>= 0.14.6)
- guard-rspec (2.6.0)
+ guard-rspec (3.0.0)
guard (>= 1.8)
rspec (~> 2.13)
guard-spinach (0.0.2)
@@ -214,8 +206,10 @@ GEM
activesupport (>= 3.1, < 4.1)
haml (>= 3.1, < 4.1)
railties (>= 3.1, < 4.1)
- hashie (2.0.4)
+ hashie (1.2.0)
hike (1.2.2)
+ hipchat (0.9.0)
+ httparty
http_parser.rb (0.5.3)
httparty (0.11.0)
multi_json (~> 1.0)
@@ -244,7 +238,7 @@ GEM
letter_opener (1.1.0)
launchy (~> 2.2.0)
libv8 (3.11.8.17)
- listen (1.0.3)
+ listen (1.1.3)
rb-fsevent (>= 0.9.3)
rb-inotify (>= 0.9)
rb-kqueue (>= 0.2)
@@ -258,7 +252,7 @@ GEM
minitest (4.7.4)
modernizr (2.6.2)
sprockets (~> 2.0)
- multi_json (1.7.2)
+ multi_json (1.7.3)
multi_xml (0.5.3)
multipart-post (1.2.0)
mysql2 (0.3.11)
@@ -291,9 +285,13 @@ GEM
omniauth-oauth (~> 1.0)
orm_adapter (0.4.0)
pg (0.15.1)
+ poltergeist (1.3.0)
+ capybara (~> 2.1.0)
+ faye-websocket (>= 0.4.4, < 0.5.0)
+ http_parser.rb (~> 0.5.3)
polyglot (0.3.3)
posix-spawn (0.3.6)
- pry (0.9.12.1)
+ pry (0.9.12.2)
coderay (~> 1.0.5)
method_source (~> 0.8)
slop (~> 3.4)
@@ -363,7 +361,7 @@ GEM
redis-activesupport (3.2.3)
activesupport (~> 3.2.3)
redis-store (~> 1.1.0)
- redis-namespace (1.2.1)
+ redis-namespace (1.3.0)
redis (~> 3.0.0)
redis-rack (1.4.2)
rack (~> 1.4.1)
@@ -396,7 +394,7 @@ GEM
rubyntlm (0.1.1)
sanitize (2.0.3)
nokogiri (>= 1.4.4, < 1.6)
- sass (3.2.8)
+ sass (3.2.9)
sass-rails (3.2.6)
railties (~> 3.2.0)
sass (>= 3.1.10)
@@ -412,14 +410,15 @@ GEM
thor (~> 0.14)
settingslogic (2.0.9)
sexp_processor (4.2.1)
- shoulda-matchers (1.3.0)
+ shoulda-matchers (2.1.0)
activesupport (>= 3.0.0)
- sidekiq (2.11.1)
- celluloid (~> 0.13.0)
- connection_pool (~> 1.0)
- multi_json (~> 1)
- redis (~> 3)
+ sidekiq (2.12.0)
+ celluloid (>= 0.14.0)
+ connection_pool (>= 1.0.0)
+ json
+ redis (>= 3.0)
redis-namespace
+ simple_oauth (0.1.9)
simplecov (0.7.1)
multi_json (~> 1.0)
simplecov-html (~> 0.7.1)
@@ -432,7 +431,7 @@ GEM
slim (1.3.8)
temple (~> 0.6.3)
tilt (~> 1.3.3)
- slop (3.4.4)
+ slop (3.4.5)
spinach (0.8.2)
colorize (= 0.5.8)
gherkin-ruby (~> 0.3.0)
@@ -461,11 +460,24 @@ GEM
thor (0.18.1)
tilt (1.3.7)
timers (1.1.0)
+ tinder (1.9.2)
+ eventmachine (~> 1.0)
+ faraday (~> 0.8)
+ faraday_middleware (~> 0.9)
+ hashie (~> 1.0)
+ json (~> 1.7.5)
+ mime-types (~> 1.19)
+ multi_json (~> 1.5)
+ twitter-stream (~> 0.1)
treetop (1.4.12)
polyglot
polyglot (>= 0.3.1)
turbolinks (1.1.1)
coffee-rails
+ twitter-stream (0.1.16)
+ eventmachine (>= 0.12.8)
+ http_parser.rb (~> 0.5.1)
+ simple_oauth (~> 0.1.4)
tzinfo (0.3.37)
uglifier (2.0.1)
execjs (>= 0.3.0)
@@ -491,7 +503,7 @@ DEPENDENCIES
awesome_print
better_errors
binding_of_caller
- bootstrap-sass (= 2.2.1.1)
+ bootstrap-sass
capybara
carrierwave
chosen-rails (= 0.9.8)
@@ -522,6 +534,7 @@ DEPENDENCIES
guard-rspec
guard-spinach
haml-rails
+ hipchat (~> 0.9.0)
httparty
jquery-atwho-rails (= 0.3.0)
jquery-rails (= 2.1.3)
@@ -538,7 +551,7 @@ DEPENDENCIES
omniauth-google-oauth2
omniauth-twitter
pg
- poltergeist!
+ poltergeist (~> 1.3.0)
pry
puma (~> 2.0.1)
quiet_assets (~> 1.0.1)
@@ -557,7 +570,7 @@ DEPENDENCIES
seed-fu
select2-rails
settingslogic
- shoulda-matchers (= 1.3.0)
+ shoulda-matchers (~> 2.1.0)
sidekiq
simplecov
sinatra
@@ -570,6 +583,7 @@ DEPENDENCIES
test_after_commit
therubyracer
thin
+ tinder (~> 1.9.2)
turbolinks
uglifier
webmock
diff --git a/README.md b/README.md
index 7f0ae041ead..2d8113c03b1 100644
--- a/README.md
+++ b/README.md
@@ -28,9 +28,9 @@
### Resources
-* GitLab.org community site: [Homepage](http://gitlab.org) [Screenshots](http://gitlab.org/screenshots/) [Blog](http://blog.gitlab.org/) [Demo](http://demo.gitlabhq.com/users/sign_in)
+* GitLab.org community site: [Homepage](http://gitlab.org) | [Screenshots](http://gitlab.org/screenshots/) | [Blog](http://blog.gitlab.org/) | [Demo](http://demo.gitlabhq.com/users/sign_in)
-* GitLab.com commercial services: [Homepage](http://www.gitlab.com/) [Subscription](http://www.gitlab.com/subscription/) [Consultancy](http://www.gitlab.com/consultancy/) [GitLab Cloud](http://www.gitlab.com/cloud/) [Blog](http://blog.gitlab.com/)
+* GitLab.com commercial services: [Homepage](http://www.gitlab.com/) | [Subscription](http://www.gitlab.com/subscription/) | [Consultancy](http://www.gitlab.com/consultancy/) | [GitLab Cloud](http://www.gitlab.com/cloud/) | [Blog](http://blog.gitlab.com/)
* GitLab CI: [Readme](https://github.com/gitlabhq/gitlab-ci/blob/master/README.md) of the GitLab open-source continuous integration server
@@ -43,13 +43,13 @@
* gitlab-shell
* redis
-** More details are in the [requirements doc](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/requirements.md)
+** More details are in the [requirements doc](doc/install/requirements.md)
### Installation
#### Official production installation
-* [Installation guide for a production server](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/installation.md)
+* [Installation guide for a production server](doc/install/installation.md)
#### Official development installation
@@ -72,18 +72,18 @@ If you want to contribute, please first read our [Contributing Guidelines](https
### New versions and upgrading
-Each month on the 22th a new version is released together with an upgrade guide.
+Each month on the 22nd a new version is released together with an upgrade guide.
-* [Upgrade guides](https://github.com/gitlabhq/gitlabhq/tree/master/doc/update)
+* [Upgrade guides](doc/update)
-* [Changelog](https://github.com/gitlabhq/gitlabhq/blob/master/CHANGELOG)
+* [Changelog](CHANGELOG)
* Features that will be in the next release are listed on [the feedback and suggestions forum with the status "started"](http://feedback.gitlab.com/forums/176466-general/status/796456).
### Run in production mode
-1. The Installation guide contains instructions on how to download an init script and run it automatically on boot. You can also start the init script manually:
+ The Installation guide contains instructions on how to download an init script and run it automatically on boot. You can also start the init script manually:
sudo service gitlab start
@@ -124,13 +124,13 @@ Start it with [Foreman](https://github.com/ddollar/foreman)
### GitLab interfaces
-* [GitLab API](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/README.md)
+* [GitLab API](doc/api/README.md)
-* [Rake tasks](https://github.com/gitlabhq/gitlabhq/tree/master/doc/raketasks)
+* [Rake tasks](doc/raketasks)
-* [Directory structure](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/structure.md)
+* [Directory structure](doc/install/structure.md)
-* [Databases](https://github.com/gitlabhq/gitlabhq/blob/master/doc/install/databases.md)
+* [Databases](doc/install/databases.md)
### Getting help
@@ -139,7 +139,7 @@ Start it with [Foreman](https://github.com/ddollar/foreman)
* [Troubleshooting guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide) contains solutions to common problems.
-* [Support forum](https://groups.google.com/forum/#!forum/gitlabhq) is the best place to ask questions. For example you can use it if you have questions about: permission denied errors, invisible repos, can't clone/pull/push or with web hooks that don't fire. Please search for similar issues before posting your own, there's a good chance somebody else had the same issue you have now and had it resolved. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there to a fix.
+* [Support forum](https://groups.google.com/forum/#!forum/gitlabhq) and [Stack Overflow](http://stackoverflow.com/questions/tagged/gitlab) are the best places to ask questions. For example you can use it if you have questions about: permission denied errors, invisible repos, can't clone/pull/push or with web hooks that don't fire. Please search for similar issues before posting your own, there's a good chance somebody else had the same issue you have now and has resolved it. There are a lot of helpful GitLab users there who may be able to help you quickly. If your particular issue turns out to be a bug, it will find its way from there to a fix.
* [Feedback and suggestions forum](http://feedback.gitlab.com) is the place to propose and discuss new features for GitLab.
diff --git a/VERSION b/VERSION
index 9f1dc66617e..91ff57278e3 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-5.2.0.rc1
+5.2.0
diff --git a/app/assets/javascripts/main.js.coffee b/app/assets/javascripts/main.js.coffee
index 45ef44fcc04..65005d6f617 100644
--- a/app/assets/javascripts/main.js.coffee
+++ b/app/assets/javascripts/main.js.coffee
@@ -41,6 +41,9 @@ window.linkify = (str) ->
exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig
return str.replace(exp,"<a href='$1'>$1</a>")
+window.simpleFormat = (str) ->
+ linkify(sanitize(str).replace(/\n/g, '<br />'))
+
window.startSpinner = ->
$('.turbolink-spinner').fadeIn()
diff --git a/app/assets/javascripts/wall.js.coffee b/app/assets/javascripts/wall.js.coffee
index c8fc960e174..4f71e6e0c35 100644
--- a/app/assets/javascripts/wall.js.coffee
+++ b/app/assets/javascripts/wall.js.coffee
@@ -60,8 +60,8 @@ class Wall
renderNote: (note) ->
template = @noteTemplate()
template = template.replace('{{author_name}}', note.author.name)
- template = template.replace('{{created_at}}', note.created_at)
- template = template.replace('{{text}}', linkify(sanitize(note.body)))
+ template = template.replace(/{{created_at}}/g, note.created_at)
+ template = template.replace('{{text}}', simpleFormat(note.body))
if note.attachment
file = '<i class="icon-paper-clip"/><a href="/files/note/' + note.id + '/' + note.attachment + '">' + note.attachment + '</a>'
diff --git a/app/assets/stylesheets/gitlab_bootstrap/files.scss b/app/assets/stylesheets/gitlab_bootstrap/files.scss
index d0bf3bdd6d3..78a3f0b810d 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/files.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/files.scss
@@ -49,6 +49,15 @@
&.wiki {
padding: 20px;
font-size: 13px;
+
+ .highlight {
+ margin-bottom: 9px;
+ @include border-radius(4px);
+
+ > pre {
+ margin: 0;
+ }
+ }
}
&.blob_file {
diff --git a/app/assets/stylesheets/gitlab_bootstrap/typography.scss b/app/assets/stylesheets/gitlab_bootstrap/typography.scss
index 1f0c4802318..ab14624186d 100644
--- a/app/assets/stylesheets/gitlab_bootstrap/typography.scss
+++ b/app/assets/stylesheets/gitlab_bootstrap/typography.scss
@@ -41,6 +41,10 @@ a {
color: $primary_color;
}
+ &:focus {
+ text-decoration: underline;
+ }
+
&.btn {
color: $style_color;
&:hover {
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index dfc1fdcee8a..d156166503f 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -69,7 +69,7 @@ class ApplicationController < ActionController::Base
@project
else
@project = nil
- render_404
+ render_404 and return
end
end
diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb
index f0d69f11184..686edd8af80 100644
--- a/app/controllers/profiles_controller.rb
+++ b/app/controllers/profiles_controller.rb
@@ -2,6 +2,9 @@ class ProfilesController < ApplicationController
include ActionView::Helpers::SanitizeHelper
before_filter :user
+ before_filter :authorize_change_password!, only: :update_password
+ before_filter :authorize_change_username!, only: :update_username
+
layout 'profile'
def show
@@ -53,9 +56,7 @@ class ProfilesController < ApplicationController
end
def update_username
- if @user.can_change_username?
- @user.update_attributes(username: params[:user][:username])
- end
+ @user.update_attributes(username: params[:user][:username])
respond_to do |format|
format.js
@@ -80,4 +81,12 @@ class ProfilesController < ApplicationController
user_attributes
end
+
+ def authorize_change_password!
+ return render_404 if @user.ldap_user?
+ end
+
+ def authorize_change_username!
+ return render_404 unless @user.can_change_username?
+ end
end
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 0e05213b797..e202ed3234e 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -33,12 +33,12 @@ class ProjectsController < ProjectResourceController
end
def update
- status = ::Projects::UpdateContext.new(project, current_user, params).execute
+ status = ::Projects::UpdateContext.new(@project, current_user, params).execute
respond_to do |format|
if status
flash[:notice] = 'Project was successfully updated.'
- format.html { redirect_to edit_project_path(project), notice: 'Project was successfully updated.' }
+ format.html { redirect_to edit_project_path(@project), notice: 'Project was successfully updated.' }
format.js
else
format.html { render action: "edit" }
diff --git a/app/controllers/services_controller.rb b/app/controllers/services_controller.rb
index 25a06501e07..fcfc4c84a91 100644
--- a/app/controllers/services_controller.rb
+++ b/app/controllers/services_controller.rb
@@ -1,25 +1,21 @@
class ServicesController < ProjectResourceController
# Authorize
before_filter :authorize_admin_project!
+ before_filter :service, only: [:edit, :update, :test]
respond_to :html
def index
- @gitlab_ci_service = @project.gitlab_ci_service
+ @project.build_missing_services
+ @services = @project.services.reload
end
def edit
- @service = @project.gitlab_ci_service
-
- # Create if missing
- @service = @project.create_gitlab_ci_service unless @service
end
def update
- @service = @project.gitlab_ci_service
-
if @service.update_attributes(params[:service])
- redirect_to edit_project_service_path(@project, :gitlab_ci)
+ redirect_to edit_project_service_path(@project, @service.to_param)
else
render 'edit'
end
@@ -28,9 +24,14 @@ class ServicesController < ProjectResourceController
def test
data = GitPushService.new.sample_data(project, current_user)
- @service = project.gitlab_ci_service
@service.execute(data)
redirect_to :back
end
+
+ private
+
+ def service
+ @service ||= @project.services.find { |service| service.to_param == params[:id] }
+ end
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index ef90a8877ee..65d03fe0ccd 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -119,10 +119,6 @@ module ApplicationHelper
Emoji.names.to_s
end
- def ldap_enable?
- Devise.omniauth_providers.include?(:ldap)
- end
-
def app_theme
Gitlab::Theme.css_class_by_id(current_user.try(:theme_id))
end
diff --git a/app/helpers/oauth_helper.rb b/app/helpers/oauth_helper.rb
new file mode 100644
index 00000000000..017c22d9e1f
--- /dev/null
+++ b/app/helpers/oauth_helper.rb
@@ -0,0 +1,13 @@
+module OauthHelper
+ def ldap_enabled?
+ Devise.omniauth_providers.include?(:ldap)
+ end
+
+ def default_providers
+ [:twitter, :github, :google_oauth2, :ldap]
+ end
+
+ def enabled_oauth_providers
+ Devise.omniauth_providers
+ end
+end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 1db8b7c689c..9b142714980 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -44,4 +44,8 @@ module ProjectsHelper
project.name
end
end
+
+ def remove_project_message(project)
+ "You are going to remove #{project.name_with_namespace}.\n Removed project CANNOT be restored!\n Are you ABSOLUTELY sure?"
+ end
end
diff --git a/app/helpers/user_teams_helper.rb b/app/helpers/user_teams_helper.rb
index 2055bb3c8bc..8603ee434a8 100644
--- a/app/helpers/user_teams_helper.rb
+++ b/app/helpers/user_teams_helper.rb
@@ -22,5 +22,4 @@ module UserTeamsHelper
def remove_from_user_team_message(team, member)
"You are going to remove #{member.name} from #{team.name}. Are you sure?"
end
-
end
diff --git a/app/models/campfire_service.rb b/app/models/campfire_service.rb
new file mode 100644
index 00000000000..6450ffe7318
--- /dev/null
+++ b/app/models/campfire_service.rb
@@ -0,0 +1,76 @@
+# == Schema Information
+#
+# Table name: services
+#
+# id :integer not null, primary key
+# type :string(255)
+# title :string(255)
+# token :string(255)
+# project_id :integer not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# active :boolean default(FALSE), not null
+# project_url :string(255)
+#
+
+class CampfireService < Service
+ attr_accessible :subdomain, :room
+
+ validates :token, presence: true, if: :activated?
+
+ def title
+ 'Campfire'
+ end
+
+ def description
+ 'Simple web-based real-time group chat'
+ end
+
+ def to_param
+ 'campfire'
+ end
+
+ def fields
+ [
+ { type: 'text', name: 'token', placeholder: '' },
+ { type: 'text', name: 'subdomain', placeholder: '' },
+ { type: 'text', name: 'room', placeholder: '' }
+ ]
+ end
+
+ def execute(push_data)
+ room = gate.find_room_by_name(self.room)
+ return true unless room
+
+ message = build_message(push_data)
+
+ room.speak(message)
+ end
+
+ private
+
+ def gate
+ @gate ||= Tinder::Campfire.new(subdomain, token: token)
+ end
+
+ def build_message(push)
+ ref = push[:ref].gsub("refs/heads/", "")
+ before = push[:before]
+ after = push[:after]
+
+ message = ""
+ message << "[#{project.name_with_namespace}] "
+ message << "#{push[:user_name]} "
+
+ if before =~ /000000/
+ message << "pushed new branch #{ref} \n"
+ elsif after =~ /000000/
+ message << "removed branch #{ref} \n"
+ else
+ message << "pushed #{push[:total_commits_count]} commits to #{ref}. "
+ message << "#{project.web_url}/compare/#{before}...#{after}"
+ end
+
+ message
+ end
+end
diff --git a/app/models/gitlab_ci_service.rb b/app/models/gitlab_ci_service.rb
index 9b1c707a6c9..bdbe7724be0 100644
--- a/app/models/gitlab_ci_service.rb
+++ b/app/models/gitlab_ci_service.rb
@@ -54,4 +54,23 @@ class GitlabCiService < Service
def status_img_path
project_url + "/status.png?ref=" + project.default_branch
end
+
+ def title
+ 'GitLab CI'
+ end
+
+ def description
+ 'Continuous integration server from GitLab'
+ end
+
+ def to_param
+ 'gitlab_ci'
+ end
+
+ def fields
+ [
+ { type: 'text', name: 'token', placeholder: 'GitLab CI project specific token' },
+ { type: 'text', name: 'project_url', placeholder: 'http://ci.gitlabhq.com/projects/3'}
+ ]
+ end
end
diff --git a/app/models/hipchat_service.rb b/app/models/hipchat_service.rb
new file mode 100644
index 00000000000..13429fa83b4
--- /dev/null
+++ b/app/models/hipchat_service.rb
@@ -0,0 +1,73 @@
+# == Schema Information
+#
+# Table name: services
+#
+# id :integer not null, primary key
+# type :string(255)
+# title :string(255)
+# token :string(255)
+# project_id :integer not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# active :boolean default(FALSE), not null
+# project_url :string(255)
+#
+
+class HipchatService < Service
+ attr_accessible :room
+
+ validates :token, presence: true, if: :activated?
+
+ def title
+ 'Hipchat'
+ end
+
+ def description
+ 'Simple web-based real-time group chat'
+ end
+
+ def to_param
+ 'hipchat'
+ end
+
+ def fields
+ [
+ { type: 'text', name: 'token', placeholder: '' },
+ { type: 'text', name: 'room', placeholder: '' }
+ ]
+ end
+
+ def execute(push_data)
+ gate[room].send('Gitlab', create_message(push_data))
+ end
+
+ private
+
+ def gate
+ @gate ||= HipChat::Client.new(token)
+ end
+
+ def create_message(push)
+ ref = push[:ref].gsub("refs/heads/", "")
+ before = push[:before]
+ after = push[:after]
+
+ message = ""
+ message << "#{push[:user_name]} "
+ if before =~ /000000/
+ message << "pushed new branch <a href=\"#{project.web_url}/commits/#{ref}\">#{ref}</a> to <a href=\"#{project.web_url}\">#{project.name_with_namespace.gsub!(/\s/,'')}</a>\n"
+ elsif after =~ /000000/
+ message << "removed branch #{ref} from <a href=\"#{project.web_url}\">#{project.name_with_namespace.gsub!(/\s/,'')}</a> \n"
+ else
+ message << "#pushed to branch <a href=\"#{project.web_url}/commits/#{ref}\">#{ref}</a> "
+ message << "of <a href=\"#{project.web_url}\">#{project.name_with_namespace.gsub!(/\s/,'')}</a> "
+ message << "(<a href=\"#{project.web_url}/compare/#{before}...#{after}\">Compare changes</a>)"
+ for commit in push[:commits] do
+ message << "<br /> - #{commit[:message]} (<a href=\"#{commit[:url]}\">#{commit[:id][0..5]}</a>)"
+ end
+ end
+
+ message
+ end
+
+end \ No newline at end of file
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index c1b4d4e0760..b2ad1b76f1f 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -118,7 +118,7 @@ class MergeRequest < ActiveRecord::Base
end
def broken_diffs?
- diffs == [Gitlab::Git::Diff::BROKEN_DIFF]
+ diffs == broken_diffs
end
def valid_diffs?
@@ -214,10 +214,22 @@ class MergeRequest < ActiveRecord::Base
end
def dump_diffs(diffs)
- diffs.map(&:to_hash)
+ if diffs == broken_diffs
+ broken_diffs
+ elsif diffs.respond_to?(:map)
+ diffs.map(&:to_hash)
+ end
+ end
+
+ def load_diffs(raw)
+ if raw == broken_diffs
+ broken_diffs
+ elsif raw.respond_to?(:map)
+ raw.map { |hash| Gitlab::Git::Diff.new(hash) }
+ end
end
- def load_diffs(array)
- array.map { |hash| Gitlab::Git::Diff.new(hash) }
+ def broken_diffs
+ [Gitlab::Git::Diff::BROKEN_DIFF]
end
end
diff --git a/app/models/project.rb b/app/models/project.rb
index bd33e3a4c13..9147aed3d40 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -45,9 +45,12 @@ class Project < ActiveRecord::Base
has_one :last_event, class_name: 'Event', order: 'events.created_at DESC', foreign_key: 'project_id'
has_one :gitlab_ci_service, dependent: :destroy
+ has_one :campfire_service, dependent: :destroy
+ has_one :hipchat_service, dependent: :destroy
has_one :forked_project_link, dependent: :destroy, foreign_key: "forked_to_project_id"
has_one :forked_from_project, through: :forked_project_link
+ has_many :services, dependent: :destroy
has_many :events, dependent: :destroy
has_many :merge_requests, dependent: :destroy
has_many :issues, dependent: :destroy, order: "state DESC, created_at DESC"
@@ -223,8 +226,18 @@ class Project < ActiveRecord::Base
self.issues_enabled && !self.used_default_issues_tracker?
end
- def services
- [gitlab_ci_service].compact
+ def build_missing_services
+ available_services_names.each do |service_name|
+ service = services.find { |service| service.to_param == service_name }
+
+ # If service is available but missing in db
+ # we should create an instance. Ex `create_gitlab_ci_service`
+ service = self.send :"create_#{service_name}_service" if service.nil?
+ end
+ end
+
+ def available_services_names
+ %w(gitlab_ci campfire hipchat)
end
def gitlab_ci?
@@ -410,4 +423,28 @@ class Project < ActiveRecord::Base
def forked?
!(forked_project_link.nil? || forked_project_link.forked_from_project.nil?)
end
+
+ def rename_repo
+ old_path_with_namespace = File.join(namespace_dir, path_was)
+ new_path_with_namespace = File.join(namespace_dir, path)
+
+ if gitlab_shell.mv_repository(old_path_with_namespace, new_path_with_namespace)
+ # If repository moved successfully we need to remove old satellite
+ # and send update instructions to users.
+ # However we cannot allow rollback since we moved repository
+ # So we basically we mute exceptions in next actions
+ begin
+ gitlab_shell.rm_satellites(old_path_with_namespace)
+ send_move_instructions
+ rescue
+ # Returning false does not rolback after_* transaction but gives
+ # us information about failing some of tasks
+ false
+ end
+ else
+ # if we cannot move namespace directory we should rollback
+ # db changes in order to prevent out of sync between db and fs
+ raise Exception.new('repository cannot be renamed')
+ end
+ end
end
diff --git a/app/models/service.rb b/app/models/service.rb
index d3486d29200..3e945aa898c 100644
--- a/app/models/service.rb
+++ b/app/models/service.rb
@@ -13,6 +13,8 @@
# project_url :string(255)
#
+# To add new service you should build a class inherited from Service
+# and implement a set of methods
class Service < ActiveRecord::Base
attr_accessible :title, :token, :type, :active
@@ -24,4 +26,25 @@ class Service < ActiveRecord::Base
def activated?
active
end
+
+ def title
+ # implement inside child
+ end
+
+ def description
+ # implement inside child
+ end
+
+ def to_param
+ # implement inside child
+ end
+
+ def fields
+ # implement inside child
+ []
+ end
+
+ def execute
+ # implement inside child
+ end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 55aa5b563c5..255a5ebd2a9 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -340,4 +340,8 @@ class User < ActiveRecord::Base
nil
end
end
+
+ def ldap_user?
+ extern_uid && provider == 'ldap'
+ end
end
diff --git a/app/observers/project_observer.rb b/app/observers/project_observer.rb
index de9edf41c6d..dda7be625da 100644
--- a/app/observers/project_observer.rb
+++ b/app/observers/project_observer.rb
@@ -12,6 +12,7 @@ class ProjectObserver < BaseObserver
def after_update(project)
project.send_move_instructions if project.namespace_id_changed?
+ project.rename_repo if project.path_changed?
end
def after_destroy(project)
diff --git a/app/services/system_hooks_service.rb b/app/services/system_hooks_service.rb
index 132bb14a675..a52d13d5237 100644
--- a/app/services/system_hooks_service.rb
+++ b/app/services/system_hooks_service.rb
@@ -26,6 +26,7 @@ class SystemHooksService
data.merge!({
name: model.name,
path: model.path,
+ path_with_namespace: model.path_with_namespace,
project_id: model.id,
owner_name: model.owner.name,
owner_email: model.owner.email
diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml
index aa006dfc997..59831d83cc2 100644
--- a/app/views/admin/projects/index.html.haml
+++ b/app/views/admin/projects/index.html.haml
@@ -53,7 +53,7 @@
= link_to project.name_with_namespace, [:admin, project]
.pull-right
= link_to 'Edit', edit_project_path(project), id: "edit_#{dom_id(project)}", class: "btn btn-small"
- = link_to 'Destroy', [project], confirm: "REMOVE #{project.name}? Are you sure?", method: :delete, class: "btn btn-small btn-remove"
+ = link_to 'Destroy', [project], confirm: remove_project_message(project), method: :delete, class: "btn btn-small btn-remove"
- if @projects.blank?
%p.nothing_here_message 0 projects matches
= paginate @projects, theme: "gitlab"
diff --git a/app/views/devise/sessions/_new_base.html.haml b/app/views/devise/sessions/_new_base.html.haml
new file mode 100644
index 00000000000..1ca43d5dd08
--- /dev/null
+++ b/app/views/devise/sessions/_new_base.html.haml
@@ -0,0 +1,13 @@
+= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
+ = f.text_field :login, class: "text top", placeholder: "Username or Email", autofocus: "autofocus"
+ = f.password_field :password, class: "text bottom", placeholder: "Password"
+ - if devise_mapping.rememberable?
+ .clearfix.inputs-list
+ %label.checkbox.remember_me{for: "user_remember_me"}
+ = f.check_box :remember_me
+ %span Remember me
+ = f.submit "Sign in", class: "btn-create btn"
+ .pull-right
+ = link_to "Forgot your password?", new_password_path(resource_name), class: "btn"
+
+
diff --git a/app/views/devise/sessions/_new_ldap.html.haml b/app/views/devise/sessions/_new_ldap.html.haml
index 29ba9c1e99c..575d33949b6 100644
--- a/app/views/devise/sessions/_new_ldap.html.haml
+++ b/app/views/devise/sessions/_new_ldap.html.haml
@@ -1,29 +1,5 @@
-= form_tag(user_omniauth_callback_path(:ldap), class: "login-box", id: 'new_ldap_user' ) do
- = image_tag "login-logo.png", width: "304", height: "66", class: "login-logo", alt: "Login Logo"
+= form_tag(user_omniauth_callback_path(:ldap), id: 'new_ldap_user' ) do
= text_field_tag :username, nil, {class: "text top", placeholder: "LDAP Login", autofocus: "autofocus"}
= password_field_tag :password, nil, {class: "text bottom", placeholder: "Password"}
%br/
- = submit_tag "LDAP Sign in", class: "btn-primary btn"
- - if devise_mapping.omniauthable?
- - (resource_class.omniauth_providers - [:ldap]).each do |provider|
- %hr/
- = link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider), class: "btn btn-primary"
- %br/
- %hr/
- %a#other_form_toggle{href: "#", onclick: "javascript:$('#new_user').toggle();"} Other Sign in
- :javascript
- $(function() {
- $('#new_user').toggle();
- });
-= form_for(resource, as: resource_name, url: session_path(resource_name), html: { class: "login-box" }) do |f|
- = f.text_field :login, class: "text top", placeholder: "Username or Email", autofocus: "autofocus"
- = f.password_field :password, class: "text bottom", placeholder: "Password"
- - if devise_mapping.rememberable?
- .clearfix.inputs-list
- %label.checkbox.remember_me{for: "user_remember_me"}
- = f.check_box :remember_me
- %span Remember me
- %br/
- = f.submit "Sign in", class: "btn-primary btn"
- .pull-right
- = render partial: "devise/shared/links"
+ = submit_tag "LDAP Sign in", class: "btn-create btn"
diff --git a/app/views/devise/sessions/_oauth_providers.html.haml b/app/views/devise/sessions/_oauth_providers.html.haml
new file mode 100644
index 00000000000..710a5d52514
--- /dev/null
+++ b/app/views/devise/sessions/_oauth_providers.html.haml
@@ -0,0 +1,10 @@
+- if enabled_oauth_providers.present?
+ %hr
+ %div{:'data-no-turbolink' => 'data-no-turbolink'}
+ %span Sign in with: &nbsp;
+ - (enabled_oauth_providers - [:ldap]).each do |provider|
+ %span
+ - if default_providers.include?(provider)
+ = link_to authbutton(provider, 32), omniauth_authorize_path(resource_name, provider)
+ - else
+ = link_to provider.to_s.titleize, omniauth_authorize_path(resource_name, provider), class: "btn"
diff --git a/app/views/devise/sessions/new.html.haml b/app/views/devise/sessions/new.html.haml
index baa232350a5..8b71ebed5f4 100644
--- a/app/views/devise/sessions/new.html.haml
+++ b/app/views/devise/sessions/new.html.haml
@@ -1,32 +1,31 @@
-- if ldap_enable?
- = render partial: 'devise/sessions/new_ldap'
-- else
- = form_for(resource, as: resource_name, url: session_path(resource_name), html: { class: "login-box" }) do |f|
- = image_tag "login-logo.png", width: "304", height: "66", class: "login-logo", alt: "Login Logo"
- = f.text_field :login, class: "text top", placeholder: "Username or Email", autofocus: "autofocus"
- = f.password_field :password, class: "text bottom", placeholder: "Password"
- - if devise_mapping.rememberable?
- .clearfix.inputs-list
- %label.checkbox.remember_me{for: "user_remember_me"}
- = f.check_box :remember_me
- %span Remember me
- %br/
- = f.submit "Sign in", class: "btn-create btn"
- .pull-right
- = link_to "Forgot your password?", new_password_path(resource_name), class: "btn"
- %br/
- - if Gitlab.config.gitlab.signup_enabled
- %hr/
+.login-box
+ = image_tag "login-logo.png", width: "304", height: "66", class: "login-logo", alt: "Login Logo"
+
+ - if ldap_enabled?
+ %ul.nav.nav-tabs
+ %li.active
+ = link_to 'LDAP', '#tab-ldap', 'data-toggle' => 'tab'
+ %li
+ = link_to 'Ordinary', '#tab-signin', 'data-toggle' => 'tab'
+ .tab-content
+ %div#tab-ldap.tab-pane.active
+ = render partial: 'devise/sessions/new_ldap'
+ %div#tab-signin.tab-pane
+ = render partial: 'devise/sessions/new_base'
+
+ - else
+ = render partial: 'devise/sessions/new_base'
+
+
+ = render 'devise/sessions/oauth_providers' if devise_mapping.omniauthable?
+
+ - if Gitlab.config.gitlab.signup_enabled
+ %hr
+ %div
Don't have an account?
- = link_to "Sign up", new_registration_path(resource_name)
- - if devise_mapping.omniauthable? && resource_class.omniauth_providers.present?
- %hr
- %div
- %span Sign in with: &nbsp;
- - resource_class.omniauth_providers.each do |provider|
- %span
- = link_to authbutton(provider, 32), omniauth_authorize_path(resource_name, provider)
+ %strong
+ = link_to "Sign up", new_registration_path(resource_name)
- - if extra_config.has_key?('sign_in_text')
- %hr
- = markdown(extra_config.sign_in_text)
+ - if extra_config.has_key?('sign_in_text')
+ %hr
+ = markdown(extra_config.sign_in_text)
diff --git a/app/views/edit_tree/show.html.haml b/app/views/edit_tree/show.html.haml
index 509205436ea..94a577d8e41 100644
--- a/app/views/edit_tree/show.html.haml
+++ b/app/views/edit_tree/show.html.haml
@@ -27,7 +27,7 @@
.message
to branch
%strong= @ref
- = link_to "Cancel", project_tree_path(@project, @id), class: "btn btn-cancel", confirm: "Are you sure?"
+ = link_to "Cancel", project_blob_path(@project, @id), class: "btn btn-cancel", confirm: "Are you sure?"
:javascript
ace.config.set("modePath", "#{Gitlab::Application.config.assets.prefix}/ace-src-noconflict")
diff --git a/app/views/help/index.html.haml b/app/views/help/index.html.haml
index 7bda5cb6027..1685c6eec53 100644
--- a/app/views/help/index.html.haml
+++ b/app/views/help/index.html.haml
@@ -27,6 +27,8 @@
%li
Ask in our
= link_to "support forum", "https://groups.google.com/forum/#!forum/gitlabhq"
+ or on
+ = link_to "Stack Overflow", "http://stackoverflow.com/questions/tagged/gitlab"
%li
Browse our
= link_to "issue tracker", "https://github.com/gitlabhq/gitlabhq/issues"
diff --git a/app/views/layouts/_google_analytics.html.haml b/app/views/layouts/_google_analytics.html.haml
index 1452651e1c0..81e03c7eff2 100644
--- a/app/views/layouts/_google_analytics.html.haml
+++ b/app/views/layouts/_google_analytics.html.haml
@@ -1,6 +1,6 @@
:javascript
var _gaq = _gaq || [];
- _gaq.push(['_setAccount', '#{gitlab_config.google_analytics_id}']);
+ _gaq.push(['_setAccount', '#{extra_config.google_analytics_id}']);
_gaq.push(['_trackPageview']);
(function() {
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index 637b2987ff8..0775abea3dd 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -9,7 +9,7 @@
= csrf_meta_tags
= include_gon
- = render 'layouts/google_analytics' if gitlab_config.has_key?('google_analytics_id')
+ = render 'layouts/google_analytics' if extra_config.has_key?('google_analytics_id')
-# Atom feed
- if current_user
diff --git a/app/views/merge_requests/show/_diffs.html.haml b/app/views/merge_requests/show/_diffs.html.haml
index 0807454c4b0..033d66a4ad4 100644
--- a/app/views/merge_requests/show/_diffs.html.haml
+++ b/app/views/merge_requests/show/_diffs.html.haml
@@ -4,7 +4,7 @@
%h4.nothing_here_message
Can't load diff.
You can
- = link_to "download it", project_merge_request_path(@project, @merge_request), format: :diff, class: "vlink"
+ = link_to "download it", project_merge_request_path(@project, @merge_request, format: :diff), class: "vlink"
instead.
- else
%h4.nothing_here_message Nothing to merge
diff --git a/app/views/milestones/index.html.haml b/app/views/milestones/index.html.haml
index 89892cd23f1..fb7cbc41edf 100644
--- a/app/views/milestones/index.html.haml
+++ b/app/views/milestones/index.html.haml
@@ -21,12 +21,12 @@
= link_to project_milestones_path(@project, f: "all") do
All
.span9
- %div.ui-box
+ .ui-box
%ul.well-list
= render @milestones
- - if @milestones.present?
- %li.bottom= paginate @milestones, theme: "gitlab"
- - else
+ - if @milestones.blank?
%li
%h3.nothing_here_message Nothing to show here
+
+ = paginate @milestones, theme: "gitlab"
diff --git a/app/views/profiles/account.html.haml b/app/views/profiles/account.html.haml
index 16d26c0d8e1..9bba73a080a 100644
--- a/app/views/profiles/account.html.haml
+++ b/app/views/profiles/account.html.haml
@@ -1,11 +1,35 @@
-- if Gitlab.config.omniauth.enabled
- %fieldset
- %legend Social Accounts
- .oauth_select_holder
- %p.hint Tip: Click on icon to activate sigin with one of the following services
- - User.omniauth_providers.each do |provider|
- %span{class: oauth_active_class(provider) }
- = link_to authbutton(provider, 32), omniauth_authorize_path(User, provider)
+- unless current_user.ldap_user?
+ - if Gitlab.config.omniauth.enabled
+ %fieldset
+ %legend Social Accounts
+ .oauth_select_holder
+ %p.hint Tip: Click on icon to activate sigin with one of the following services
+ - User.omniauth_providers.each do |provider|
+ %span{class: oauth_active_class(provider) }
+ = link_to authbutton(provider, 32), omniauth_authorize_path(User, provider)
+
+
+ %fieldset.update-password
+ %legend Password
+ = form_for @user, url: update_password_profile_path, method: :put do |f|
+ .padded
+ %p.slead After successful password update you will be redirected to login page where you should login with new password
+ -if @user.errors.any?
+ .alert.alert-error
+ %ul
+ - @user.errors.full_messages.each do |msg|
+ %li= msg
+
+ .clearfix
+ = f.label :password
+ .input= f.password_field :password, required: true
+ .clearfix
+ = f.label :password_confirmation
+ .input
+ = f.password_field :password_confirmation, required: true
+ .clearfix
+ .input
+ = f.submit 'Save password', class: "btn btn-save"
@@ -29,29 +53,6 @@
%span You don`t have one yet. Click generate to fix it.
= f.submit 'Generate', class: "btn success btn-build-token"
-%fieldset.update-password
- %legend Password
- = form_for @user, url: update_password_profile_path, method: :put do |f|
- .padded
- %p.slead After successful password update you will be redirected to login page where you should login with new password
- -if @user.errors.any?
- .alert.alert-error
- %ul
- - @user.errors.full_messages.each do |msg|
- %li= msg
-
- .clearfix
- = f.label :password
- .input= f.password_field :password, required: true
- .clearfix
- = f.label :password_confirmation
- .input
- = f.password_field :password_confirmation, required: true
- .clearfix
- .input
- = f.submit 'Save password', class: "btn btn-save"
-
-
- if current_user.can_change_username?
%fieldset.update-username
diff --git a/app/views/projects/edit.html.haml b/app/views/projects/edit.html.haml
index dd087100e4c..bec64bf6c58 100644
--- a/app/views/projects/edit.html.haml
+++ b/app/views/projects/edit.html.haml
@@ -11,6 +11,8 @@
%li.active
= link_to 'Settings', '#tab-settings', 'data-toggle' => 'tab'
%li
+ = link_to 'Rename repo', '#tab-rename', 'data-toggle' => 'tab'
+ %li
= link_to 'Transfer', '#tab-transfer', 'data-toggle' => 'tab'
%li
= link_to 'Remove', '#tab-remove', 'data-toggle' => 'tab'
@@ -137,6 +139,24 @@
- else
%p.nothing_here_message Only project owner can transfer a project
+ .tab-pane#tab-rename
+ .ui-box.ui-box-danger
+ %h5.title Rename repository
+ .errors-holder
+ .form-holder
+ = form_for(@project) do |f|
+ .control-group
+ = f.label :path do
+ %span Path
+ .controls
+ .clearfix
+ = f.text_field :path
+ %ul
+ %li Be careful. Rename of project repo can have unintended side effects
+ %li You will need to update your local repositories to point to the new location.
+ .form-actions
+ = f.submit 'Rename', class: "btn btn-remove"
+
.tab-pane#tab-remove
- if can?(current_user, :remove_project, @project)
.ui-box.ui-box-danger
@@ -147,7 +167,7 @@
%p
%strong Removed project can not be restored!
- = link_to 'Remove project', @project, confirm: 'Removed project can not be restored! Are you sure?', method: :delete, class: "btn btn-remove btn-small"
+ = link_to 'Remove project', @project, confirm: remove_project_message(@project), method: :delete, class: "btn btn-remove btn-small"
- else
%p.nothing_here_message Only project owner can remove a project
diff --git a/app/views/projects/empty.html.haml b/app/views/projects/empty.html.haml
index b1795b301b0..56dbbf0755e 100644
--- a/app/views/projects/empty.html.haml
+++ b/app/views/projects/empty.html.haml
@@ -31,4 +31,4 @@
- if can? current_user, :remove_project, @project
.prepend-top-20
- = link_to 'Remove project', @project, confirm: 'Are you sure?', method: :delete, class: "btn btn-remove pull-right"
+ = link_to 'Remove project', @project, confirm: remove_project_message(@project), method: :delete, class: "btn btn-remove pull-right"
diff --git a/app/views/services/_form.html.haml b/app/views/services/_form.html.haml
new file mode 100644
index 00000000000..ff6769531c4
--- /dev/null
+++ b/app/views/services/_form.html.haml
@@ -0,0 +1,48 @@
+%h3.page_title
+ - if @service.activated?
+ %span.cgreen
+ %i.icon-circle
+ - else
+ %span.cgray
+ %i.icon-circle-blank
+ = @service.title
+
+%p= @service.description
+
+.back_link
+ = link_to project_services_path(@project) do
+ &larr; to services
+
+%hr
+
+= form_for(@service, as: :service, url: project_service_path(@project, @service.to_param), method: :put) do |f|
+ - if @service.errors.any?
+ .alert.alert-error
+ %ul
+ - @service.errors.full_messages.each do |msg|
+ %li= msg
+
+
+ .control-group
+ = f.label :active, "Active", class: "control-label"
+ .controls
+ = f.check_box :active
+
+ - @service.fields.each do |field|
+ - name = field[:name]
+ - type = field[:type]
+ - placeholder = field[:placeholder]
+
+ .control-group
+ = f.label name, class: "control-label"
+ .controls
+ - if type == 'text'
+ = f.text_field name, class: "input-xlarge", placeholder: placeholder
+ - elsif type == 'checkbox'
+ = f.check_box name
+
+ .form-actions
+ = f.submit 'Save', class: 'btn btn-save'
+ &nbsp;
+ - if @service.valid? && @service.activated?
+ = link_to 'Test settings', test_project_service_path(@project, @service.to_param), class: 'btn btn-small'
diff --git a/app/views/services/_gitlab_ci.html.haml b/app/views/services/_gitlab_ci.html.haml
deleted file mode 100644
index dfde643849e..00000000000
--- a/app/views/services/_gitlab_ci.html.haml
+++ /dev/null
@@ -1,46 +0,0 @@
-%h3.page_title
- GitLab CI
- %small Continuous integration server from GitLab
- .pull-right
- - if @service.active
- %small.cgreen Enabled
- - else
- %small.cgray Disabled
-
-
-
-.back_link
- = link_to project_services_path(@project) do
- &larr; to services
-
-%hr
-= form_for(@service, :as => :service, :url => project_service_path(@project, :gitlab_ci), :method => :put) do |f|
- - if @service.errors.any?
- .alert.alert-error
- %ul
- - @service.errors.full_messages.each do |msg|
- %li= msg
-
-
- .control-group
- = f.label :active, "Active", class: "control-label"
- .controls
- = f.check_box :active
-
- .control-group
- = f.label :project_url, "Project URL", class: "control-label"
- .controls
- = f.text_field :project_url, class: "input-xlarge", placeholder: "http://ci.gitlabhq.com/projects/3"
-
- .control-group
- = f.label :token, class: "control-label" do
- CI Project token
- .controls
- = f.text_field :token, class: "input-xlarge", placeholder: "GitLab CI project specific token"
-
-
- .form-actions
- = f.submit 'Save', class: 'btn btn-save'
- &nbsp;
- - if @service.valid? && @service.active
- = link_to 'Test settings', test_project_service_path(@project), class: 'btn btn-small'
diff --git a/app/views/services/edit.html.haml b/app/views/services/edit.html.haml
index 0c63a7ed58c..d4bc9e41c27 100644
--- a/app/views/services/edit.html.haml
+++ b/app/views/services/edit.html.haml
@@ -1,3 +1,3 @@
= render "projects/settings_nav"
-= render 'gitlab_ci'
+= render 'form'
diff --git a/app/views/services/index.html.haml b/app/views/services/index.html.haml
index eb2f8d0ca1c..bd52948a6fd 100644
--- a/app/views/services/index.html.haml
+++ b/app/views/services/index.html.haml
@@ -3,30 +3,16 @@
%h3.page_title Services
%br
-%ul.ui-box.well-list
- %li
- %h4.cgreen
- = link_to edit_project_service_path(@project, :gitlab_ci) do
- GitLab CI
- %small Continuous integration server from GitLab
- .pull-right
- - if @gitlab_ci_service.try(:active)
- %small.cgreen
- %i.icon-ok
- Enabled
+%ul.bordered-list
+ - @services.each do |service|
+ %li
+ %h4
+ - if service.activated?
+ %span.cgreen
+ %i.icon-circle
- else
- %small.cgray
- %i.icon-off
- Disabled
- %li.disabled
- %h4
- Jenkins CI
- %small An extendable open source continuous integration server
- .pull-right
- %small Not implemented yet
- %li.disabled
- %h4
- Campfire
- %small Web-based group chat tool
- .pull-right
- %small Not implemented yet
+ %span.cgray
+ %i.icon-circle-blank
+ = link_to edit_project_service_path(@project, service.to_param) do
+ = service.title
+ %p= service.description
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 19b58bcc371..413560159d5 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -34,6 +34,8 @@ production: &base
## Project settings
default_projects_limit: 10
+
+ ## Users management
# signup_enabled: true # default: false - Account passwords are not sent via the email if signup is enabled.
# username_changing_enabled: false # default: true - User can change her username/namespace
diff --git a/config/initializers/secret_token.rb b/config/initializers/secret_token.rb
index 6d3a9f07787..16d1d4a9fdd 100644
--- a/config/initializers/secret_token.rb
+++ b/config/initializers/secret_token.rb
@@ -1,7 +1,23 @@
# Be sure to restart your server when you modify this file.
+require 'securerandom'
+
# Your secret key for verifying the integrity of signed cookies.
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
-Gitlab::Application.config.secret_token = '0a38e9a40ca5d66d7002a6ade0ed0f8b71058c820163f66cf65d91521ab55255ff708b9909b138008a7f13d68fec575def1dc3ff7200cd72b065896315e0bed2'
+
+def find_secure_token
+ token_file = Rails.root.join('.secret')
+ if File.exist? token_file
+ # Use the existing token.
+ File.read(token_file).chomp
+ else
+ # Generate a new token of 64 random hexadecimal characters and store it in token_file.
+ token = SecureRandom.hex(64)
+ File.write(token_file, token)
+ token
+ end
+end
+
+Gitlab::Application.config.secret_token = find_secure_token
diff --git a/db/migrate/20130522141856_add_more_fields_to_service.rb b/db/migrate/20130522141856_add_more_fields_to_service.rb
new file mode 100644
index 00000000000..298e902df2f
--- /dev/null
+++ b/db/migrate/20130522141856_add_more_fields_to_service.rb
@@ -0,0 +1,6 @@
+class AddMoreFieldsToService < ActiveRecord::Migration
+ def change
+ add_column :services, :subdomain, :string
+ add_column :services, :room, :string
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index d2fa70cc374..6a16caf59d8 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20130506095501) do
+ActiveRecord::Schema.define(:version => 20130522141856) do
create_table "deploy_keys_projects", :force => true do |t|
t.integer "deploy_key_id", :null => false
@@ -194,6 +194,8 @@ ActiveRecord::Schema.define(:version => 20130506095501) do
t.datetime "updated_at", :null => false
t.boolean "active", :default => false, :null => false
t.string "project_url"
+ t.string "subdomain"
+ t.string "room"
end
add_index "services", ["project_id"], :name => "index_services_on_project_id"
diff --git a/doc/api/README.md b/doc/api/README.md
index c4d44c52748..16af64be049 100644
--- a/doc/api/README.md
+++ b/doc/api/README.md
@@ -69,13 +69,13 @@ When listing resources you can pass the following parameters:
## Contents
-+ [Users](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/users.md)
-+ [Session](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/session.md)
-+ [Projects](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/projects.md)
-+ [Groups](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/groups.md)
-+ [Snippets](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/snippets.md)
-+ [Repositories](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/repositories.md)
-+ [Issues](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/issues.md)
-+ [Milestones](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/milestones.md)
-+ [Notes](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/notes.md)
-+ [System Hooks](https://github.com/gitlabhq/gitlabhq/blob/master/doc/api/system_hooks.md)
++ [Users](doc/api/users.md)
++ [Session](doc/api/session.md)
++ [Projects](doc/api/projects.md)
++ [Groups](doc/api/groups.md)
++ [Snippets](doc/api/snippets.md)
++ [Repositories](doc/api/repositories.md)
++ [Issues](doc/api/issues.md)
++ [Milestones](doc/api/milestones.md)
++ [Notes](doc/api/notes.md)
++ [System Hooks](doc/api/system_hooks.md)
diff --git a/doc/install/installation.md b/doc/install/installation.md
index d6679222dd5..e770cf24934 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -1,3 +1,11 @@
+# Select Version to Install
+Make sure you view this installation guide from the branch (version) of GitLab you would like to install. In most cases
+this should be the highest numbered stable branch (example shown below).
+
+![capture](https://f.cloud.github.com/assets/1192780/564911/2f9f3e1e-c5b7-11e2-9f89-98e527d1adec.png)
+
+If this is unclear check the [GitLab Blog](http://blog.gitlab.org/) for installation guide links by version.
+
# Important notes
This installation guide was created for and tested on **Debian/Ubuntu** operating systems. Please read [`doc/install/requirements.md`](./requirements.md) for hardware and operating system requirements.
@@ -6,7 +14,7 @@ This is the official installation guide to set up a production server. To set up
The following steps have been known to work. Please **use caution when you deviate** from this guide. Make sure you don't violate any assumptions GitLab makes about its environment.
-If you find a bug/error in this guide please **submit a pull request** following the [`contributing guide`](../../CONTRIBUTING.md).
+If you find a bug/error in this guide please **submit a pull request** following the [contributing guide](../../CONTRIBUTING.md).
- - -
@@ -69,6 +77,10 @@ does not ship with one. The recommended mail server is postfix and you can insta
# 2. Ruby
+Remove old 1.8 ruby if present
+
+ sudo apt-get remove ruby1.8
+
Download and compile it:
mkdir /tmp/ruby && cd /tmp/ruby
@@ -137,10 +149,10 @@ To setup the MySQL/PostgreSQL database and dependencies please see [`doc/install
cd /home/git/gitlab
# Checkout to stable release
- sudo -u git -H git checkout 5-1-stable
+ sudo -u git -H git checkout 5-2-stable
**Note:**
-You can change `5-1-stable` to `master` if you want the *bleeding edge* version, but
+You can change `5-2-stable` to `master` if you want the *bleeding edge* version, but
do so with caution!
## Configure it
@@ -207,7 +219,7 @@ Make sure to update username/password in config/database.yml.
sudo -u git -H bundle install --deployment --without development test mysql
-## Initialise Database and Activate Advanced Features
+## Initialize Database and Activate Advanced Features
sudo -u git -H bundle exec rake gitlab:setup RAILS_ENV=production
@@ -216,7 +228,7 @@ Make sure to update username/password in config/database.yml.
Download the init script (will be /etc/init.d/gitlab):
- sudo curl --output /etc/init.d/gitlab https://raw.github.com/gitlabhq/gitlabhq/master/lib/support/init.d/gitlab
+ sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
sudo chmod +x /etc/init.d/gitlab
Make GitLab start on boot:
@@ -257,7 +269,7 @@ If you can't or don't want to use Nginx as your web server, have a look at the
Download an example site config:
- sudo curl --output /etc/nginx/sites-available/gitlab https://raw.github.com/gitlabhq/gitlabhq/master/lib/support/nginx/gitlab
+ sudo cp lib/support/nginx/gitlab /etc/nginx/sites-available/gitlab
sudo ln -s /etc/nginx/sites-available/gitlab /etc/nginx/sites-enabled/gitlab
Make sure to edit the config file to match your setup:
@@ -282,7 +294,7 @@ The setup has created an admin account for you. You can use it to log in:
5iveL!fe
**Important Note:**
-Please go over to your profile page and immediately chage the password, so
+Please go over to your profile page and immediately change the password, so
nobody can access your GitLab by using this login information later on.
**Enjoy!**
@@ -326,10 +338,10 @@ GitLab uses [Omniauth](http://www.omniauth.org/) for authentication and already
These steps are fairly general and you will need to figure out the exact details from the Omniauth provider's documentation.
-* Add `gem "omniauth-your-auth-provider"` to the [Gemfile](https://github.com/gitlabhq/gitlabhq/blob/master/Gemfile#L18)
+* Add `gem "omniauth-your-auth-provider"` to the [Gemfile](https://github.com/gitlabhq/gitlabhq/blob/5-2-stable/Gemfile#L18)
* Run `sudo -u git -H bundle install` to install the new gem(s)
-* Add provider specific configuration options to your `config/gitlab.yml` (you can use the [auth providers section of the example config](https://github.com/gitlabhq/gitlabhq/blob/master/config/gitlab.yml.example#L53) as a reference)
-* Add icons for the new provider into the [vendor/assets/images/authbuttons](https://github.com/gitlabhq/gitlabhq/tree/master/vendor/assets/images/authbuttons) directory (you can find some more popular ones over at https://github.com/intridea/authbuttons)
+* Add provider specific configuration options to your `config/gitlab.yml` (you can use the [auth providers section of the example config](https://github.com/gitlabhq/gitlabhq/blob/5-2-stable/config/gitlab.yml.example#L53) as a reference)
+* Add icons for the new provider into the [vendor/assets/images/authbuttons](https://github.com/gitlabhq/gitlabhq/tree/5-2-stable/vendor/assets/images/authbuttons) directory (you can find some more popular ones over at https://github.com/intridea/authbuttons)
* Restart GitLab
### Examples
diff --git a/doc/raketasks/maintenance.md b/doc/raketasks/maintenance.md
index 338e885851d..68c1a72b230 100644
--- a/doc/raketasks/maintenance.md
+++ b/doc/raketasks/maintenance.md
@@ -66,7 +66,7 @@ python2 is supported version? ... yes
Checking Environment ... Finished
-Checking Gitlab Shell ...
+Checking GitLab Shell ...
GitLab Shell version? ... OK (1.2.0)
Repo base directory exists? ... yes
@@ -76,7 +76,7 @@ Repo base access is drwxrws---? ... yes
post-receive hook up-to-date? ... yes
post-receive hooks in repos are links: ... yes
-Checking Gitlab Shell ... Finished
+Checking GitLab Shell ... Finished
Checking Sidekiq ...
@@ -116,6 +116,8 @@ bundle exec rake gitlab:satellites:create RAILS_ENV=production
Notes:
* project owner will be a first admin
+* groups will be created as needed
+* group owner will be the first admin
* existing projects will be skipped
How to use:
@@ -132,5 +134,8 @@ Example output:
```
Processing abcd.git
* Created abcd (abcd.git)
+Processing group/xyz.git
+ * Created Group group (2)
+ * Created xyz (group/xyz.git)
[...]
```
diff --git a/features/project/service.feature b/features/project/service.feature
index ca8a4756056..6bb0c3e2c57 100644
--- a/features/project/service.feature
+++ b/features/project/service.feature
@@ -12,3 +12,9 @@ Feature: Project Services
And I click gitlab-ci service link
And I fill gitlab-ci settings
Then I should see service settings saved
+
+ Scenario: Activate hipchat service
+ When I visit project "Shop" services page
+ And I click hipchat service link
+ And I fill hipchat settings
+ Then I should see hipchat service settings saved
diff --git a/features/project/source/search_code.feature b/features/project/source/search_code.feature
index f62adb5d056..13f15cc922f 100644
--- a/features/project/source/search_code.feature
+++ b/features/project/source/search_code.feature
@@ -4,6 +4,6 @@ Feature: Project Search code
And I own project "Shop"
Given I visit project source page
- Scenario: Search for term "Welcome to Gitlab"
- When I search for term "Welcome to Gitlab"
- Then I should see files from repository containing "Welcome to Gitlab"
+ Scenario: Search for term "Welcome to GitLab"
+ When I search for term "Welcome to GitLab"
+ Then I should see files from repository containing "Welcome to GitLab"
diff --git a/features/steps/project/project_search_code.rb b/features/steps/project/project_search_code.rb
index 0dcd17a0d13..d117b019a15 100644
--- a/features/steps/project/project_search_code.rb
+++ b/features/steps/project/project_search_code.rb
@@ -3,14 +3,14 @@ class ProjectSearchCode < Spinach::FeatureSteps
include SharedProject
include SharedPaths
- When 'I search for term "Welcome to Gitlab"' do
- fill_in "search", with: "Welcome to Gitlab"
+ When 'I search for term "Welcome to GitLab"' do
+ fill_in "search", with: "Welcome to GitLab"
click_button "Go"
click_link 'Repository Code'
end
- Then 'I should see files from repository containing "Welcome to Gitlab"' do
- page.should have_content "Welcome to Gitlab"
+ Then 'I should see files from repository containing "Welcome to GitLab"' do
+ page.should have_content "Welcome to GitLab"
page.should have_content "GitLab is a free project and repository management application"
end
diff --git a/features/steps/project/project_services.rb b/features/steps/project/project_services.rb
index b1668ff7207..10feb8ea8be 100644
--- a/features/steps/project/project_services.rb
+++ b/features/steps/project/project_services.rb
@@ -9,7 +9,8 @@ class ProjectServices < Spinach::FeatureSteps
Then 'I should see list of available services' do
page.should have_content 'Services'
- page.should have_content 'Jenkins'
+ page.should have_content 'Campfire'
+ page.should have_content 'Hipchat'
page.should have_content 'GitLab CI'
end
@@ -19,12 +20,28 @@ class ProjectServices < Spinach::FeatureSteps
And 'I fill gitlab-ci settings' do
check 'Active'
- fill_in 'Project URL', with: 'http://ci.gitlab.org/projects/3'
- fill_in 'CI Project token', with: 'verySecret'
+ fill_in 'Project url', with: 'http://ci.gitlab.org/projects/3'
+ fill_in 'Token', with: 'verySecret'
click_button 'Save'
end
Then 'I should see service settings saved' do
- find_field('Project URL').value.should == 'http://ci.gitlab.org/projects/3'
+ find_field('Project url').value.should == 'http://ci.gitlab.org/projects/3'
end
+
+ And 'I click hipchat service link' do
+ click_link 'Hipchat'
+ end
+
+ And 'I fill hipchat settings' do
+ check 'Active'
+ fill_in 'Room', with: 'gitlab'
+ fill_in 'Token', with: 'verySecret'
+ click_button 'Save'
+ end
+
+ Then 'I should see hipchat service settings saved' do
+ find_field('Room').value.should == 'gitlab'
+ end
+
end
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 28e6add73ed..c2752406122 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -27,6 +27,7 @@ module API
mount Groups
mount Users
mount Projects
+ mount Repositories
mount Issues
mount Milestones
mount Session
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index d9743b4539a..ddc403c12db 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -286,95 +286,6 @@ module API
end
end
- # Get a project repository branches
- #
- # Parameters:
- # id (required) - The ID of a project
- # Example Request:
- # GET /projects/:id/repository/branches
- get ":id/repository/branches" do
- present user_project.repo.heads.sort_by(&:name), with: Entities::RepoObject, project: user_project
- end
-
- # Get a single branch
- #
- # Parameters:
- # id (required) - The ID of a project
- # branch (required) - The name of the branch
- # Example Request:
- # GET /projects/:id/repository/branches/:branch
- get ":id/repository/branches/:branch" do
- @branch = user_project.repo.heads.find { |item| item.name == params[:branch] }
- not_found!("Branch does not exist") if @branch.nil?
- present @branch, with: Entities::RepoObject, project: user_project
- end
-
- # Protect a single branch
- #
- # Parameters:
- # id (required) - The ID of a project
- # branch (required) - The name of the branch
- # Example Request:
- # PUT /projects/:id/repository/branches/:branch/protect
- put ":id/repository/branches/:branch/protect" do
- @branch = user_project.repo.heads.find { |item| item.name == params[:branch] }
- not_found! unless @branch
- protected = user_project.protected_branches.find_by_name(@branch.name)
-
- unless protected
- user_project.protected_branches.create(name: @branch.name)
- end
-
- present @branch, with: Entities::RepoObject, project: user_project
- end
-
- # Unprotect a single branch
- #
- # Parameters:
- # id (required) - The ID of a project
- # branch (required) - The name of the branch
- # Example Request:
- # PUT /projects/:id/repository/branches/:branch/unprotect
- put ":id/repository/branches/:branch/unprotect" do
- @branch = user_project.repo.heads.find { |item| item.name == params[:branch] }
- not_found! unless @branch
- protected = user_project.protected_branches.find_by_name(@branch.name)
-
- if protected
- protected.destroy
- end
-
- present @branch, with: Entities::RepoObject, project: user_project
- end
-
- # Get a project repository tags
- #
- # Parameters:
- # id (required) - The ID of a project
- # Example Request:
- # GET /projects/:id/repository/tags
- get ":id/repository/tags" do
- present user_project.repo.tags.sort_by(&:name).reverse, with: Entities::RepoObject
- end
-
- # Get a project repository commits
- #
- # Parameters:
- # id (required) - The ID of a project
- # ref_name (optional) - The name of a repository branch or tag, if not given the default branch is used
- # Example Request:
- # GET /projects/:id/repository/commits
- get ":id/repository/commits" do
- authorize! :download_code, user_project
-
- page = params[:page] || 0
- per_page = (params[:per_page] || 20).to_i
- ref = params[:ref_name] || user_project.try(:default_branch) || 'master'
-
- commits = user_project.repository.commits(ref, nil, per_page, page * per_page)
- present commits, with: Entities::RepoCommit
- end
-
# Get a project snippets
#
# Parameters:
@@ -479,32 +390,6 @@ module API
present @snippet.content
end
- # Get a raw file contents
- #
- # Parameters:
- # id (required) - The ID of a project
- # sha (required) - The commit or branch name
- # filepath (required) - The path to the file to display
- # Example Request:
- # GET /projects/:id/repository/commits/:sha/blob
- get ":id/repository/commits/:sha/blob" do
- authorize! :download_code, user_project
- required_attributes! [:filepath]
-
- ref = params[:sha]
-
- repo = user_project.repository
-
- commit = repo.commit(ref)
- not_found! "Commit" unless commit
-
- blob = Gitlab::Git::Blob.new(repo, commit.id, ref, params[:filepath])
- not_found! "File" unless blob.exists?
-
- content_type blob.mime_type
- present blob.data
- end
-
# Get a specific project's keys
#
# Example Request:
diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb
new file mode 100644
index 00000000000..964b9eb38ac
--- /dev/null
+++ b/lib/api/repositories.rb
@@ -0,0 +1,133 @@
+module API
+ # Projects API
+ class Repositories < Grape::API
+ before { authenticate! }
+
+ resource :projects do
+ helpers do
+ def handle_project_member_errors(errors)
+ if errors[:project_access].any?
+ error!(errors[:project_access], 422)
+ end
+ not_found!
+ end
+ end
+
+ # Get a project repository branches
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # Example Request:
+ # GET /projects/:id/repository/branches
+ get ":id/repository/branches" do
+ present user_project.repo.heads.sort_by(&:name), with: Entities::RepoObject, project: user_project
+ end
+
+ # Get a single branch
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # branch (required) - The name of the branch
+ # Example Request:
+ # GET /projects/:id/repository/branches/:branch
+ get ":id/repository/branches/:branch" do
+ @branch = user_project.repo.heads.find { |item| item.name == params[:branch] }
+ not_found!("Branch does not exist") if @branch.nil?
+ present @branch, with: Entities::RepoObject, project: user_project
+ end
+
+ # Protect a single branch
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # branch (required) - The name of the branch
+ # Example Request:
+ # PUT /projects/:id/repository/branches/:branch/protect
+ put ":id/repository/branches/:branch/protect" do
+ @branch = user_project.repo.heads.find { |item| item.name == params[:branch] }
+ not_found! unless @branch
+ protected = user_project.protected_branches.find_by_name(@branch.name)
+
+ unless protected
+ user_project.protected_branches.create(name: @branch.name)
+ end
+
+ present @branch, with: Entities::RepoObject, project: user_project
+ end
+
+ # Unprotect a single branch
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # branch (required) - The name of the branch
+ # Example Request:
+ # PUT /projects/:id/repository/branches/:branch/unprotect
+ put ":id/repository/branches/:branch/unprotect" do
+ @branch = user_project.repo.heads.find { |item| item.name == params[:branch] }
+ not_found! unless @branch
+ protected = user_project.protected_branches.find_by_name(@branch.name)
+
+ if protected
+ protected.destroy
+ end
+
+ present @branch, with: Entities::RepoObject, project: user_project
+ end
+
+ # Get a project repository tags
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # Example Request:
+ # GET /projects/:id/repository/tags
+ get ":id/repository/tags" do
+ present user_project.repo.tags.sort_by(&:name).reverse, with: Entities::RepoObject
+ end
+
+ # Get a project repository commits
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # ref_name (optional) - The name of a repository branch or tag, if not given the default branch is used
+ # Example Request:
+ # GET /projects/:id/repository/commits
+ get ":id/repository/commits" do
+ authorize! :download_code, user_project
+
+ page = params[:page] || 0
+ per_page = (params[:per_page] || 20).to_i
+ ref = params[:ref_name] || user_project.try(:default_branch) || 'master'
+
+ commits = user_project.repository.commits(ref, nil, per_page, page * per_page)
+ present commits, with: Entities::RepoCommit
+ end
+
+ # Get a raw file contents
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # sha (required) - The commit or branch name
+ # filepath (required) - The path to the file to display
+ # Example Request:
+ # GET /projects/:id/repository/commits/:sha/blob
+ get ":id/repository/commits/:sha/blob" do
+ authorize! :download_code, user_project
+ required_attributes! [:filepath]
+
+ ref = params[:sha]
+
+ repo = user_project.repository
+
+ commit = repo.commit(ref)
+ not_found! "Commit" unless commit
+
+ blob = Gitlab::Git::Blob.new(repo, commit.id, ref, params[:filepath])
+ not_found! "File" unless blob.exists?
+
+ content_type blob.mime_type
+ present blob.data
+ end
+ end
+ end
+end
+
diff --git a/lib/gitlab/auth.rb b/lib/gitlab/auth.rb
index 78d2196fbbe..ff1d1b13cc9 100644
--- a/lib/gitlab/auth.rb
+++ b/lib/gitlab/auth.rb
@@ -70,5 +70,24 @@ module Gitlab
def log
Gitlab::AppLogger
end
+
+ def ldap_auth(login, password)
+ # Check user against LDAP backend if user is not authenticated
+ # Only check with valid login and password to prevent anonymous bind results
+ return nil unless ldap_conf.enabled && !login.blank? && !password.blank?
+
+ ldap = OmniAuth::LDAP::Adaptor.new(ldap_conf)
+ ldap_user = ldap.bind_as(
+ filter: Net::LDAP::Filter.eq(ldap.uid, login),
+ size: 1,
+ password: password
+ )
+
+ User.find_by_extern_uid_and_provider(ldap_user.dn, 'ldap') if ldap_user
+ end
+
+ def ldap_conf
+ @ldap_conf ||= Gitlab.config.ldap
+ end
end
end
diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb
index 6a411aabcc6..4f3f7b02a5b 100644
--- a/lib/gitlab/backend/grack_auth.rb
+++ b/lib/gitlab/backend/grack_auth.rb
@@ -32,20 +32,11 @@ module Grack
if @auth.provided?
# Authentication with username and password
login, password = @auth.credentials
- self.user = User.find_by_email(login) || User.find_by_username(login)
-
- # If the provided login was not a known email or username
- # then user is nil
- if user.nil?
- # Second chance - try LDAP authentication
- return false unless Gitlab.config.ldap.enabled
- ldap_auth(login,password)
- return false unless !user.nil?
- else
- return false unless user.valid_password?(password)
- end
-
- Gitlab::ShellEnv.set_env(user)
+
+ @user = authenticate(login, password)
+ return false unless @user
+
+ Gitlab::ShellEnv.set_env(@user)
end
# Git upload and receive
@@ -58,21 +49,35 @@ module Grack
end
end
+ def authenticate(login, password)
+ user = User.find_by_email(login) || User.find_by_username(login)
+
+ # If the provided login was not a known email or username
+ # then user is nil
+ if user.nil? || user.ldap_user?
+ # Second chance - try LDAP authentication
+ return nil unless ldap_conf.enabled
+
+ auth = Gitlab::Auth.new
+ auth.ldap_auth(login, password)
+ else
+ return user if user.valid_password?(password)
+ end
+ end
+
def ldap_auth(login, password)
# Check user against LDAP backend if user is not authenticated
# Only check with valid login and password to prevent anonymous bind results
- gl = Gitlab.config
- if gl.ldap.enabled && !login.blank? && !password.blank?
- ldap = OmniAuth::LDAP::Adaptor.new(gl.ldap)
- ldap_user = ldap.bind_as(
- filter: Net::LDAP::Filter.eq(ldap.uid, login),
- size: 1,
- password: password
- )
- if ldap_user
- self.user = User.find_by_extern_uid_and_provider(ldap_user.dn, 'ldap')
- end
- end
+ return nil unless ldap_conf.enabled && !login.blank? && !password.blank?
+
+ ldap = OmniAuth::LDAP::Adaptor.new(ldap_conf)
+ ldap_user = ldap.bind_as(
+ filter: Net::LDAP::Filter.eq(ldap.uid, login),
+ size: 1,
+ password: password
+ )
+
+ User.find_by_extern_uid_and_provider(ldap_user.dn, 'ldap') if ldap_user
end
def validate_get_request
@@ -139,5 +144,9 @@ module Grack
abilities
end
end
+
+ def ldap_conf
+ @ldap_conf ||= Gitlab.config.ldap
+ end
end# Auth
end# Grack
diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab
index 47996594e3b..4c5499bbf23 100644
--- a/lib/support/init.d/gitlab
+++ b/lib/support/init.d/gitlab
@@ -24,7 +24,7 @@ SIDEKIQ_PID="$PID_PATH/sidekiq.pid"
STOP_SIDEKIQ="RAILS_ENV=production bundle exec rake sidekiq:stop"
START_SIDEKIQ="RAILS_ENV=production bundle exec rake sidekiq:start"
NAME="gitlab"
-DESC="Gitlab service"
+DESC="GitLab service"
check_pid(){
if [ -f $WEB_SERVER_PID ]; then
diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
index 77f5c02be2e..e7cfa4424ab 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -362,10 +362,10 @@ namespace :gitlab do
namespace :gitlab_shell do
- desc "GITLAB | Check the configuration of Gitlab Shell"
+ desc "GITLAB | Check the configuration of GitLab Shell"
task check: :environment do
warn_user_is_not_gitlab
- start_checking "Gitlab Shell"
+ start_checking "GitLab Shell"
check_gitlab_shell
check_repo_base_exists
@@ -375,7 +375,7 @@ namespace :gitlab do
check_post_receive_hook_is_up_to_date
check_repos_post_receive_hooks_is_link
- finished_checking "Gitlab Shell"
+ finished_checking "GitLab Shell"
end
@@ -410,12 +410,12 @@ namespace :gitlab do
puts "no".red
puts "#{repo_base_path} is missing".red
try_fixing_it(
- "This should have been created when setting up Gitlab Shell.",
+ "This should have been created when setting up GitLab Shell.",
"Make sure it's set correctly in config/gitlab.yml",
- "Make sure Gitlab Shell is installed correctly."
+ "Make sure GitLab Shell is installed correctly."
)
for_more_information(
- see_installation_guide_section "Gitlab Shell"
+ see_installation_guide_section "GitLab Shell"
)
fix_and_rerun
end
@@ -460,7 +460,7 @@ namespace :gitlab do
"find #{repo_base_path} -type d -print0 | sudo xargs -0 chmod g+s"
)
for_more_information(
- see_installation_guide_section "Gitlab Shell"
+ see_installation_guide_section "GitLab Shell"
)
fix_and_rerun
end
@@ -486,7 +486,7 @@ namespace :gitlab do
"sudo chown -R #{gitlab_shell_ssh_user}:#{gitlab_shell_owner_group} #{repo_base_path}"
)
for_more_information(
- see_installation_guide_section "Gitlab Shell"
+ see_installation_guide_section "GitLab Shell"
)
fix_and_rerun
end
@@ -535,7 +535,7 @@ namespace :gitlab do
File.realpath(project_hook_file) == File.realpath(gitlab_shell_hook_file)
puts "ok".green
else
- puts "not a link to Gitlab Shell's hook".red
+ puts "not a link to GitLab Shell's hook".red
try_fixing_it(
"sudo -u #{gitlab_shell_ssh_user} ln -sf #{gitlab_shell_hook_file} #{project_hook_file}"
)
@@ -588,7 +588,7 @@ namespace :gitlab do
def check_sidekiq_running
print "Running? ... "
- if run_and_match("ps aux | grep -i sidekiq", /sidekiq \d\.\d\.\d.+$/)
+ if run_and_match("ps aux | grep -i sidekiq", /sidekiq \d+\.\d+\.\d+.+$/)
puts "yes".green
else
puts "no".red
diff --git a/lib/tasks/gitlab/import.rake b/lib/tasks/gitlab/import.rake
index acf6abedd19..c11284e3d78 100644
--- a/lib/tasks/gitlab/import.rake
+++ b/lib/tasks/gitlab/import.rake
@@ -13,42 +13,61 @@ namespace :gitlab do
task repos: :environment do
git_base_path = Gitlab.config.gitlab_shell.repos_path
- repos_to_import = Dir.glob(git_base_path + '/*')
+ repos_to_import = Dir.glob(git_base_path + '/**/*.git')
namespaces = Namespace.pluck(:path)
repos_to_import.each do |repo_path|
- repo_name = File.basename repo_path
+ # strip repo base path
+ repo_path[0..git_base_path.length] = ''
- # Skip if group or user
- next if namespaces.include?(repo_name)
+ path = repo_path.sub(/\.git$/, '')
+ name = File.basename path
+ group_name = File.dirname path
+ group_name = nil if group_name == '.'
- # skip if not git repo
- next unless repo_name =~ /.git$/
+ # Skip if group or user
+ next if namespaces.include?(name)
- next if repo_name == 'gitolite-admin.git'
+ next if name == 'gitolite-admin'
- path = repo_name.sub(/\.git$/, '')
+ puts "Processing #{repo_path}".yellow
project = Project.find_with_namespace(path)
- puts "Processing #{repo_name}".yellow
-
if project
- puts " * #{project.name} (#{repo_name}) exists"
+ puts " * #{project.name} (#{repo_path}) exists"
else
user = User.admins.first
project_params = {
- name: path,
+ name: name,
}
+ # find group namespace
+ if group_name
+ group = Group.find_by_path(group_name)
+ # create group namespace
+ if !group
+ group = Group.new(:name => group_name)
+ group.path = group_name
+ group.owner = user
+ if group.save
+ puts " * Created Group #{group.name} (#{group.id})".green
+ else
+ puts " * Failed trying to create group #{group.name}".red
+ end
+ end
+ # set project group
+ project_params[:namespace_id] = group.id
+ end
+
project = Projects::CreateContext.new(user, project_params).execute
if project.valid?
- puts " * Created #{project.name} (#{repo_name})".green
+ puts " * Created #{project.name} (#{repo_path})".green
else
- puts " * Failed trying to create #{project.name} (#{repo_name})".red
+ puts " * Failed trying to create #{project.name} (#{repo_path})".red
end
end
end
diff --git a/spec/features/gitlab_flavored_markdown_spec.rb b/spec/features/gitlab_flavored_markdown_spec.rb
index aa72bcee005..53d31766a00 100644
--- a/spec/features/gitlab_flavored_markdown_spec.rb
+++ b/spec/features/gitlab_flavored_markdown_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe "Gitlab Flavored Markdown" do
+describe "GitLab Flavored Markdown" do
let(:project) { create(:project_with_code) }
let(:issue) { create(:issue, project: project) }
let(:merge_request) { create(:merge_request, project: project) }
diff --git a/spec/helpers/gitlab_markdown_helper_spec.rb b/spec/helpers/gitlab_markdown_helper_spec.rb
index 4140ba484f0..23b18fbf0eb 100644
--- a/spec/helpers/gitlab_markdown_helper_spec.rb
+++ b/spec/helpers/gitlab_markdown_helper_spec.rb
@@ -370,7 +370,7 @@ describe GitlabMarkdownHelper do
@wiki.stub(:content).and_return('wiki content')
end
- it "should use Gitlab Flavored Markdown for markdown files" do
+ it "should use GitLab Flavored Markdown for markdown files" do
@wiki.stub(:format).and_return(:markdown)
helper.should_receive(:markdown).with('wiki content')
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 6b7799f7af7..04b4ce1763e 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -61,10 +61,6 @@ describe Project do
it { should ensure_length_of(:path).is_within(0..255) }
it { should ensure_length_of(:description).is_within(0..2000) }
it { should validate_presence_of(:creator) }
- it { should ensure_inclusion_of(:issues_enabled).in_array([true, false]) }
- it { should ensure_inclusion_of(:wall_enabled).in_array([true, false]) }
- it { should ensure_inclusion_of(:merge_requests_enabled).in_array([true, false]) }
- it { should ensure_inclusion_of(:wiki_enabled).in_array([true, false]) }
it { should ensure_length_of(:issues_tracker_id).is_within(0..255) }
it "should not allow new projects beyond user limits" do
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index 4346bfe8f2e..de0631d5b70 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -173,75 +173,6 @@ describe API::API do
end
end
- describe "GET /projects/:id/repository/branches" do
- it "should return an array of project branches" do
- get api("/projects/#{project.id}/repository/branches", user)
- response.status.should == 200
- json_response.should be_an Array
- json_response.first['name'].should == project.repo.heads.sort_by(&:name).first.name
- end
- end
-
- describe "GET /projects/:id/repository/branches/:branch" do
- it "should return the branch information for a single branch" do
- get api("/projects/#{project.id}/repository/branches/new_design", user)
- response.status.should == 200
-
- json_response['name'].should == 'new_design'
- json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1'
- json_response['protected'].should == false
- end
-
- it "should return a 404 error if branch is not available" do
- get api("/projects/#{project.id}/repository/branches/unknown", user)
- response.status.should == 404
- end
- end
-
- describe "PUT /projects/:id/repository/branches/:branch/protect" do
- it "should protect a single branch" do
- put api("/projects/#{project.id}/repository/branches/new_design/protect", user)
- response.status.should == 200
-
- json_response['name'].should == 'new_design'
- json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1'
- json_response['protected'].should == true
- end
-
- it "should return a 404 error if branch not found" do
- put api("/projects/#{project.id}/repository/branches/unknown/protect", user)
- response.status.should == 404
- end
-
- it "should return success when protect branch again" do
- put api("/projects/#{project.id}/repository/branches/new_design/protect", user)
- put api("/projects/#{project.id}/repository/branches/new_design/protect", user)
- response.status.should == 200
- end
- end
-
- describe "PUT /projects/:id/repository/branches/:branch/unprotect" do
- it "should unprotect a single branch" do
- put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user)
- response.status.should == 200
-
- json_response['name'].should == 'new_design'
- json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1'
- json_response['protected'].should == false
- end
-
- it "should return success when unprotect branch" do
- put api("/projects/#{project.id}/repository/branches/unknown/unprotect", user)
- response.status.should == 404
- end
-
- it "should return success when unprotect branch again" do
- put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user)
- put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user)
- response.status.should == 200
- end
- end
-
describe "GET /projects/:id/members" do
it "should return project team members" do
get api("/projects/#{project.id}/members", user)
@@ -491,35 +422,6 @@ describe API::API do
end
end
- describe "GET /projects/:id/repository/tags" do
- it "should return an array of project tags" do
- get api("/projects/#{project.id}/repository/tags", user)
- response.status.should == 200
- json_response.should be_an Array
- json_response.first['name'].should == project.repo.tags.sort_by(&:name).reverse.first.name
- end
- end
-
- describe "GET /projects/:id/repository/commits" do
- context "authorized user" do
- before { project.team << [user2, :reporter] }
-
- it "should return project commits" do
- get api("/projects/#{project.id}/repository/commits", user)
- response.status.should == 200
-
- json_response.should be_an Array
- json_response.first['id'].should == project.repository.commit.id
- end
- end
-
- context "unauthorized user" do
- it "should not return project commits" do
- get api("/projects/#{project.id}/repository/commits")
- response.status.should == 401
- end
- end
- end
describe "GET /projects/:id/snippets" do
it "should return an array of project snippets" do
@@ -613,28 +515,6 @@ describe API::API do
end
end
- describe "GET /projects/:id/repository/commits/:sha/blob" do
- it "should get the raw file contents" do
- get api("/projects/#{project.id}/repository/commits/master/blob?filepath=README.md", user)
- response.status.should == 200
- end
-
- it "should return 404 for invalid branch_name" do
- get api("/projects/#{project.id}/repository/commits/invalid_branch_name/blob?filepath=README.md", user)
- response.status.should == 404
- end
-
- it "should return 404 for invalid file" do
- get api("/projects/#{project.id}/repository/commits/master/blob?filepath=README.invalid", user)
- response.status.should == 404
- end
-
- it "should return a 400 error if filepath is missing" do
- get api("/projects/#{project.id}/repository/commits/master/blob", user)
- response.status.should == 400
- end
- end
-
describe :deploy_keys do
let(:deploy_keys_project) { create(:deploy_keys_project, project: project) }
let(:deploy_key) { deploy_keys_project.deploy_key }
diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb
new file mode 100644
index 00000000000..31176316af2
--- /dev/null
+++ b/spec/requests/api/repositories_spec.rb
@@ -0,0 +1,135 @@
+require 'spec_helper'
+
+describe API::API do
+ include ApiHelpers
+ before(:each) { enable_observers }
+
+ let(:user) { create(:user) }
+ let(:user2) { create(:user) }
+ let!(:project) { create(:project_with_code, creator_id: user.id) }
+ let!(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
+
+ before { project.team << [user, :reporter] }
+
+
+ describe "GET /projects/:id/repository/branches" do
+ it "should return an array of project branches" do
+ get api("/projects/#{project.id}/repository/branches", user)
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.first['name'].should == project.repo.heads.sort_by(&:name).first.name
+ end
+ end
+
+ describe "GET /projects/:id/repository/branches/:branch" do
+ it "should return the branch information for a single branch" do
+ get api("/projects/#{project.id}/repository/branches/new_design", user)
+ response.status.should == 200
+
+ json_response['name'].should == 'new_design'
+ json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1'
+ json_response['protected'].should == false
+ end
+
+ it "should return a 404 error if branch is not available" do
+ get api("/projects/#{project.id}/repository/branches/unknown", user)
+ response.status.should == 404
+ end
+ end
+
+ describe "PUT /projects/:id/repository/branches/:branch/protect" do
+ it "should protect a single branch" do
+ put api("/projects/#{project.id}/repository/branches/new_design/protect", user)
+ response.status.should == 200
+
+ json_response['name'].should == 'new_design'
+ json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1'
+ json_response['protected'].should == true
+ end
+
+ it "should return a 404 error if branch not found" do
+ put api("/projects/#{project.id}/repository/branches/unknown/protect", user)
+ response.status.should == 404
+ end
+
+ it "should return success when protect branch again" do
+ put api("/projects/#{project.id}/repository/branches/new_design/protect", user)
+ put api("/projects/#{project.id}/repository/branches/new_design/protect", user)
+ response.status.should == 200
+ end
+ end
+
+ describe "PUT /projects/:id/repository/branches/:branch/unprotect" do
+ it "should unprotect a single branch" do
+ put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user)
+ response.status.should == 200
+
+ json_response['name'].should == 'new_design'
+ json_response['commit']['id'].should == '621491c677087aa243f165eab467bfdfbee00be1'
+ json_response['protected'].should == false
+ end
+
+ it "should return success when unprotect branch" do
+ put api("/projects/#{project.id}/repository/branches/unknown/unprotect", user)
+ response.status.should == 404
+ end
+
+ it "should return success when unprotect branch again" do
+ put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user)
+ put api("/projects/#{project.id}/repository/branches/new_design/unprotect", user)
+ response.status.should == 200
+ end
+ end
+
+ describe "GET /projects/:id/repository/tags" do
+ it "should return an array of project tags" do
+ get api("/projects/#{project.id}/repository/tags", user)
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.first['name'].should == project.repo.tags.sort_by(&:name).reverse.first.name
+ end
+ end
+
+ describe "GET /projects/:id/repository/commits" do
+ context "authorized user" do
+ before { project.team << [user2, :reporter] }
+
+ it "should return project commits" do
+ get api("/projects/#{project.id}/repository/commits", user)
+ response.status.should == 200
+
+ json_response.should be_an Array
+ json_response.first['id'].should == project.repository.commit.id
+ end
+ end
+
+ context "unauthorized user" do
+ it "should not return project commits" do
+ get api("/projects/#{project.id}/repository/commits")
+ response.status.should == 401
+ end
+ end
+ end
+
+ describe "GET /projects/:id/repository/commits/:sha/blob" do
+ it "should get the raw file contents" do
+ get api("/projects/#{project.id}/repository/commits/master/blob?filepath=README.md", user)
+ response.status.should == 200
+ end
+
+ it "should return 404 for invalid branch_name" do
+ get api("/projects/#{project.id}/repository/commits/invalid_branch_name/blob?filepath=README.md", user)
+ response.status.should == 404
+ end
+
+ it "should return 404 for invalid file" do
+ get api("/projects/#{project.id}/repository/commits/master/blob?filepath=README.invalid", user)
+ response.status.should == 404
+ end
+
+ it "should return a 400 error if filepath is missing" do
+ get api("/projects/#{project.id}/repository/commits/master/blob", user)
+ response.status.should == 400
+ end
+ end
+end