summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFranz-Robert van Vugt <f.vanvugt@zeno.nu>2014-03-27 21:40:33 +0100
committerFranz-Robert van Vugt <f.vanvugt@zeno.nu>2014-03-27 21:40:33 +0100
commitcfc4a2dbe3652180c1d08d5d9e154e28cbb340fb (patch)
treef9af595878a2789be45c612e26ced8c9f7c592ad
parentf03820ebf2f28ddb26e422322219a815d8cd3749 (diff)
parentfc5ac1451dcfda7cf53d536db79b552b29849276 (diff)
downloadgitlab-ce-cfc4a2dbe3652180c1d08d5d9e154e28cbb340fb.tar.gz
Merge branch 'master' of https://github.com/gitlabhq/gitlabhq into patch-1
-rw-r--r--.rspec2
-rw-r--r--.travis.yml4
-rw-r--r--CHANGELOG18
-rw-r--r--CONTRIBUTING.md20
-rw-r--r--Gemfile7
-rw-r--r--Gemfile.lock13
-rw-r--r--PROCESS.md4
-rw-r--r--Procfile2
-rw-r--r--README.md29
-rw-r--r--VERSION2
-rw-r--r--app/assets/javascripts/application.js31
-rw-r--r--app/assets/javascripts/application.js.coffee (renamed from app/assets/javascripts/main.js.coffee)42
-rw-r--r--app/assets/javascripts/gfm_auto_complete.js.coffee3
-rw-r--r--app/assets/stylesheets/application.scss2
-rw-r--r--app/assets/stylesheets/generic/common.scss4
-rw-r--r--app/assets/stylesheets/generic/typography.scss11
-rw-r--r--app/assets/stylesheets/main/mixins.scss3
-rw-r--r--app/assets/stylesheets/print.scss13
-rw-r--r--app/assets/stylesheets/sections/dashboard.scss2
-rw-r--r--app/assets/stylesheets/sections/diff.scss25
-rw-r--r--app/assets/stylesheets/sections/events.scss6
-rw-r--r--app/assets/stylesheets/sections/header.scss6
-rw-r--r--app/assets/stylesheets/sections/notes.scss8
-rw-r--r--app/controllers/passwords_controller.rb18
-rw-r--r--app/controllers/profiles/keys_controller.rb2
-rw-r--r--app/controllers/projects/issues_controller.rb2
-rw-r--r--app/controllers/projects/merge_requests_controller.rb2
-rw-r--r--app/controllers/projects/milestones_controller.rb3
-rw-r--r--app/controllers/projects_controller.rb34
-rw-r--r--app/finders/base_finder.rb4
-rw-r--r--app/helpers/commits_helper.rb76
-rw-r--r--app/helpers/merge_requests_helper.rb2
-rw-r--r--app/helpers/tree_helper.rb2
-rw-r--r--app/mailers/emails/merge_requests.rb4
-rw-r--r--app/models/concerns/issuable.rb2
-rw-r--r--app/models/diff_line.rb3
-rw-r--r--app/models/event.rb8
-rw-r--r--app/models/issue.rb3
-rw-r--r--app/models/merge_request.rb2
-rw-r--r--app/models/milestone.rb5
-rw-r--r--app/models/note.rb6
-rw-r--r--app/models/project.rb3
-rw-r--r--app/models/project_services/slack_message.rb95
-rw-r--r--app/models/project_services/slack_service.rb68
-rw-r--r--app/models/user.rb4
-rw-r--r--app/observers/activity_observer.rb39
-rw-r--r--app/observers/base_observer.rb4
-rw-r--r--app/observers/issue_observer.rb3
-rw-r--r--app/observers/merge_request_observer.rb23
-rw-r--r--app/observers/milestone_observer.rb13
-rw-r--r--app/observers/note_observer.rb6
-rw-r--r--app/services/event_create_service.rb64
-rw-r--r--app/services/merge_requests/auto_merge_service.rb5
-rw-r--r--app/services/merge_requests/base_merge_service.rb10
-rw-r--r--app/services/merge_requests/merge_service.rb5
-rw-r--r--app/services/notification_service.rb5
-rw-r--r--app/views/devise/sessions/_oauth_providers.html.haml4
-rw-r--r--app/views/layouts/_head.html.haml3
-rw-r--r--app/views/layouts/_head_panel.html.haml4
-rw-r--r--app/views/layouts/_init_auto_complete.html.haml3
-rw-r--r--app/views/layouts/_public_head_panel.html.haml16
-rw-r--r--app/views/layouts/public_projects.html.haml2
-rw-r--r--app/views/notify/repository_push_email.html.haml6
-rw-r--r--app/views/notify/repository_push_email.text.haml4
-rw-r--r--app/views/projects/commits/_parallel_view.html.haml114
-rw-r--r--app/views/projects/commits/_text_file.html.haml2
-rw-r--r--app/views/projects/compare/show.html.haml8
-rw-r--r--app/views/projects/deploy_keys/show.html.haml2
-rw-r--r--app/views/projects/issues/_form.html.haml2
-rw-r--r--app/views/projects/merge_requests/_form.html.haml45
-rw-r--r--app/views/projects/merge_requests/_show.html.haml2
-rw-r--r--app/views/projects/merge_requests/branch_from.js.haml2
-rw-r--r--app/views/projects/merge_requests/show/_diffs.html.haml2
-rw-r--r--app/views/projects/merge_requests/show/_mr_accept.html.haml11
-rw-r--r--app/views/projects/merge_requests/show/_mr_box.html.haml4
-rw-r--r--app/views/projects/notes/_note.html.haml2
-rw-r--r--app/views/projects/show.html.haml4
-rw-r--r--config/application.rb2
-rw-r--r--config/environments/production.rb6
-rw-r--r--config/initializers/gemoji.rb3
-rw-r--r--config/routes.rb2
-rw-r--r--config/unicorn_development.rb2
-rw-r--r--db/fixtures/development/11_keys.rb2
-rw-r--r--doc/README.md17
-rw-r--r--doc/api/README.md53
-rw-r--r--doc/api/merge_requests.md42
-rw-r--r--doc/api/projects.md26
-rw-r--r--doc/api/system_hooks.md140
-rw-r--r--doc/development/README.md2
-rw-r--r--doc/development/architecture.md6
-rw-r--r--doc/development/shell_commands.md6
-rw-r--r--doc/install/README.md4
-rw-r--r--doc/install/database_mysql.md7
-rw-r--r--doc/install/installation.md4
-rw-r--r--doc/integration/external-issue-tracker.md2
-rw-r--r--doc/legal/README.md2
-rw-r--r--doc/permissions/permissions.md2
-rw-r--r--doc/raketasks/README.md6
-rw-r--r--doc/release/README.md2
-rw-r--r--doc/release/monthly.md16
-rw-r--r--doc/security/README.md2
-rw-r--r--doc/ssh/deploy_keys.md12
-rw-r--r--doc/update/4.2-to-5.0.md2
-rw-r--r--doc/update/5.0-to-5.1.md2
-rw-r--r--doc/update/5.1-to-5.2.md2
-rw-r--r--doc/update/5.1-to-5.4.md3
-rw-r--r--doc/update/5.1-to-6.0.md2
-rw-r--r--doc/update/5.2-to-5.3.md2
-rw-r--r--doc/update/5.3-to-5.4.md3
-rw-r--r--doc/update/5.4-to-6.0.md2
-rw-r--r--doc/update/6.0-to-6.1.md2
-rw-r--r--doc/update/6.0-to-6.7.md (renamed from doc/update/6.0-to-6.5.md)35
-rw-r--r--doc/update/6.1-to-6.2.md3
-rw-r--r--doc/update/6.6-to-6.7.md2
-rw-r--r--doc/update/README.md5
-rw-r--r--doc/web_hooks/web_hooks.md1
-rw-r--r--features/project/service.feature6
-rw-r--r--features/steps/dashboard/dashboard.rb2
-rw-r--r--features/steps/project/redirects.rb2
-rw-r--r--features/steps/project/services.rb18
-rw-r--r--features/steps/public/projects.rb2
-rw-r--r--features/steps/shared/project.rb8
-rw-r--r--lib/api/entities.rb4
-rw-r--r--lib/api/internal.rb60
-rw-r--r--lib/api/merge_requests.rb16
-rw-r--r--lib/api/projects.rb11
-rw-r--r--lib/gitlab/backend/grack_auth.rb106
-rw-r--r--lib/gitlab/backend/grack_helpers.rb28
-rw-r--r--lib/gitlab/git_access.rb74
-rw-r--r--lib/gitlab/markdown.rb6
-rw-r--r--lib/gitlab/satellite/satellite.rb17
-rw-r--r--lib/gitlab/upgrader.rb1
-rwxr-xr-xlib/support/init.d/gitlab34
-rw-r--r--lib/support/nginx/gitlab8
-rw-r--r--lib/tasks/gitlab/check.rake17
-rwxr-xr-xscript/background_jobs26
-rw-r--r--spec/controllers/profile_keys_controller_spec.rb10
-rw-r--r--spec/factories.rb18
-rw-r--r--spec/features/notes_on_merge_requests_spec.rb49
-rw-r--r--spec/features/security/group/internal_group_access_spec.rb2
-rw-r--r--spec/features/security/group/mixed_group_access_spec.rb4
-rw-r--r--spec/features/security/group/public_group_access_spec.rb2
-rw-r--r--spec/features/security/project/internal_access_spec.rb7
-rw-r--r--spec/finders/merge_requests_finder_spec.rb18
-rw-r--r--spec/finders/projects_finder_spec.rb8
-rw-r--r--spec/mailers/notify_spec.rb24
-rw-r--r--spec/models/concerns/issuable_spec.rb5
-rw-r--r--spec/models/project_spec.rb1
-rw-r--r--spec/models/slack_message_spec.rb56
-rw-r--r--spec/models/slack_service_spec.rb69
-rw-r--r--spec/models/user_spec.rb14
-rw-r--r--spec/observers/activity_observer_spec.rb61
-rw-r--r--spec/observers/merge_request_observer_spec.rb2
-rw-r--r--spec/requests/api/issues_spec.rb12
-rw-r--r--spec/requests/api/merge_requests_spec.rb17
-rw-r--r--spec/requests/api/projects_spec.rb41
-rw-r--r--spec/seed_project.tar.gzbin9789938 -> 9769010 bytes
-rw-r--r--spec/services/event_create_service_spec.rb103
-rw-r--r--spec/services/notification_service_spec.rb14
-rw-r--r--spec/services/projects/create_service_spec.rb (renamed from spec/services/projects_create_service_spec.rb)0
-rw-r--r--spec/services/projects/transfer_service_spec.rb (renamed from spec/services/project_transfer_service_spec.rb)0
-rw-r--r--spec/services/projects/update_service_spec.rb (renamed from spec/services/projects_update_service_spec.rb)0
-rw-r--r--spec/services/search_service_spec.rb33
-rw-r--r--spec/spec_helper.rb101
-rw-r--r--spec/support/test_env.rb6
165 files changed, 1699 insertions, 882 deletions
diff --git a/.rspec b/.rspec
index 7488cbe7792..4e1e0d2f722 100644
--- a/.rspec
+++ b/.rspec
@@ -1 +1 @@
---color --drb
+--color
diff --git a/.travis.yml b/.travis.yml
index d7c65286cfe..6bff3752b2a 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,10 +19,10 @@ rvm:
services:
- redis-server
before_script:
- - "bundle exec rake db:setup"
- - "bundle exec rake db:seed_fu"
- "cp config/database.yml.$DB config/database.yml"
- "cp config/gitlab.yml.example config/gitlab.yml"
+ - "bundle exec rake db:setup"
+ - "bundle exec rake db:seed_fu"
script: "bundle exec rake $TASK --trace"
notifications:
email: false
diff --git a/CHANGELOG b/CHANGELOG
index 031536816a5..06d19df7a32 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,14 @@
+v 6.8.0
+ - Ability to at mention users that are participating in issue and merge req. discussion
+ - Enabled GZip Compression for assets in example Nginx, make sure that Nginx is compiled with --with-http_gzip_static_module flag (this is default in Ubuntu)
+ - Make user search case-insensitive (Christopher Arnold)
+
+v 6.7.2
+ - Fix upgrader script
+
+v 6.7.1
+ - Fix GitLab CI integration
+
v 6.7.0
- Increased the example Nginx client_max_body_size from 5MB to 20MB, consider updating it manually on existing installations
- Add support for Gemnasium as a Project Service (Olivier Gonzalez)
@@ -9,6 +20,7 @@ v 6.7.0
- Show contribution guide link for new issue form (Jeroen van Baarsen)
- Fix CI status for merge requests from fork
- Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard)
+ - New page load indicator that includes a spinner that scrolls with the page
- Converted all the help sections into markdown
- LDAP user filters
- Streamline the content of notification emails (Pierre de La Morinerie)
@@ -24,6 +36,12 @@ v 6.7.0
- Faster authorized_keys rebuilding in `rake gitlab:shell:setup` (requires gitlab-shell 1.8.5)
- Create and Update MR calls now support the description parameter (Greg Messner)
- Markdown relative links in the wiki link to wiki pages, markdown relative links in repositories link to files in the repository
+ - Added Slack service integration (Federico Ravasio)
+ - Better API responses for access_levels (sponsored by O'Reilly Media)
+ - Requires at least 2 unicorn workers
+ - Requires gitlab-shell v1.9+
+ - Replaced gemoji(due to closed licencing problem) with Phantom Open Emoji library(combined SIL Open Font License, MIT License and the CC 3.0 License)
+ - Fix `/:username.keys` response content type (Dmitry Medvinsky)
v 6.6.5
- Added option to remove issue assignee on project issue page and issue edit page (Jason Blanchard)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 93dd88360a8..b5fc2d59c9d 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -24,9 +24,12 @@ Issues and merge requests should be in English and contain appropriate language
To get support for your particular problem please use the channels as detailed in the [getting help section of the readme](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/README.md#getting-help). Professional [support subscriptions](http://www.gitlab.com/subscription/) and [consulting services](http://www.gitlab.com/consultancy/) are available from [GitLab.com](http://www.gitlab.com/).
-The [issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/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. Not all issues will be addressed and your issue is more likely to be addressed if you submit a merge request which partially or fully addresses the issue.
+The [issue tracker](https://gitlab.com/gitlab-org/gitlab-ce/issues) is only for obvious errors in the latest [stable or development release of GitLab](MAINTENANCE.md).
+If something is wrong but it is not a regression compared to older versions of GitLab please do not open an issue but a feature request.
+When submitting an issue please conform to the issue submission guidelines listed below.
+Not all issues will be addressed and your issue is more likely to be addressed if you submit a merge request which partially or fully addresses the issue.
-Do not use the issue tracker for feature requests. We have a specific [feedback and suggestions forum](http://feedback.gitlab.com) for this purpose.
+Do not use the issue tracker for feature requests. We have a specific [feature request forum](http://feedback.gitlab.com) for this purpose.
Please send a merge request with a tested solution or a merge request with a failing test instead of opening an issue if you can. If you're unsure where to post, post to the [mailing list](https://groups.google.com/forum/#!forum/gitlabhq) or [Stack Overflow](http://stackoverflow.com/questions/tagged/gitlab) first. 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.
@@ -48,7 +51,7 @@ Please send a merge request with a tested solution or a merge request with a fai
## Merge requests
-We welcome merge requests with fixes and improvements to GitLab code, tests, and/or documentation. The features we would really like a merge request for are listed with the [status 'accepting merge requests' on our feedback forum](http://feedback.gitlab.com/forums/176466-general/status/796455) but other improvements are also welcome. If you want to add a new feature that is not marked it is best to first create a feedback issue (if there isn't one already) and leave a comment asking for it to be marked accepting merge requests. Please include screenshots or wireframes if the feature will also change the UI.
+We welcome merge requests with fixes and improvements to GitLab code, tests, and/or documentation. The features we would really like a merge request for are listed with the [status 'accepting merge requests' on our feature request forum](http://feedback.gitlab.com/forums/176466-general/status/796455) but other improvements are also welcome. If you want to add a new feature that is not marked it is best to first create a feedback issue (if there isn't one already) and leave a comment asking for it to be marked accepting merge requests. Please include screenshots or wireframes if the feature will also change the UI.
### Merge request guidelines
@@ -64,7 +67,8 @@ If you can, please submit a merge request with the fix or improvements including
1. The MR title should describes the change you want to make
1. The MR description should give a motive for your change and the method you used to achieve it
1. If the MR changes the UI it should include before and after screenshots
-1. Link relevant [issues](https://gitlab.com/gitlab-org/gitlab-ce/issues) and/or [feedback items](http://feedback.gitlab.com/) from the merge request description and leave a comment on them with a link back to the MR
+1. If the MR changes CSS classes please include the list of affected pages `grep css-class ./app -R`
+1. Link relevant [issues](https://gitlab.com/gitlab-org/gitlab-ce/issues) and/or [feature requests](http://feedback.gitlab.com/) from the merge request description and leave a comment on them with a link back to the MR
1. Be prepared to answer questions and incorporate feedback even if requests for this arrive weeks or months after your MR submittion
1. If your MR touches code that executes shell commands, make sure it adheres to the [shell command guidelines]( doc/development/shell_commands.md).
@@ -74,6 +78,14 @@ Please keep the change in a single MR **as small as possible**. If you want to c
For examples of feedback on merge requests please look at already [closed merge requests](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests?assignee_id=&label_name=&milestone_id=&scope=&sort=&state=closed). Please ensure that your merge request meets the following contribution acceptance criteria.
+**Please format your merge request description as follows:**
+
+1. What does this MR do?
+2. Are there points in the code the reviewer needs to double check?
+3. Why was this MR needed?
+4. What are the relevant issue numbers / [Feature requests](http://feedback.gitlab.com/)?
+5. Screenshots (If appropiate)
+
## Contribution acceptance criteria
1. The change is as small as possible (see the above paragraph for details)
diff --git a/Gemfile b/Gemfile
index e3acf4a153d..397165f668f 100644
--- a/Gemfile
+++ b/Gemfile
@@ -132,6 +132,9 @@ gem "gitlab-flowdock-git-hook", "~> 0.4.2"
# Gemnasium integration
gem "gemnasium-gitlab-service", "~> 0.2"
+# Slack integration
+gem "slack-notifier", "~> 0.2.0"
+
# d3
gem "d3_rails", "~> 3.1.4"
@@ -162,8 +165,9 @@ gem "modernizr", "2.6.2"
gem "raphael-rails", "~> 2.1.2"
gem 'bootstrap-sass', '~> 3.0'
gem "font-awesome-rails", '~> 3.2'
-gem "gemoji", "~> 1.3.0"
+gem "gitlab_emoji", "~> 0.0.1.1"
gem "gon", '~> 5.0.0'
+gem 'nprogress-rails'
group :development do
gem "annotate", "~> 2.6.0.beta2"
@@ -214,7 +218,6 @@ group :development, :test do
# PhantomJS driver for Capybara
gem 'poltergeist', '~> 1.4.1'
- gem 'spork', '~> 1.0rc'
gem 'jasmine', '2.0.0.rc5'
gem "spring", '1.1.1'
diff --git a/Gemfile.lock b/Gemfile.lock
index 52d6ac31463..1a0bce98ac5 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -128,6 +128,8 @@ GEM
mail (~> 2.2)
email_validator (1.4.0)
activemodel
+ emoji (1.0.1)
+ json
enumerize (0.7.0)
activesupport (>= 3.2)
equalizer (0.0.8)
@@ -165,7 +167,6 @@ GEM
formatador (0.2.4)
gemnasium-gitlab-service (0.2.1)
rugged (~> 0.19)
- gemoji (1.3.1)
gherkin-ruby (0.3.1)
racc
github-markdown (0.5.5)
@@ -190,6 +191,8 @@ GEM
charlock_holmes (~> 0.6.6)
escape_utils (~> 0.2.4)
mime-types (~> 1.19)
+ gitlab_emoji (0.0.1.1)
+ emoji (~> 1.0.1)
gitlab_git (5.7.1)
activesupport (~> 4.0.0)
charlock_holmes (~> 0.6.9)
@@ -297,6 +300,7 @@ GEM
net-ssh (>= 1.99.1)
net-ssh (2.7.0)
nokogiri (1.5.10)
+ nprogress-rails (0.1.2.3)
oauth (0.4.7)
oauth2 (0.8.1)
faraday (~> 0.8)
@@ -468,6 +472,7 @@ GEM
rack-protection (~> 1.4)
tilt (~> 1.3, >= 1.3.4)
six (0.2.0)
+ slack-notifier (0.2.0)
slim (2.0.2)
temple (~> 0.6.6)
tilt (>= 1.3.3, < 2.1)
@@ -479,7 +484,6 @@ GEM
capybara (>= 2.0.0)
railties (>= 3)
spinach (>= 0.4)
- spork (1.0.0rc4)
spring (1.1.1)
spring-commands-rspec (1.0.1)
spring (>= 0.9.1)
@@ -591,12 +595,12 @@ DEPENDENCIES
font-awesome-rails (~> 3.2)
foreman
gemnasium-gitlab-service (~> 0.2)
- gemoji (~> 1.3.0)
github-markup (~> 0.7.4)!
gitlab-flowdock-git-hook (~> 0.4.2)
gitlab-gollum-lib (~> 1.1.0)
gitlab-grack (~> 2.0.0.pre)
gitlab-linguist (~> 3.0.0)
+ gitlab_emoji (~> 0.0.1.1)
gitlab_git (~> 5.7.1)
gitlab_meta (= 6.0)
gitlab_omniauth-ldap (= 1.0.4)
@@ -620,6 +624,7 @@ DEPENDENCIES
minitest (~> 4.7.0)
modernizr (= 2.6.2)
mysql2
+ nprogress-rails
omniauth (~> 1.1.3)
omniauth-github
omniauth-google-oauth2
@@ -652,9 +657,9 @@ DEPENDENCIES
simplecov
sinatra
six
+ slack-notifier (~> 0.2.0)
slim
spinach-rails
- spork (~> 1.0rc)
spring (= 1.1.1)
spring-commands-rspec (= 1.0.1)
spring-commands-spinach (= 1.0.0)
diff --git a/PROCESS.md b/PROCESS.md
index c582dc6fd0d..2266d50b238 100644
--- a/PROCESS.md
+++ b/PROCESS.md
@@ -24,8 +24,6 @@ Below we describe the contributing process to GitLab for two reasons. So that co
- Monitors for new merge requests (at least once a week)
- Manages their work queue by looking at issues and merge requests assigned to them
- Close fixed issues (via commit messages or manually)
-- Codes [new features](http://feedback.gitlab.com/forums/176466-general/filters/top)!
-- Response guidelines
- Be kind to people trying to contribute. Be aware that people can be a non-native or a native English speaker, they might not understand thing or they might be very sensitive to how your word things. Use emoji to express your feelings (heart, star, smile, etc.). Some good tips about giving feedback to merge requests is in the [Thoughtbot code review guide](https://github.com/thoughtbot/guides/tree/master/code-review).
## Priorities of the issue team
@@ -73,7 +71,7 @@ Thanks for the issue report. Please reformat your issue to conform to the issue
### Feature requests
-Thanks for your interest in GitLab. We don't use the issue tracker for feature requests. Please use http://feedback.gitlab.com/ for this purpose or create a merge request implementing this feature. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information.
+Thank you for your interest in improving GitLab. We don't use the issue tracker for feature requests. Things that are wrong but are not a regression compared to older versions of GitLab are considered feature requests and not issues. Please the [feature request forum](http://feedback.gitlab.com/) for this purpose or create a merge request implementing this feature. Have a look at the \[contribution guidelines\]\(https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) for more information.
### Issue report for old version
diff --git a/Procfile b/Procfile
index 9003369c938..18df7e78f9b 100644
--- a/Procfile
+++ b/Procfile
@@ -1,2 +1,2 @@
-web: bundle exec unicorn_rails -p $PORT -E development
+web: bundle exec unicorn_rails -p $PORT -E development -c config/unicorn_development.rb
worker: bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,common,default,gitlab_shell
diff --git a/README.md b/README.md
index b23c0bb14f9..2668ed8bac0 100644
--- a/README.md
+++ b/README.md
@@ -71,7 +71,7 @@ Since 2011 GitLab is released on the 22nd of every month. Every new release incl
It is recommended to follow a monthly upgrade schedule. Security releases come out when needed. For more information about the release process see the documentation for [monthly](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/release/monthly.md) and [security](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/release/security.md) releases.
-* Features that will be in the next releases are listed on [the feedback and suggestions forum](http://feedback.gitlab.com/forums/176466-general) with the status [started](http://feedback.gitlab.com/forums/176466-general/status/796456) and [completed](http://feedback.gitlab.com/forums/176466-general/status/796457).
+* Features that will be in the next releases are listed on the [feature request forum](http://feedback.gitlab.com/forums/176466-general) with the status [started](http://feedback.gitlab.com/forums/176466-general/status/796456) and [completed](http://feedback.gitlab.com/forums/176466-general/status/796457).
### Run in production mode
@@ -96,14 +96,9 @@ or start each component separately
### Run the tests
-* Seed the database
-
- bundle exec rake db:setup RAILS_ENV=test
- bundle exec rake db:seed_fu RAILS_ENV=test
-
* Run all tests
- bundle exec rake gitlab:test RAILS_ENV=test
+ bundle exec rake test
* [RSpec](http://rspec.info/) unit and functional tests
@@ -134,22 +129,4 @@ or start each component separately
### Getting help
-* [Maintenance policy](MAINTENANCE.md) specifies what versions are supported.
-
-* [Troubleshooting guide](https://github.com/gitlabhq/gitlab-public-wiki/wiki/Trouble-Shooting-Guide) contains solutions to common problems.
-
-* [Mailing list](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.
-
-* [Contributing guide](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/CONTRIBUTING.md) describes how to submit merge requests and issues. Pull requests and issues not in line with the guidelines in this document will be closed.
-
-* [Support subscription](http://www.gitlab.com/subscription/) connects you to the knowledge of GitLab experts that will resolve your issues and answer your questions.
-
-* [Consultancy](http://www.gitlab.com/consultancy/) from the GitLab experts for installations, upgrades and customizations.
-
-* [#gitlab IRC channel](http://www.freenode.net/) on Freenode to get in touch with other GitLab users and get help, it's managed by James Newton (newton), Drew Blessing (dblessing), and Sam Gleske (sag47).
-
-* [Book](http://www.packtpub.com/gitlab-repository-management/book) written by GitLab enthusiast Jonathan M. Hethey is unofficial but it offers a good overview.
-
-* [Gitter chat room](https://gitter.im/gitlabhq/gitlabhq#) here you can ask questions when you need help.
+Please see [Getting help for GitLab](https://www.gitlab.com/getting-help/) on our website for the many options to get help.
diff --git a/VERSION b/VERSION
index 998707b421c..38f2fa89925 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-6.7.0.pre
+6.8.0.pre
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
deleted file mode 100644
index 4a393dbfe81..00000000000
--- a/app/assets/javascripts/application.js
+++ /dev/null
@@ -1,31 +0,0 @@
-// This is a manifest file that'll be compiled into including all the files listed below.
-// Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
-// be included in the compiled file accessible from http://example.com/assets/application.js
-// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
-// the compiled file.
-//
-//= require jquery
-//= require jquery.ui.all
-//= require jquery_ujs
-//= require jquery.cookie
-//= require jquery.endless-scroll
-//= require jquery.highlight
-//= require jquery.history
-//= require jquery.waitforimages
-//= require jquery.atwho
-//= require jquery.scrollto
-//= require jquery.blockUI
-//= require turbolinks
-//= require jquery.turbolinks
-//= require bootstrap
-//= require modernizr
-//= require select2
-//= require raphael
-//= require g.raphael-min
-//= require g.bar-min
-//= require branch-graph
-//= require highlightjs.min
-//= require ace/ace
-//= require_tree .
-//= require d3
-//= require underscore
diff --git a/app/assets/javascripts/main.js.coffee b/app/assets/javascripts/application.js.coffee
index 70e8972d24d..5042221abe4 100644
--- a/app/assets/javascripts/main.js.coffee
+++ b/app/assets/javascripts/application.js.coffee
@@ -1,3 +1,37 @@
+# This is a manifest file that'll be compiled into including all the files listed below.
+# Add new JavaScript/Coffee code in separate files in this directory and they'll automatically
+# be included in the compiled file accessible from http://example.com/assets/application.js
+# It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
+# the compiled file.
+#
+#= require jquery
+#= require jquery.ui.all
+#= require jquery_ujs
+#= require jquery.cookie
+#= require jquery.endless-scroll
+#= require jquery.highlight
+#= require jquery.history
+#= require jquery.waitforimages
+#= require jquery.atwho
+#= require jquery.scrollto
+#= require jquery.blockUI
+#= require turbolinks
+#= require jquery.turbolinks
+#= require bootstrap
+#= require modernizr
+#= require select2
+#= require raphael
+#= require g.raphael-min
+#= require g.bar-min
+#= require branch-graph
+#= require highlightjs.min
+#= require ace/ace
+#= require d3
+#= require underscore
+#= require nprogress
+#= require nprogress-turbolinks
+#= require_tree .
+
window.slugify = (text) ->
text.replace(/[^-a-zA-Z0-9]+/g, '_').toLowerCase()
@@ -41,19 +75,11 @@ window.linkify = (str) ->
window.simpleFormat = (str) ->
linkify(sanitize(str).replace(/\n/g, '<br />'))
-window.startSpinner = ->
- $('.turbolink-spinner').fadeIn()
-
-window.stopSpinner = ->
- $('.turbolink-spinner').fadeOut()
-
window.unbindEvents = ->
$(document).unbind('scroll')
$(document).off('scroll')
-document.addEventListener("page:fetch", startSpinner)
document.addEventListener("page:fetch", unbindEvents)
-document.addEventListener("page:change", stopSpinner)
$ ->
# Click a .one_click_select field, select the contents
diff --git a/app/assets/javascripts/gfm_auto_complete.js.coffee b/app/assets/javascripts/gfm_auto_complete.js.coffee
index dd12000a1cf..00d56ae5b4b 100644
--- a/app/assets/javascripts/gfm_auto_complete.js.coffee
+++ b/app/assets/javascripts/gfm_auto_complete.js.coffee
@@ -6,7 +6,6 @@ GitLab.GfmAutoComplete =
dataSource: ''
# Emoji
Emoji:
- assetBase: ''
template: '<li data-value="${insert}">${name} <img alt="${name}" height="20" src="${image}" width="20" /></li>'
# Team Members
@@ -27,7 +26,7 @@ GitLab.GfmAutoComplete =
tpl: @Emoji.template
callbacks:
before_save: (emojis) =>
- $.map emojis, (em) => name: em, insert: em+ ':', image: "#{@Emoji.assetBase}/#{em}.png"
+ $.map emojis, (em) => name: em.name, insert: em.name+ ':', image: em.path
# Team Members
input.atwho
diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss
index 33466714681..4b7103010bb 100644
--- a/app/assets/stylesheets/application.scss
+++ b/app/assets/stylesheets/application.scss
@@ -7,6 +7,8 @@
*= require select2
*= require highlightjs.min
*= require_self
+ *= require nprogress
+ *= require nprogress-bootstrap
*/
@import "main/variables.scss";
diff --git a/app/assets/stylesheets/generic/common.scss b/app/assets/stylesheets/generic/common.scss
index b5ccaed0401..4e660d0b1e0 100644
--- a/app/assets/stylesheets/generic/common.scss
+++ b/app/assets/stylesheets/generic/common.scss
@@ -355,3 +355,7 @@ table {
@media (max-width: $screen-xs-max) {
.container .content { margin-top: 20px; }
}
+
+.wiki .highlight, .note-body .highlight {
+ margin-bottom: 9px;
+}
diff --git a/app/assets/stylesheets/generic/typography.scss b/app/assets/stylesheets/generic/typography.scss
index 3a31e28e0ac..a4419551738 100644
--- a/app/assets/stylesheets/generic/typography.scss
+++ b/app/assets/stylesheets/generic/typography.scss
@@ -88,9 +88,6 @@ a:focus {
.wiki {
@include md-typography;
- font-size: 14px;
- line-height: 1.6;
-
/* Link to current header. */
h1, h2, h3, h4, h5, h6 {
position: relative;
@@ -120,3 +117,11 @@ a:focus {
.md {
@include md-typography;
}
+
+/**
+ * Textareas intended for GFM
+ *
+ */
+textarea.js-gfm-input {
+ font-family: $monospace_font;
+}
diff --git a/app/assets/stylesheets/main/mixins.scss b/app/assets/stylesheets/main/mixins.scss
index 4afe61d756c..fcc7374d0d9 100644
--- a/app/assets/stylesheets/main/mixins.scss
+++ b/app/assets/stylesheets/main/mixins.scss
@@ -84,6 +84,9 @@
}
@mixin md-typography {
+ font-size: 14px;
+ line-height: 1.6;
+
img {
max-width: 100%;
}
diff --git a/app/assets/stylesheets/print.scss b/app/assets/stylesheets/print.scss
new file mode 100644
index 00000000000..42dbf4d6ef3
--- /dev/null
+++ b/app/assets/stylesheets/print.scss
@@ -0,0 +1,13 @@
+/* Generic print styles */
+header, nav, nav.main-nav, nav.navbar-collapse, nav.navbar-collapse.collapse {display: none!important;}
+.profiler-results {display: none;}
+
+/* Styles targeted specifically at printing files */
+.tree-ref-holder, .tree-holder .breadcrumb, .blob-commit-info {display: none;}
+.file-title {display: none;}
+.file-holder {border: none;}
+
+.wiki h1, .wiki h2, .wiki h3, .wiki h4, .wiki h5, .wiki h6 {margin-top: 17px; }
+.wiki h1 {font-size: 30px;}
+.wiki h2 {font-size: 22px;}
+.wiki h3 {font-size: 18px; font-weight: bold; }
diff --git a/app/assets/stylesheets/sections/dashboard.scss b/app/assets/stylesheets/sections/dashboard.scss
index 6fc394e2e2b..e088ef82203 100644
--- a/app/assets/stylesheets/sections/dashboard.scss
+++ b/app/assets/stylesheets/sections/dashboard.scss
@@ -61,7 +61,7 @@
}
.project-row, .group-row {
- padding: 10px 12px !important;
+ padding: 8px 12px !important;
font-size: 14px;
line-height: 24px;
diff --git a/app/assets/stylesheets/sections/diff.scss b/app/assets/stylesheets/sections/diff.scss
index 813566c4def..eb272f20f40 100644
--- a/app/assets/stylesheets/sections/diff.scss
+++ b/app/assets/stylesheets/sections/diff.scss
@@ -62,6 +62,29 @@
font-size: 12px;
}
}
+
+ .text-file-parallel div {
+ display: inline-block;
+ padding-bottom: 16px;
+ }
+ .diff-side {
+ overflow-x: scroll;
+ width: 508px;
+ height: 700px;
+ }
+ .diff-side.diff-side-left{
+ overflow-y:hidden;
+ }
+ .diff-side table, td.diff-middle table {
+ height: 700px;
+ }
+ .diff-middle {
+ width: 114px;
+ vertical-align: top;
+ height: 700px;
+ overflow: hidden
+ }
+
.old_line, .new_line, .diff_line {
margin: 0px;
padding: 0px;
@@ -125,8 +148,6 @@
}
&.parallel {
display: table-cell;
- overflow: hidden;
- width: 50%;
}
}
}
diff --git a/app/assets/stylesheets/sections/events.scss b/app/assets/stylesheets/sections/events.scss
index 6ef12b20a5a..b68f882220e 100644
--- a/app/assets/stylesheets/sections/events.scss
+++ b/app/assets/stylesheets/sections/events.scss
@@ -42,7 +42,7 @@
}
}
- padding: 14px 0px;
+ padding: 12px 0px;
border-bottom: 1px solid #eee;
.event-title {
color: #333;
@@ -63,6 +63,10 @@
color: #666;
margin-top: 5px;
+ .md {
+ font-size: 13px;
+ }
+
pre {
border: none;
background: #f9f9f9;
diff --git a/app/assets/stylesheets/sections/header.scss b/app/assets/stylesheets/sections/header.scss
index f8da4f0f87b..06709bd7ef6 100644
--- a/app/assets/stylesheets/sections/header.scss
+++ b/app/assets/stylesheets/sections/header.scss
@@ -273,3 +273,9 @@ header {
}
}
}
+
+@media (max-width: $screen-xs-max) {
+ #nprogress .spinner {
+ right: 35px !important;
+ }
+}
diff --git a/app/assets/stylesheets/sections/notes.scss b/app/assets/stylesheets/sections/notes.scss
index a65771974c6..4d7a873a519 100644
--- a/app/assets/stylesheets/sections/notes.scss
+++ b/app/assets/stylesheets/sections/notes.scss
@@ -27,11 +27,15 @@ ul.notes {
.discussion-last-update,
.note-last-update {
- font-style: italic;
+ &:before {
+ content: "\00b7";
+ }
+ font-size: 13px;
}
.author {
- color: $style_color;
+ color: #555;
font-weight: bold;
+ font-size: 14px;
&:hover {
color: $primary_color;
}
diff --git a/app/controllers/passwords_controller.rb b/app/controllers/passwords_controller.rb
new file mode 100644
index 00000000000..988ede3007b
--- /dev/null
+++ b/app/controllers/passwords_controller.rb
@@ -0,0 +1,18 @@
+class PasswordsController < Devise::PasswordsController
+
+ def create
+ email = resource_params[:email]
+ resource_found = resource_class.find_by_email(email)
+ if resource_found && resource_found.ldap_user?
+ flash[:alert] = "Cannot reset password for LDAP user."
+ respond_with({}, :location => after_sending_reset_password_instructions_path_for(resource_name)) and return
+ end
+
+ self.resource = resource_class.send_reset_password_instructions(resource_params)
+ if successfully_sent?(resource)
+ respond_with({}, :location => after_sending_reset_password_instructions_path_for(resource_name))
+ else
+ respond_with(resource)
+ end
+ end
+end
diff --git a/app/controllers/profiles/keys_controller.rb b/app/controllers/profiles/keys_controller.rb
index b4f14e649e2..6713cd7c8c7 100644
--- a/app/controllers/profiles/keys_controller.rb
+++ b/app/controllers/profiles/keys_controller.rb
@@ -41,7 +41,7 @@ class Profiles::KeysController < ApplicationController
begin
user = User.find_by_username(params[:username])
if user.present?
- render text: user.all_ssh_keys.join("\n")
+ render text: user.all_ssh_keys.join("\n"), content_type: "text/plain"
else
render_404 and return
end
diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb
index 9d97c820f38..eef849d8209 100644
--- a/app/controllers/projects/issues_controller.rb
+++ b/app/controllers/projects/issues_controller.rb
@@ -76,7 +76,7 @@ class Projects::IssuesController < Projects::ApplicationController
end
def update
- @issue.update_attributes(params[:issue].merge(author_id_of_changes: current_user.id))
+ @issue.update_attributes(params[:issue])
@issue.reset_events_cache
respond_to do |format|
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 38e567f3b13..e6edceb1fbc 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -109,7 +109,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
params[:merge_request].delete(:source_project_id)
params[:merge_request].delete(:target_project_id)
- if @merge_request.update_attributes(params[:merge_request].merge(author_id_of_changes: current_user.id))
+ if @merge_request.update_attributes(params[:merge_request])
@merge_request.reset_events_cache
respond_to do |format|
diff --git a/app/controllers/projects/milestones_controller.rb b/app/controllers/projects/milestones_controller.rb
index aea92a19f34..05237bbd2d2 100644
--- a/app/controllers/projects/milestones_controller.rb
+++ b/app/controllers/projects/milestones_controller.rb
@@ -38,7 +38,6 @@ class Projects::MilestonesController < Projects::ApplicationController
def create
@milestone = @project.milestones.new(params[:milestone])
- @milestone.author_id_of_changes = current_user.id
if @milestone.save
redirect_to project_milestone_path(@project, @milestone)
@@ -48,7 +47,7 @@ class Projects::MilestonesController < Projects::ApplicationController
end
def update
- @milestone.update_attributes(params[:milestone].merge(author_id_of_changes: current_user.id))
+ @milestone.update_attributes(params[:milestone])
respond_to do |format|
format.js
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 8d24052f724..ebb8a90c630 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -123,11 +123,20 @@ class ProjectsController < ApplicationController
end
def autocomplete_sources
+ note_type = params['type']
+ note_id = params['type_id']
+ participating = if note_type && note_id
+ participants_in(note_type, note_id)
+ else
+ []
+ end
+ team_members = sorted(@project.team.members)
+ participants = team_members + participating
@suggestions = {
- emojis: Emoji.names,
+ emojis: Emoji.names.map { |e| { name: e, path: view_context.image_url("emoji/#{e}.png") } },
issues: @project.issues.select([:iid, :title, :description]),
mergerequests: @project.merge_requests.select([:iid, :title, :description]),
- members: @project.team.members.sort_by(&:username).map { |user| { username: user.username, name: user.name } }
+ members: participants.uniq
}
respond_to do |format|
@@ -162,4 +171,25 @@ class ProjectsController < ApplicationController
def user_layout
current_user ? "projects" : "public_projects"
end
+
+ def participants_in(type, id)
+ users = case type
+ when "Issue"
+ issue = @project.issues.find_by_iid(id)
+ issue ? issue.participants : []
+ when "MergeRequest"
+ merge_request = @project.merge_requests.find_by_iid(id)
+ merge_request ? merge_request.participants : []
+ when "Commit"
+ author_ids = Note.for_commit_id(id).pluck(:author_id).uniq
+ User.where(id: author_ids)
+ else
+ []
+ end
+ sorted(users)
+ end
+
+ def sorted(users)
+ users.uniq.sort_by(&:username).map { |user| { username: user.username, name: user.name } }
+ end
end
diff --git a/app/finders/base_finder.rb b/app/finders/base_finder.rb
index d20716fb170..7fc5840561c 100644
--- a/app/finders/base_finder.rb
+++ b/app/finders/base_finder.rb
@@ -47,9 +47,9 @@ class BaseFinder
[]
end
elsif current_user && params[:authorized_only].presence
- klass.of_projects(current_user.authorized_projects)
+ klass.of_projects(current_user.authorized_projects).references(:project)
else
- klass.of_projects(Project.accessible_to(current_user))
+ klass.of_projects(Project.accessible_to(current_user)).references(:project)
end
end
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index 5e5f3f77a21..c6e4f574b67 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -105,8 +105,80 @@ module CommitsHelper
branches.sort.map { |branch| link_to(branch, project_tree_path(project, branch)) }.join(", ").html_safe
end
- def get_old_file(project, commit, diff)
- project.repository.blob_at(commit.parent_id, diff.old_path) if commit.parent_id
+ def parallel_diff_lines(project, commit, diff, file)
+ old_file = project.repository.blob_at(commit.parent_id, diff.old_path) if commit.parent_id
+ deleted_lines = {}
+ added_lines = {}
+ each_diff_line(diff, 0) do |line, type, line_code, line_new, line_old|
+ if type == "old"
+ deleted_lines[line_old] = { line_code: line_code, type: type, line: line }
+ elsif type == "new"
+ added_lines[line_new] = { line_code: line_code, type: type, line: line }
+ end
+ end
+ max_length = old_file ? old_file.sloc + added_lines.length : file.sloc
+
+ offset1 = 0
+ offset2 = 0
+ old_lines = []
+ new_lines = []
+
+ max_length.times do |line_index|
+ line_index1 = line_index - offset1
+ line_index2 = line_index - offset2
+ deleted_line = deleted_lines[line_index1 + 1]
+ added_line = added_lines[line_index2 + 1]
+ old_line = old_file.lines[line_index1] if old_file
+ new_line = file.lines[line_index2]
+
+ if deleted_line && added_line
+ elsif deleted_line
+ new_line = nil
+ offset2 += 1
+ elsif added_line
+ old_line = nil
+ offset1 += 1
+ end
+
+ old_lines[line_index] = DiffLine.new
+ new_lines[line_index] = DiffLine.new
+
+ # old
+ if line_index == 0 && diff.new_file
+ old_lines[line_index].type = :file_created
+ old_lines[line_index].content = 'File was created'
+ elsif deleted_line
+ old_lines[line_index].type = :deleted
+ old_lines[line_index].content = old_line
+ old_lines[line_index].num = line_index1 + 1
+ old_lines[line_index].code = deleted_line[:line_code]
+ elsif old_line
+ old_lines[line_index].type = :no_change
+ old_lines[line_index].content = old_line
+ old_lines[line_index].num = line_index1 + 1
+ else
+ old_lines[line_index].type = :added
+ end
+
+ # new
+ if line_index == 0 && diff.deleted_file
+ new_lines[line_index].type = :file_deleted
+ new_lines[line_index].content = "File was deleted"
+ elsif added_line
+ new_lines[line_index].type = :added
+ new_lines[line_index].num = line_index2 + 1
+ new_lines[line_index].content = new_line
+ new_lines[line_index].code = added_line[:line_code]
+ elsif new_line
+ new_lines[line_index].type = :no_change
+ new_lines[line_index].num = line_index2 + 1
+ new_lines[line_index].content = new_line
+ else
+ new_lines[line_index].type = :deleted
+ end
+ end
+
+ return old_lines, new_lines
end
protected
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 1381b0220d6..ba25a87f392 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -20,7 +20,7 @@ module MergeRequestsHelper
target_project_id: target_project.id,
source_branch: event.branch_name,
target_branch: target_project.repository.root_ref,
- title: event.branch_name.titleize
+ title: event.branch_name.humanize
}
end
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index 2dbc1cffb16..50501dffefb 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -40,7 +40,7 @@ module TreeHelper
# Returns boolean
def markup?(filename)
filename.downcase.end_with?(*%w(.textile .rdoc .org .creole
- .mediawiki .rst .asciidoc .pod))
+ .mediawiki .rst .adoc .asciidoc .pod))
end
def gitlab_markdown?(filename)
diff --git a/app/mailers/emails/merge_requests.rb b/app/mailers/emails/merge_requests.rb
index 5e1b8faf13e..a97d55f1b50 100644
--- a/app/mailers/emails/merge_requests.rb
+++ b/app/mailers/emails/merge_requests.rb
@@ -29,11 +29,11 @@ module Emails
subject: subject("#{@merge_request.title} (!#{@merge_request.iid})"))
end
- def merged_merge_request_email(recipient_id, merge_request_id)
+ def merged_merge_request_email(recipient_id, merge_request_id, updated_by_user_id)
@merge_request = MergeRequest.find(merge_request_id)
@project = @merge_request.project
@target_url = project_merge_request_url(@project, @merge_request)
- mail(from: sender(@merge_request.author_id_of_changes),
+ mail(from: sender(updated_by_user_id),
to: recipient(recipient_id),
subject: subject("#{@merge_request.title} (!#{@merge_request.iid})"))
end
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 75989888bfa..de167f8803a 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -37,8 +37,6 @@ module Issuable
allow_nil: true,
prefix: true
- attr_accessor :author_id_of_changes
-
attr_mentionable :title, :description
end
diff --git a/app/models/diff_line.rb b/app/models/diff_line.rb
new file mode 100644
index 00000000000..ad37945874a
--- /dev/null
+++ b/app/models/diff_line.rb
@@ -0,0 +1,3 @@
+class DiffLine
+ attr_accessor :type, :content, :num, :code
+end
diff --git a/app/models/event.rb b/app/models/event.rb
index d43d6eb682f..5c156856d79 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -47,14 +47,6 @@ class Event < ActiveRecord::Base
scope :in_projects, ->(project_ids) { where(project_id: project_ids).recent }
class << self
- def determine_action(record)
- if [Issue, MergeRequest].include? record.class
- Event::CREATED
- elsif record.kind_of? Note
- Event::COMMENTED
- end
- end
-
def create_ref_event(project, user, ref, action = 'add', prefix = 'refs/heads')
commit = project.repository.commit(ref.target)
diff --git a/app/models/issue.rb b/app/models/issue.rb
index a8dc6e5fd85..21040327741 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -30,8 +30,7 @@ class Issue < ActiveRecord::Base
scope :of_user_team, ->(team) { where(project_id: team.project_ids, assignee_id: team.member_ids) }
attr_accessible :title, :assignee_id, :position, :description,
- :milestone_id, :label_list, :author_id_of_changes,
- :state_event
+ :milestone_id, :label_list, :state_event
acts_as_taggable_on :labels
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 7c2648d8c7a..5c2b0656d40 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -38,7 +38,7 @@ class MergeRequest < ActiveRecord::Base
delegate :commits, :diffs, :last_commit, :last_commit_short_sha, to: :merge_request_diff, prefix: nil
- attr_accessible :title, :assignee_id, :source_project_id, :source_branch, :target_project_id, :target_branch, :milestone_id, :author_id_of_changes, :state_event, :description
+ attr_accessible :title, :assignee_id, :source_project_id, :source_branch, :target_project_id, :target_branch, :milestone_id, :state_event, :description
attr_accessor :should_remove_source_branch
diff --git a/app/models/milestone.rb b/app/models/milestone.rb
index 1a73fa71e48..e16529a634c 100644
--- a/app/models/milestone.rb
+++ b/app/models/milestone.rb
@@ -16,8 +16,7 @@
class Milestone < ActiveRecord::Base
include InternalId
- attr_accessible :title, :description, :due_date, :state_event, :author_id_of_changes
- attr_accessor :author_id_of_changes
+ attr_accessible :title, :description, :due_date, :state_event
belongs_to :project
has_many :issues
@@ -89,6 +88,6 @@ class Milestone < ActiveRecord::Base
end
def author_id
- author_id_of_changes
+ nil
end
end
diff --git a/app/models/note.rb b/app/models/note.rb
index 48c03c9d587..906de4855ab 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -199,7 +199,8 @@ class Note < ActiveRecord::Base
def downvote?
votable? && (note.start_with?('-1') ||
note.start_with?(':-1:') ||
- note.start_with?(':thumbsdown:')
+ note.start_with?(':thumbsdown:') ||
+ note.start_with?(':thumbs_down_sign:')
)
end
@@ -249,7 +250,8 @@ class Note < ActiveRecord::Base
def upvote?
votable? && (note.start_with?('+1') ||
note.start_with?(':+1:') ||
- note.start_with?(':thumbsup:')
+ note.start_with?(':thumbsup:') ||
+ note.start_with?(':thumbs_up_sign:')
)
end
diff --git a/app/models/project.rb b/app/models/project.rb
index 7d7edc45739..769ab217625 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -56,6 +56,7 @@ class Project < ActiveRecord::Base
has_one :flowdock_service, dependent: :destroy
has_one :assembla_service, dependent: :destroy
has_one :gemnasium_service, dependent: :destroy
+ has_one :slack_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
# Merge Requests for target project should be removed with it
@@ -304,7 +305,7 @@ class Project < ActiveRecord::Base
end
def available_services_names
- %w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium)
+ %w(gitlab_ci campfire hipchat pivotaltracker flowdock assembla emails_on_push gemnasium slack)
end
def gitlab_ci?
diff --git a/app/models/project_services/slack_message.rb b/app/models/project_services/slack_message.rb
new file mode 100644
index 00000000000..b2b8d6fed7a
--- /dev/null
+++ b/app/models/project_services/slack_message.rb
@@ -0,0 +1,95 @@
+require 'slack-notifier'
+
+class SlackMessage
+ def initialize(params)
+ @after = params.fetch(:after)
+ @before = params.fetch(:before)
+ @commits = params.fetch(:commits, [])
+ @project_name = params.fetch(:project_name)
+ @project_url = params.fetch(:project_url)
+ @ref = params.fetch(:ref).gsub('refs/heads/', '')
+ @username = params.fetch(:user_name)
+ end
+
+ def compose
+ format(message)
+ end
+
+ private
+
+ attr_reader :after
+ attr_reader :before
+ attr_reader :commits
+ attr_reader :project_name
+ attr_reader :project_url
+ attr_reader :ref
+ attr_reader :username
+
+ def message
+ if new_branch?
+ new_branch_message
+ elsif removed_branch?
+ removed_branch_message
+ else
+ push_message << commit_messages
+ end
+ end
+
+ def format(string)
+ Slack::Notifier::LinkFormatter.format(string)
+ end
+
+ def new_branch_message
+ "#{username} pushed new branch #{branch_link} to #{project_link}"
+ end
+
+ def removed_branch_message
+ "#{username} removed branch #{ref} from #{project_link}"
+ end
+
+ def push_message
+ "#{username} pushed to branch #{branch_link} of #{project_link} (#{compare_link})"
+ end
+
+ def commit_messages
+ commits.each_with_object('') do |commit, str|
+ str << compose_commit_message(commit)
+ end
+ end
+
+ def compose_commit_message(commit)
+ id = commit.fetch(:id)[0..5]
+ message = commit.fetch(:message)
+ url = commit.fetch(:url)
+
+ "\n - #{message} ([#{id}](#{url}))"
+ end
+
+ def new_branch?
+ before =~ /000000/
+ end
+
+ def removed_branch?
+ after =~ /000000/
+ end
+
+ def branch_url
+ "#{project_url}/commits/#{ref}"
+ end
+
+ def compare_url
+ "#{project_url}/compare/#{before}...#{after}"
+ end
+
+ def branch_link
+ "[#{ref}](#{branch_url})"
+ end
+
+ def project_link
+ "[#{project_name}](#{project_url})"
+ end
+
+ def compare_link
+ "[Compare changes](#{compare_url})"
+ end
+end
diff --git a/app/models/project_services/slack_service.rb b/app/models/project_services/slack_service.rb
new file mode 100644
index 00000000000..410dda22d47
--- /dev/null
+++ b/app/models/project_services/slack_service.rb
@@ -0,0 +1,68 @@
+# == 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)
+# subdomain :string(255)
+# room :string(255)
+# api_key :string(255)
+#
+
+class SlackService < Service
+ attr_accessible :room
+ attr_accessible :subdomain
+
+ validates :room, presence: true, if: :activated?
+ validates :subdomain, presence: true, if: :activated?
+ validates :token, presence: true, if: :activated?
+
+ def title
+ 'Slack'
+ end
+
+ def description
+ 'A team communication tool for the 21st century'
+ end
+
+ def to_param
+ 'slack'
+ end
+
+ def fields
+ [
+ { type: 'text', name: 'subdomain', placeholder: '' },
+ { type: 'text', name: 'token', placeholder: '' },
+ { type: 'text', name: 'room', placeholder: 'Ex. #general' },
+ ]
+ end
+
+ def execute(push_data)
+ message = SlackMessage.new(push_data.merge(
+ project_url: project_url,
+ project_name: project_name
+ ))
+
+ notifier = Slack::Notifier.new(subdomain, token)
+ notifier.channel = room
+ notifier.username = 'GitLab'
+ notifier.ping(message.compose)
+ end
+
+ private
+
+ def project_name
+ project.name_with_namespace.gsub(/\s/, '')
+ end
+
+ def project_url
+ project.web_url
+ end
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index a9ee471ad61..25c10a6faa0 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -204,7 +204,7 @@ class User < ActiveRecord::Base
end
def search query
- where("name LIKE :query OR email LIKE :query OR username LIKE :query", query: "%#{query}%")
+ where("lower(name) LIKE :query OR lower(email) LIKE :query OR lower(username) LIKE :query", query: "%#{query.downcase}%")
end
def by_username_or_id(name_or_id)
@@ -249,7 +249,7 @@ class User < ActiveRecord::Base
def namespace_uniq
namespace_name = self.username
if Namespace.find_by(path: namespace_name)
- self.errors.add :username, "already exist"
+ self.errors.add :username, "already exists"
end
end
diff --git a/app/observers/activity_observer.rb b/app/observers/activity_observer.rb
deleted file mode 100644
index d754ac8185a..00000000000
--- a/app/observers/activity_observer.rb
+++ /dev/null
@@ -1,39 +0,0 @@
-class ActivityObserver < BaseObserver
- observe :issue, :note, :milestone
-
- def after_create(record)
- event_author_id = record.author_id
-
- if record.kind_of?(Note)
- # Skip system notes, like status changes and cross-references.
- return true if record.system?
-
- # Skip wall notes to prevent spamming of dashboard
- return true if record.noteable_type.blank?
- end
-
- if event_author_id
- create_event(record, Event.determine_action(record))
- end
- end
-
- def after_close(record, transition)
- create_event(record, Event::CLOSED)
- end
-
- def after_reopen(record, transition)
- create_event(record, Event::REOPENED)
- end
-
- protected
-
- def create_event(record, status)
- Event.create(
- project: record.project,
- target_id: record.id,
- target_type: record.class.name,
- action: status,
- author_id: current_user.id
- )
- end
-end
diff --git a/app/observers/base_observer.rb b/app/observers/base_observer.rb
index f9a0242ce77..d685bd5d819 100644
--- a/app/observers/base_observer.rb
+++ b/app/observers/base_observer.rb
@@ -3,6 +3,10 @@ class BaseObserver < ActiveRecord::Observer
NotificationService.new
end
+ def event_service
+ EventCreateService.new
+ end
+
def log_info message
Gitlab::AppLogger.info message
end
diff --git a/app/observers/issue_observer.rb b/app/observers/issue_observer.rb
index 6ef13eb5d5e..30da1f83da7 100644
--- a/app/observers/issue_observer.rb
+++ b/app/observers/issue_observer.rb
@@ -1,17 +1,20 @@
class IssueObserver < BaseObserver
def after_create(issue)
notification.new_issue(issue, current_user)
+ event_service.open_issue(issue, current_user)
issue.create_cross_references!(issue.project, current_user)
execute_hooks(issue)
end
def after_close(issue, transition)
notification.close_issue(issue, current_user)
+ event_service.close_issue(issue, current_user)
create_note(issue)
execute_hooks(issue)
end
def after_reopen(issue, transition)
+ event_service.reopen_issue(issue, current_user)
create_note(issue)
execute_hooks(issue)
end
diff --git a/app/observers/merge_request_observer.rb b/app/observers/merge_request_observer.rb
index f2e2d16c943..04ee30b4976 100644
--- a/app/observers/merge_request_observer.rb
+++ b/app/observers/merge_request_observer.rb
@@ -1,25 +1,20 @@
-class MergeRequestObserver < ActivityObserver
- observe :merge_request
-
+class MergeRequestObserver < BaseObserver
def after_create(merge_request)
- if merge_request.author_id
- create_event(merge_request, Event.determine_action(merge_request))
- end
-
+ event_service.open_mr(merge_request, current_user)
notification.new_merge_request(merge_request, current_user)
merge_request.create_cross_references!(merge_request.project, current_user)
execute_hooks(merge_request)
end
def after_close(merge_request, transition)
- create_event(merge_request, Event::CLOSED)
+ event_service.close_mr(merge_request, current_user)
notification.close_mr(merge_request, current_user)
create_note(merge_request)
execute_hooks(merge_request)
end
def after_reopen(merge_request, transition)
- create_event(merge_request, Event::REOPENED)
+ event_service.reopen_mr(merge_request, current_user)
create_note(merge_request)
execute_hooks(merge_request)
merge_request.reload_code
@@ -33,16 +28,6 @@ class MergeRequestObserver < ActivityObserver
execute_hooks(merge_request)
end
- def create_event(record, status)
- Event.create(
- project: record.target_project,
- target_id: record.id,
- target_type: record.class.name,
- action: status,
- author_id: current_user.id
- )
- end
-
private
# Create merge request note with service comment like 'Status changed to closed'
diff --git a/app/observers/milestone_observer.rb b/app/observers/milestone_observer.rb
new file mode 100644
index 00000000000..a1a62a99a8f
--- /dev/null
+++ b/app/observers/milestone_observer.rb
@@ -0,0 +1,13 @@
+class MilestoneObserver < BaseObserver
+ def after_create(milestone)
+ event_service.open_milestone(milestone, current_user)
+ end
+
+ def after_close(milestone, transition)
+ event_service.close_milestone(milestone, current_user)
+ end
+
+ def after_reopen(milestone, transition)
+ event_service.reopen_milestone(milestone, current_user)
+ end
+end
diff --git a/app/observers/note_observer.rb b/app/observers/note_observer.rb
index d31b6e8d7ce..337bb1dc5ae 100644
--- a/app/observers/note_observer.rb
+++ b/app/observers/note_observer.rb
@@ -2,6 +2,12 @@ class NoteObserver < BaseObserver
def after_create(note)
notification.new_note(note)
+ # Skip system notes, like status changes and cross-references.
+ # Skip wall notes to prevent spamming of dashboard
+ if note.noteable_type.present? && !note.system
+ event_service.leave_note(note, current_user)
+ end
+
unless note.system?
# Create a cross-reference note if this Note contains GFM that names an
# issue, merge request, or commit.
diff --git a/app/services/event_create_service.rb b/app/services/event_create_service.rb
new file mode 100644
index 00000000000..8d8a5873e62
--- /dev/null
+++ b/app/services/event_create_service.rb
@@ -0,0 +1,64 @@
+# EventCreateService class
+#
+# Used for creating events feed on dashboard after certain user action
+#
+# Ex.
+# EventCreateService.new.new_issue(issue, current_user)
+#
+class EventCreateService
+ def open_issue(issue, current_user)
+ create_event(issue, current_user, Event::CREATED)
+ end
+
+ def close_issue(issue, current_user)
+ create_event(issue, current_user, Event::CLOSED)
+ end
+
+ def reopen_issue(issue, current_user)
+ create_event(issue, current_user, Event::REOPENED)
+ end
+
+ def open_mr(merge_request, current_user)
+ create_event(merge_request, current_user, Event::CREATED)
+ end
+
+ def close_mr(merge_request, current_user)
+ create_event(merge_request, current_user, Event::CLOSED)
+ end
+
+ def reopen_mr(merge_request, current_user)
+ create_event(merge_request, current_user, Event::REOPENED)
+ end
+
+ def merge_mr(merge_request, current_user)
+ create_event(merge_request, current_user, Event::MERGED)
+ end
+
+ def open_milestone(milestone, current_user)
+ create_event(milestone, current_user, Event::CREATED)
+ end
+
+ def close_milestone(milestone, current_user)
+ create_event(milestone, current_user, Event::CLOSED)
+ end
+
+ def reopen_milestone(milestone, current_user)
+ create_event(milestone, current_user, Event::REOPENED)
+ end
+
+ def leave_note(note, current_user)
+ create_event(note, current_user, Event::COMMENTED)
+ end
+
+ private
+
+ def create_event(record, current_user, status)
+ Event.create(
+ project: record.project,
+ target_id: record.id,
+ target_type: record.class.name,
+ action: status,
+ author_id: current_user.id
+ )
+ end
+end
diff --git a/app/services/merge_requests/auto_merge_service.rb b/app/services/merge_requests/auto_merge_service.rb
index d60d61ed54a..e35c03275f2 100644
--- a/app/services/merge_requests/auto_merge_service.rb
+++ b/app/services/merge_requests/auto_merge_service.rb
@@ -9,11 +9,10 @@ module MergeRequests
merge_request.lock
if Gitlab::Satellite::MergeAction.new(current_user, merge_request).merge!(commit_message)
- merge_request.author_id_of_changes = current_user.id
merge_request.merge
- notification.merge_mr(merge_request)
- create_merge_event(merge_request)
+ notification.merge_mr(merge_request, current_user)
+ create_merge_event(merge_request, current_user)
execute_project_hooks(merge_request)
true
diff --git a/app/services/merge_requests/base_merge_service.rb b/app/services/merge_requests/base_merge_service.rb
index dbdb0063074..9bc50d3d16c 100644
--- a/app/services/merge_requests/base_merge_service.rb
+++ b/app/services/merge_requests/base_merge_service.rb
@@ -7,14 +7,8 @@ module MergeRequests
NotificationService.new
end
- def create_merge_event(merge_request)
- Event.create(
- project: merge_request.target_project,
- target_id: merge_request.id,
- target_type: merge_request.class.name,
- action: Event::MERGED,
- author_id: merge_request.author_id_of_changes
- )
+ def create_merge_event(merge_request, current_user)
+ EventCreateService.new.merge_mr(merge_request, current_user)
end
def execute_project_hooks(merge_request)
diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb
index 1d5af04cdbb..680766140bd 100644
--- a/app/services/merge_requests/merge_service.rb
+++ b/app/services/merge_requests/merge_service.rb
@@ -7,11 +7,10 @@ module MergeRequests
# to target branch
class MergeService < BaseMergeService
def execute(merge_request, current_user, commit_message)
- merge_request.author_id_of_changes = current_user.id
merge_request.merge
- notification.merge_mr(merge_request)
- create_merge_event(merge_request)
+ notification.merge_mr(merge_request, current_user)
+ create_merge_event(merge_request, current_user)
execute_project_hooks(merge_request)
true
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index 5daf573630d..6fda9868aa5 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -86,12 +86,12 @@ class NotificationService
# * merge_request assignee if their notification level is not Disabled
# * project team members with notification level higher then Participating
#
- def merge_mr(merge_request)
+ def merge_mr(merge_request, current_user)
recipients = reject_muted_users([merge_request.author, merge_request.assignee], merge_request.target_project)
recipients = recipients.concat(project_watchers(merge_request.target_project)).uniq
recipients.each do |recipient|
- mailer.merged_merge_request_email(recipient.id, merge_request.id)
+ mailer.merged_merge_request_email(recipient.id, merge_request.id, current_user.id)
end
end
@@ -111,6 +111,7 @@ class NotificationService
# ignore gitlab service messages
return true if note.note =~ /\A_Status changed to closed_/
+ return true if note.note =~ /\A_mentioned in / && note.system == true
opts = { noteable_type: note.noteable_type, project_id: note.project_id }
diff --git a/app/views/devise/sessions/_oauth_providers.html.haml b/app/views/devise/sessions/_oauth_providers.html.haml
index 935bc6af505..2b1cb9c694f 100644
--- a/app/views/devise/sessions/_oauth_providers.html.haml
+++ b/app/views/devise/sessions/_oauth_providers.html.haml
@@ -2,10 +2,12 @@
- if providers.present?
%hr
%div{:'data-no-turbolink' => 'data-no-turbolink'}
- %span Sign in with: &nbsp;
+ %span Sign in with*: &nbsp;
- providers.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"
+ %br
+ %small * Make sure your email address is public
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index 9ba20f1347d..d9a7a2d31cf 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -4,7 +4,8 @@
= "#{title} | " if defined?(title)
GitLab
= favicon_link_tag 'favicon.ico'
- = stylesheet_link_tag "application"
+ = stylesheet_link_tag "application", :media => "all"
+ = stylesheet_link_tag "print", :media => "print"
= javascript_include_tag "application"
= csrf_meta_tags
= include_gon
diff --git a/app/views/layouts/_head_panel.html.haml b/app/views/layouts/_head_panel.html.haml
index 5080a1b7ef6..d8001fd76d7 100644
--- a/app/views/layouts/_head_panel.html.haml
+++ b/app/views/layouts/_head_panel.html.haml
@@ -15,10 +15,6 @@
.navbar-collapse.collapse
%ul.nav.navbar-nav
%li.hidden-sm.hidden-xs
- %a
- %div.hide.turbolink-spinner
- %i.icon-refresh.icon-spin
- %li.hidden-sm.hidden-xs
= render "layouts/search"
%li.visible-sm.visible-xs
= link_to search_path, title: "Search", class: 'has_bottom_tooltip', 'data-original-title' => 'Search area' do
diff --git a/app/views/layouts/_init_auto_complete.html.haml b/app/views/layouts/_init_auto_complete.html.haml
index 6a20dedf62f..353f7ce34f1 100644
--- a/app/views/layouts/_init_auto_complete.html.haml
+++ b/app/views/layouts/_init_auto_complete.html.haml
@@ -1,4 +1,3 @@
:javascript
- GitLab.GfmAutoComplete.dataSource = "#{autocomplete_sources_project_path(@project)}"
- GitLab.GfmAutoComplete.Emoji.assetBase = "#{Gitlab.config.gitlab.relative_url_root + '/assets/emoji'}"
+ GitLab.GfmAutoComplete.dataSource = "#{autocomplete_sources_project_path(@project, type: @noteable.class, type_id: params[:id])}"
GitLab.GfmAutoComplete.setup();
diff --git a/app/views/layouts/_public_head_panel.html.haml b/app/views/layouts/_public_head_panel.html.haml
index 99e11cd2b5c..63992a22f32 100644
--- a/app/views/layouts/_public_head_panel.html.haml
+++ b/app/views/layouts/_public_head_panel.html.haml
@@ -8,11 +8,15 @@
%span.separator
%h1.title= title
- .pull-right
+ %button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", type: "button"}
+ %span.sr-only Toggle navigation
+ %i.icon-reorder
+
+ .pull-right.hidden-xs
= link_to "Sign in", new_session_path(:user), class: 'btn btn-sign-in btn-new'
- %ul.nav.navbar-nav
- %li
- %a
- %div.hide.turbolink-spinner
- %i.icon-refresh.icon-spin
+ .navbar-collapse.collapse
+ %ul.nav.navbar-nav
+ %li.visible-xs
+ = link_to "Sign in", new_session_path(:user)
+
diff --git a/app/views/layouts/public_projects.html.haml b/app/views/layouts/public_projects.html.haml
index cf4ca9c7a84..2a9230244f8 100644
--- a/app/views/layouts/public_projects.html.haml
+++ b/app/views/layouts/public_projects.html.haml
@@ -4,7 +4,7 @@
%body{class: "#{app_theme} application", :'data-page' => body_data_page}
= render "layouts/broadcast"
= render "layouts/public_head_panel", title: project_title(@project)
- %nav.main-nav
+ %nav.main-nav.navbar-collapse.collapse
.container= render 'layouts/nav/project'
.container
.content= yield
diff --git a/app/views/notify/repository_push_email.html.haml b/app/views/notify/repository_push_email.html.haml
index ab0d6c653b9..85a01a567f3 100644
--- a/app/views/notify/repository_push_email.html.haml
+++ b/app/views/notify/repository_push_email.html.haml
@@ -7,7 +7,7 @@
%li
#{commit.short_id} - #{commit.title}
-%h4 Diff:
+%h4 Changes:
- @diffs.each do |diff|
%li
%strong
@@ -23,6 +23,6 @@
%br
- if @compare.timeout
- %h5 Huge diff. To prevent performance issues it was hidden
+ %h5 To prevent performance issues changes are hidden
- elsif @compare.commits_over_limit?
- %h5 Diff for big amount of commits is disabled
+ %h5 Changes are not shown due to large amount of commits
diff --git a/app/views/notify/repository_push_email.text.haml b/app/views/notify/repository_push_email.text.haml
index 93b344d2c82..b8d7fbeb046 100644
--- a/app/views/notify/repository_push_email.text.haml
+++ b/app/views/notify/repository_push_email.text.haml
@@ -6,7 +6,7 @@ Commits:
#{commit.short_id} - #{truncate(commit.title, length: 40)}
\
\
-Diff:
+Changes:
- @diffs.each do |diff|
\
\=====================================
@@ -22,4 +22,4 @@ Diff:
- if @compare.timeout
Huge diff. To prevent performance issues it was hidden
- elsif @compare.commits_over_limit?
- Diff for big amount of commits is disabled
+ Changes are not shown due to large amount of commits
diff --git a/app/views/projects/commits/_parallel_view.html.haml b/app/views/projects/commits/_parallel_view.html.haml
index 3234e9da0ac..5b60ab80ba4 100644
--- a/app/views/projects/commits/_parallel_view.html.haml
+++ b/app/views/projects/commits/_parallel_view.html.haml
@@ -1,75 +1,55 @@
/ Side-by-side diff view
-- old_file = get_old_file(project, @commit, diff)
-- deleted_lines = {}
-- added_lines = {}
-- each_diff_line(diff, index) do |line, type, line_code, line_new, line_old, raw_line|
- - if type == "old"
- - deleted_lines[line_old] = { line_code: line_code, type: type, line: line }
- - elsif type == "new"
- - added_lines[line_new] = { line_code: line_code, type: type, line: line }
-
-- max_length = old_file.sloc + added_lines.length if old_file
-- max_length ||= file.sloc
-- offset1 = 0
-- offset2 = 0
+- old_lines, new_lines = parallel_diff_lines(project, @commit, diff, file)
+- num_lines = old_lines.length
%div.text-file-parallel
- %table{ style: "table-layout: fixed;" }
- - max_length.times do |line_index|
- - line_index1 = line_index - offset1
- - line_index2 = line_index - offset2
- - deleted_line = deleted_lines[line_index1 + 1]
- - added_line = added_lines[line_index2 + 1]
- - old_line = old_file.lines[line_index1] if old_file
- - new_line = file.lines[line_index2]
+ %div.diff-side.diff-side-left
+ %table
+ - old_lines.each do |line|
+
+ %tr.line_holder.parallel
+ - if line.type == :file_created
+ %td.line_content.parallel= "File was created"
+ - elsif line.type == :deleted
+ %td.line_content{class: "parallel noteable_line old #{line.code}", "line_code" => line.code }= line.content
+ - else line.type == :no_change
+ %td.line_content.parallel= line.content
+
+ %div.diff-middle
+ %table
+ - num_lines.times do |index|
+ %tr
+ - if old_lines[index].type == :deleted
+ %td.old_line.old= old_lines[index].num
+ - else
+ %td.old_line= old_lines[index].num
+
+ %td.diff_line=""
- - if deleted_line && added_line
- - elsif deleted_line
- - new_line = nil
- - offset2 += 1
- - elsif added_line
- - old_line = nil
- - offset1 += 1
+ - if new_lines[index].type == :added
+ %td.new_line.new= new_lines[index].num
+ - else
+ %td.new_line= new_lines[index].num
- %tr.line_holder.parallel
- - if line_index == 0 && diff.new_file
- %td.line_content.parallel= "File was created"
- %td.old_line= ""
- - elsif deleted_line
- %td.line_content{class: "parallel noteable_line old #{deleted_line[:line_code]}", "line_code" => deleted_line[:line_code] }= old_line
- %td.old_line.old
- = line_index1 + 1
- - if @comments_allowed
- =# render "projects/notes/diff_note_link", line_code: deleted_line[:line_code]
- - elsif old_line
- %td.line_content.parallel= old_line
- %td.old_line= line_index1 + 1
- - else
- %td.line_content.parallel= ""
- %td.old_line= ""
+ %div.diff-side.diff-side-right
+ %table
+ - new_lines.each do |line|
- %td.diff_line= ""
+ %tr.line_holder.parallel
+ - if line.type == :file_deleted
+ %td.line_content.parallel= "File was deleted"
+ - elsif line.type == :added
+ %td.line_content{class: "parallel noteable_line new #{line.code}", "line_code" => line.code }= line.content
+ - else line.type == :no_change
+ %td.line_content.parallel= line.content
- - if diff.deleted_file && line_index == 0
- %td.new_line= ""
- %td.line_content.parallel= "File was deleted"
- - elsif added_line
- %td.new_line.new
- = line_index2 + 1
- - if @comments_allowed
- =# render "projects/notes/diff_note_link", line_code: added_line[:line_code]
- %td.line_content{class: "parallel noteable_line new #{added_line[:line_code]}", "line_code" => added_line[:line_code] }= new_line
- - elsif new_line
- %td.new_line= line_index2 + 1
- %td.line_content.parallel= new_line
- - else
- %td.new_line= ""
- %td.line_content.parallel= ""
+:javascript
+ $('.diff-side-right').on('scroll', function(){
+ $('.diff-side-left, .diff-middle').scrollTop($(this).scrollTop());
+ $('.diff-side-left').scrollLeft($(this).scrollLeft());
+ });
- - if @reply_allowed
- - comments1 = []
- - comments2 = []
- - comments1 = @line_notes.select { |n| n.line_code == deleted_line[:line_code] }.sort_by(&:created_at) if deleted_line
- - comments2 = @line_notes.select { |n| n.line_code == added_line[:line_code] }.sort_by(&:created_at) if added_line
- - unless comments1.empty? && comments2.empty?
- = render "projects/notes/diff_notes_with_reply_parallel", notes1: comments1, notes2: comments2, line1: deleted_line, line2: added_line \ No newline at end of file
+ $('.diff-side-left').on('scroll', function(){
+ $('.diff-side-right, .diff-middle').scrollTop($(this).scrollTop()); // might never be relevant
+ $('.diff-side-right').scrollLeft($(this).scrollLeft());
+ });
diff --git a/app/views/projects/commits/_text_file.html.haml b/app/views/projects/commits/_text_file.html.haml
index c827d96d855..ba83d2e5a0f 100644
--- a/app/views/projects/commits/_text_file.html.haml
+++ b/app/views/projects/commits/_text_file.html.haml
@@ -1,6 +1,6 @@
- too_big = diff.diff.lines.count > 1000
- if too_big
- %a.supp_diff_link Diff suppressed. Click to show
+ %a.supp_diff_link Changes suppressed. Click to show
%table.text-file{class: "#{'hide' if too_big}"}
- each_diff_line(diff, index) do |line, type, line_code, line_new, line_old, raw_line|
diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml
index 9bd49855369..57331bff31b 100644
--- a/app/views/projects/compare/show.html.haml
+++ b/app/views/projects/compare/show.html.haml
@@ -18,17 +18,17 @@
- else
%ul.well-list= render Commit.decorate(@commits), project: @project
- %h4 Diff
+ %h4 Changes
- if @diffs.present?
= render "projects/commits/diffs", diffs: @diffs, project: @project
- elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
.bs-callout.bs-callout-danger
%h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits.
- %p To preserve performance the line diff is not shown.
+ %p To preserve performance the line changes are not shown.
- elsif @timeout
.bs-callout.bs-callout-danger
- %h4 Diff for this comparison is extremely large.
- %p Use command line to browse diff for this comparison.
+ %h4 Number of changed files for this comparison is extremely large.
+ %p Use command line to browse through changes for this comparison.
- else
diff --git a/app/views/projects/deploy_keys/show.html.haml b/app/views/projects/deploy_keys/show.html.haml
index 67615e1781f..c66e6bc69c3 100644
--- a/app/views/projects/deploy_keys/show.html.haml
+++ b/app/views/projects/deploy_keys/show.html.haml
@@ -2,7 +2,7 @@
Deploy key:
= @key.title
%small
- created at
+ created on
= @key.created_at.stamp("Aug 21, 2011")
.back-link
= link_to project_deploy_keys_path(@project) do
diff --git a/app/views/projects/issues/_form.html.haml b/app/views/projects/issues/_form.html.haml
index dd091302c8e..05cae80e50c 100644
--- a/app/views/projects/issues/_form.html.haml
+++ b/app/views/projects/issues/_form.html.haml
@@ -1,7 +1,7 @@
%div.issue-form-holder
%h3.page-title= @issue.new_record? ? "New Issue" : "Edit Issue ##{@issue.iid}"
%hr
- - if @repository.contribution_guide && !@issue.persisted?
+ - if !@repository.empty? && @repository.contribution_guide && !@issue.persisted?
- contribution_guide_url = project_blob_path(@project, tree_join(@repository.root_ref, @repository.contribution_guide.name))
.alert.alert-info.col-sm-10.col-sm-offset-2
="Please review the <strong>#{link_to "guidelines for contribution", contribution_guide_url}</strong> to this repository.".html_safe
diff --git a/app/views/projects/merge_requests/_form.html.haml b/app/views/projects/merge_requests/_form.html.haml
index 51fa29ddcbe..22502760e50 100644
--- a/app/views/projects/merge_requests/_form.html.haml
+++ b/app/views/projects/merge_requests/_form.html.haml
@@ -1,13 +1,18 @@
-- if @repository.contribution_guide && !@merge_request.persisted?
- - contribution_guide_url = project_blob_path(@project, tree_join(@repository.root_ref, @repository.contribution_guide.name))
- .alert.alert-info.col-sm-10.col-sm-offset-2
- ="Please review the <strong>#{link_to "guidelines for contribution", contribution_guide_url}</strong> to this repository.".html_safe
= form_for [@project, @merge_request], html: { class: "merge-request-form form-horizontal" } do |f|
- -if @merge_request.errors.any?
- .alert.alert-danger
- %ul
- - @merge_request.errors.full_messages.each do |msg|
- %li= msg
+ .row
+ .col-sm-2
+ .col-sm-10
+ - if @repository.contribution_guide && !@merge_request.persisted?
+ - contribution_guide_url = project_blob_path(@project, tree_join(@repository.root_ref, @repository.contribution_guide.name))
+ .alert.alert-info
+ Please review the
+ %strong #{link_to "guidelines for contribution", contribution_guide_url}
+ to this repository.
+
+ -if @merge_request.errors.any?
+ .alert.alert-danger
+ - @merge_request.errors.full_messages.each do |msg|
+ %div= msg
.merge-request-branches
.form-group
@@ -47,24 +52,6 @@
= f.text_area :description, class: "form-control js-gfm-input", rows: 14
%p.hint Description is parsed with #{link_to "GitLab Flavored Markdown", help_markdown_path, target: '_blank'}.
- %hr
- .form-group
- .merge-request-assignee
- = f.label :assignee_id, class: 'control-label' do
- %i.icon-user
- Assign to
- .col-sm-10
- = project_users_select_tag('merge_request[assignee_id]', placeholder: 'Select a user', class: 'custom-form-control', selected: @merge_request.assignee_id)
- &nbsp;
- = link_to 'Assign to me', '#', class: 'btn btn-small assign-to-me-link'
- .form-group
- .merge-request-milestone
- = f.label :milestone_id, class: 'control-label' do
- %i.icon-time
- Milestone
- .col-sm-10= f.select(:milestone_id, milestone_options(@merge_request), { include_blank: "Select milestone" }, {class: 'select2'})
-
-
.form-actions
- if @merge_request.new_record?
= f.submit 'Submit merge request', class: "btn btn-create"
@@ -96,7 +83,3 @@
target_branch.on("change", function() {
$.get("#{branch_to_project_merge_requests_path(@source_project)}", {target_project_id: target_project.val(),ref: $(this).val() });
});
- $('.assign-to-me-link').on('click', function(e){
- $('#merge_request_assignee_id').val("#{current_user.id}").trigger("change");
- e.preventDefault();
- });
diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml
index 809b01918cf..7a21c0dd069 100644
--- a/app/views/projects/merge_requests/_show.html.haml
+++ b/app/views/projects/merge_requests/_show.html.haml
@@ -20,7 +20,7 @@
%li.diffs-tab{data: {action: 'diffs'}}
= link_to diffs_project_merge_request_path(@project, @merge_request) do
%i.icon-list-alt
- Diff
+ Changes
- content_for :note_actions do
- if can?(current_user, :modify_merge_request, @merge_request)
diff --git a/app/views/projects/merge_requests/branch_from.js.haml b/app/views/projects/merge_requests/branch_from.js.haml
index d3147188d1c..1b1082baafe 100644
--- a/app/views/projects/merge_requests/branch_from.js.haml
+++ b/app/views/projects/merge_requests/branch_from.js.haml
@@ -3,5 +3,5 @@
var mrTitle = $('#merge_request_title');
if(mrTitle.val().length == 0) {
- mrTitle.val("#{params[:ref].titleize}");
+ mrTitle.val("#{params[:ref].humanize}");
}
diff --git a/app/views/projects/merge_requests/show/_diffs.html.haml b/app/views/projects/merge_requests/show/_diffs.html.haml
index 7c4f43d2d80..3d48514f98b 100644
--- a/app/views/projects/merge_requests/show/_diffs.html.haml
+++ b/app/views/projects/merge_requests/show/_diffs.html.haml
@@ -5,7 +5,7 @@
- else
.bs-callout.bs-callout-warning
%h4
- Diff for this comparison is extremely large.
+ Changes view for this comparison is extremely large.
%p
You can
= link_to "download it", project_merge_request_path(@merge_request.source_project, @merge_request, format: :diff), class: "vlink"
diff --git a/app/views/projects/merge_requests/show/_mr_accept.html.haml b/app/views/projects/merge_requests/show/_mr_accept.html.haml
index 97706a5a4b0..bd7c8435f4c 100644
--- a/app/views/projects/merge_requests/show/_mr_accept.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_accept.html.haml
@@ -1,6 +1,13 @@
- unless @allowed_to_merge
- .bs-callout
- %strong You don't have permission to merge this MR
+ - if @project.archived?
+ .bs-callout.bs-callout-warning
+ %strong Archived projects cannot be committed to!
+ - else
+ .bs-callout
+ .automerge_widget.cannot_be_merged.hide
+ %strong This can't be merged automatically, even if it could be merged you don't have the permission to do so.
+ .automerge_widget.can_be_merged.hide
+ %strong This can be merged automatically but you don't have the permission to do so.
- if @show_merge_controls
diff --git a/app/views/projects/merge_requests/show/_mr_box.html.haml b/app/views/projects/merge_requests/show/_mr_box.html.haml
index 38db4363ade..abdcd127a0c 100644
--- a/app/views/projects/merge_requests/show/_mr_box.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_box.html.haml
@@ -29,13 +29,13 @@
%span
%i.icon-remove
Closed by #{link_to_member(@project, @merge_request.closed_event.author)}
- #{time_ago_with_tooltip(@merge_request.closed_event.created_at)}.
+ #{time_ago_with_tooltip(@merge_request.closed_event.created_at)}
- if @merge_request.merged?
.alert.alert-info
%span
%i.icon-ok
Merged by #{link_to_member(@project, @merge_request.merge_event.author)}
- #{time_ago_with_tooltip(@merge_request.merge_event.created_at)}.
+ #{time_ago_with_tooltip(@merge_request.merge_event.created_at)}
- if !@closes_issues.empty? && @merge_request.open?
.alert.alert-info.alert-info
%span
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index 217e36e38d0..81bf0611ec6 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -23,7 +23,7 @@
%i.icon-thumbs-up
\+1
- if note.downvote?
- %span.vote.downvote.label.label-error
+ %span.vote.downvote.label.label-danger
%i.icon-thumbs-down
\-1
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index 8a1e1d3354b..20879d69091 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -9,8 +9,8 @@
.col-md-3.project-side.hidden-sm
.clearfix
- if @project.archived?
- .alert
- %h5
+ .alert.alert-warning
+ %h4
%i.icon-warning-sign
Archived project!
%p Repository is read-only
diff --git a/config/application.rb b/config/application.rb
index 4d7c1415c8e..a782dd1d01e 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -19,7 +19,7 @@ module Gitlab
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
# Activate observers that should always be running.
- config.active_record.observers = :activity_observer,
+ config.active_record.observers = :milestone_observer,
:project_activity_cache_observer,
:issue_observer,
:key_observer,
diff --git a/config/environments/production.rb b/config/environments/production.rb
index 9ac4622abc2..ad3c03d8fc9 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -33,6 +33,12 @@ Gitlab::Application.configure do
# See everything in the log (default is :info)
# config.log_level = :debug
+ # Suppress 'Rendered template ...' messages in the log
+ # source: http://stackoverflow.com/a/16369363
+ %w{render_template render_partial render_collection}.each do |event|
+ ActiveSupport::Notifications.unsubscribe "#{event}.action_view"
+ end
+
# Prepend all log lines with the following tags
# config.log_tags = [ :subdomain, :uuid ]
diff --git a/config/initializers/gemoji.rb b/config/initializers/gemoji.rb
deleted file mode 100644
index 6cc33aced77..00000000000
--- a/config/initializers/gemoji.rb
+++ /dev/null
@@ -1,3 +0,0 @@
-# Workaround for https://github.com/github/gemoji/pull/18
-require 'gemoji'
-Gitlab::Application.config.assets.paths << Emoji.images_path
diff --git a/config/routes.rb b/config/routes.rb
index 628d1f631bc..709b66d3e06 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -167,7 +167,7 @@ Gitlab::Application.routes.draw do
resources :projects, constraints: { id: /[^\/]+/ }, only: [:new, :create]
- devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations }
+ devise_for :users, controllers: { omniauth_callbacks: :omniauth_callbacks, registrations: :registrations , passwords: :passwords}
#
# Project Area
diff --git a/config/unicorn_development.rb b/config/unicorn_development.rb
new file mode 100644
index 00000000000..94a7061451d
--- /dev/null
+++ b/config/unicorn_development.rb
@@ -0,0 +1,2 @@
+worker_processes 2
+timeout 30
diff --git a/db/fixtures/development/11_keys.rb b/db/fixtures/development/11_keys.rb
index 42171393d1b..61329f197c3 100644
--- a/db/fixtures/development/11_keys.rb
+++ b/db/fixtures/development/11_keys.rb
@@ -2,7 +2,7 @@ Gitlab::Seeder.quiet do
User.first(30).each_with_index do |user, i|
Key.seed(:id, [
{
- id: i,
+ id: i + 1,
title: "Sample key #{i}",
key: "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt#{i + 100}6k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=",
user_id: user.id,
diff --git a/doc/README.md b/doc/README.md
new file mode 100644
index 00000000000..865806f297a
--- /dev/null
+++ b/doc/README.md
@@ -0,0 +1,17 @@
+## The GitLab Documentation covers the following subjects
+
++ [API](api/README.md)
++ [Development](development/README.md)
++ [Install](install/README.md)
++ [Integration](external-issue-tracker/README.md)
++ [Legal](legal/README.md)
++ [Markdown](markdown/markdown.md)
++ [Permissions](permissions/permissions.md)
++ [Public access](public_access/public_access.md)
++ [Raketasks](raketasks/README.md)
++ [Release](release/README.md)
++ [Security](security/README.md)
++ [System hooks](system_hooks/system_hooks.md)
++ [Update](update/README.md)
++ [Web hooks](web_hooks/web_hooks.md)
++ [Workflow](workflow/workflow.md)
diff --git a/doc/api/README.md b/doc/api/README.md
index 850666953a3..fa5b12af14c 100644
--- a/doc/api/README.md
+++ b/doc/api/README.md
@@ -1,5 +1,31 @@
# GitLab API
+## End-points
+
++ [Users](users.md)
++ [Session](session.md)
++ [Projects](projects.md)
++ [Project Snippets](project_snippets.md)
++ [Repositories](repositories.md)
++ [Repository Files](repository_files.md)
++ [Commits](commits.md)
++ [Merge Requests](merge_requests.md)
++ [Issues](issues.md)
++ [Milestones](milestones.md)
++ [Notes](notes.md)
++ [Deploy Keys](deploy_keys.md)
++ [System Hooks](system_hooks.md)
++ [Groups](groups.md)
+
+## Clients
+
++ [php-gitlab-api](https://github.com/m4tthumphrey/php-gitlab-api) - PHP
++ [Ruby Wrapper](https://github.com/NARKOZ/gitlab) - Ruby
++ [python-gitlab](https://github.com/Itxaka/python-gitlab) - Python
++ [java-gitlab-api](https://github.com/timols/java-gitlab-api) - Java
+
+## Introduction
+
All API requests require authentication. You need to pass a `private_token` parameter by url or header. If passed as header, the header name must be "PRIVATE-TOKEN" (capital and with dash instead of underscore). You can find or reset your private token in your profile.
If no, or an invalid, `private_token` is provided then an error message will be returned with status code 401:
@@ -117,30 +143,3 @@ Issue
So if you want to get issue with api you use `http://host/api/v3/.../issues/:id.json`
But when you want to create a link to web page - use `http:://host/project/issues/:iid.json`
-
-
-
-## Contents
-
-+ [Users](users.md)
-+ [Session](session.md)
-+ [Projects](projects.md)
-+ [Project Snippets](project_snippets.md)
-+ [Repositories](repositories.md)
-+ [Repository Files](repository_files.md)
-+ [Commits](commits.md)
-+ [Merge Requests](merge_requests.md)
-+ [Issues](issues.md)
-+ [Milestones](milestones.md)
-+ [Notes](notes.md)
-+ [Deploy Keys](deploy_keys.md)
-+ [System Hooks](system_hooks.md)
-+ [Groups](groups.md)
-
-
-## Clients
-
-+ [php-gitlab-api](https://github.com/m4tthumphrey/php-gitlab-api) - PHP
-+ [Ruby Wrapper](https://github.com/NARKOZ/gitlab) - Ruby
-+ [python-gitlab](https://github.com/Itxaka/python-gitlab) - Python
-+ [java-gitlab-api](https://github.com/timols/java-gitlab-api) - Java
diff --git a/doc/api/merge_requests.md b/doc/api/merge_requests.md
index 2ddaea5a584..3ce0fb84917 100644
--- a/doc/api/merge_requests.md
+++ b/doc/api/merge_requests.md
@@ -150,6 +150,7 @@ Parameters:
+ `target_branch` - The target branch
+ `assignee_id` - Assignee user ID
+ `title` - Title of MR
++ `state_event` - New state (close|reopen|merge)
```json
@@ -210,3 +211,44 @@ Parameters:
"note":"text1"
}
```
+
+
+## Get the comments on a MR
+
+Gets all the comments associated with a merge request.
+
+```
+GET /projects/:id/merge_request/:merge_request_id/comments
+```
+
+Parameters:
+
++ `id` (required) - The ID of a project
++ `merge_request_id` (required) - ID of merge request
+
+```json
+[
+ {
+ "note":"this is the 1st comment on the 2merge merge request",
+ "author":{
+ "id":11,
+ "username":"admin",
+ "email":"admin@local.host",
+ "name":"Administrator",
+ "state":"active",
+ "created_at":"2014-03-06T08:17:35.000Z"
+ }
+ },
+ {
+ "note":"_Status changed to closed_",
+ "author":{
+ "id":11,
+ "username":"admin",
+ "email":"admin@local.host",
+ "name":"Administrator",
+ "state":"active",
+ "created_at":"2014-03-06T08:17:35.000Z"
+ }
+ }
+]
+```
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 6e82ddd9903..54618d7c045 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -621,3 +621,29 @@ Parameters:
+ query (required) - A string contained in the project name
+ per_page (optional) - number of projects to return per page
+ page (optional) - the page to retrieve
+
+
+## Labels
+
+### List project labels
+
+Get a list of project labels.
+
+```
+GET /projects/:id/labels
+```
+
+Parameters:
+
++ `id` (required) - The ID or NAMESPACE/PROJECT_NAME of a project
+
+```json
+[
+ {
+ "name":"featute"
+ },
+ {
+ "name": "bug"
+ }
+]
+```
diff --git a/doc/api/system_hooks.md b/doc/api/system_hooks.md
index 355ce31c126..2e87ada1d70 100644
--- a/doc/api/system_hooks.md
+++ b/doc/api/system_hooks.md
@@ -1,70 +1,70 @@
-All methods require admin authorization.
-
-The url endpoint of the system hooks can be configured in [the admin area under hooks](/admin/hooks).
-
-## List system hooks
-
-Get list of system hooks
-
-```
-GET /hooks
-```
-
-Parameters:
-
-+ **none**
-
-```json
-[
- {
- "id":3,
- "url":"http://example.com/hook",
- "created_at":"2013-10-02T10:15:31Z"
- }
-]
-```
-
-## Add new system hook hook
-
-```
-POST /hooks
-```
-
-Parameters:
-
-+ `url` (required) - The hook URL
-
-
-## Test system hook
-
-```
-GET /hooks/:id
-```
-
-Parameters:
-
-+ `id` (required) - The ID of hook
-
-```json
-{
- "event_name":"project_create",
- "name":"Ruby",
- "path":"ruby",
- "project_id":1,
- "owner_name":"Someone",
- "owner_email":"example@gitlabhq.com"
-}
-```
-
-## Delete system hook
-
-Deletes a system hook. This is an idempotent API function and returns `200 Ok` even if the hook
-is not available. If the hook is deleted it is also returned as JSON.
-
-```
-DELETE /hooks/:id
-```
-
-Parameters:
-
-+ `id` (required) - The ID of hook
+All methods require admin authorization.
+
+The url endpoint of the system hooks can be configured in [the admin area under hooks](/admin/hooks).
+
+## List system hooks
+
+Get list of system hooks
+
+```
+GET /hooks
+```
+
+Parameters:
+
++ **none**
+
+```json
+[
+ {
+ "id":3,
+ "url":"http://example.com/hook",
+ "created_at":"2013-10-02T10:15:31Z"
+ }
+]
+```
+
+## Add new system hook hook
+
+```
+POST /hooks
+```
+
+Parameters:
+
++ `url` (required) - The hook URL
+
+
+## Test system hook
+
+```
+GET /hooks/:id
+```
+
+Parameters:
+
++ `id` (required) - The ID of hook
+
+```json
+{
+ "event_name":"project_create",
+ "name":"Ruby",
+ "path":"ruby",
+ "project_id":1,
+ "owner_name":"Someone",
+ "owner_email":"example@gitlabhq.com"
+}
+```
+
+## Delete system hook
+
+Deletes a system hook. This is an idempotent API function and returns `200 Ok` even if the hook
+is not available. If the hook is deleted it is also returned as JSON.
+
+```
+DELETE /hooks/:id
+```
+
+Parameters:
+
++ `id` (required) - The ID of hook
diff --git a/doc/development/README.md b/doc/development/README.md
new file mode 100644
index 00000000000..aa59eb2c3e1
--- /dev/null
+++ b/doc/development/README.md
@@ -0,0 +1,2 @@
++ [Architecture](architecture.md)
++ [Shell commands](shell_commands.md)
diff --git a/doc/development/architecture.md b/doc/development/architecture.md
index ab74af4faf9..6f832614d70 100644
--- a/doc/development/architecture.md
+++ b/doc/development/architecture.md
@@ -18,7 +18,7 @@ New releases are generally around the same time as GitLab CE releases with excep
# System Layout
-When referring to ~git in the picures it means the home directory of the git user which is typically /home/git.
+When referring to ~git in the pictures it means the home directory of the git user which is typically /home/git.
GitLab is primarily installed within the `/home/git` user home directory as `git` user.
Within the home directory is where the gitlabhq server software resides as well as the repositories (though the repository location is configurable).
@@ -28,7 +28,7 @@ To serve repositories over SSH there's an add-on application called gitlab-shell
## Components
-![GitLab Diagram Overview](resources/gitlab_diagram_overview.png "GitLab Diagram Overview")
+![GitLab Diagram Overview](resources/gitlab_diagram_overview.png)
A typical install of GitLab will be on Ubuntu Linux or RHEL/CentOS.
It uses Nginx or Apache as a web front end to proxypass the Unicorn web server.
@@ -180,4 +180,4 @@ bundle exec rake gitlab:check RAILS_ENV=production
```
Note: It is recommended to log into the `git` user using `sudo -i -u git` or `sudo su - git`.
-While the sudo commands provided by gitlabhq work in Ubuntu they do not always work in RHEL.
+While the sudo commands provided by gitlabhq work in Ubuntu they do not always work in RHEL. \ No newline at end of file
diff --git a/doc/development/shell_commands.md b/doc/development/shell_commands.md
index 57b1172d5e6..af0d5ca4426 100644
--- a/doc/development/shell_commands.md
+++ b/doc/development/shell_commands.md
@@ -1,5 +1,11 @@
# Guidelines for shell commands in the GitLab codebase
+## References
+
+- [Google Ruby Security Reviewer's Guide](https://code.google.com/p/ruby-security/wiki/Guide)
+- [OWASP Command Injection](https://www.owasp.org/index.php/Command_Injection)
+- [Ruby on Rails Security Guide Command Line Injection](http://guides.rubyonrails.org/security.html#command-line-injection)
+
## Use File and FileUtils instead of shell commands
Sometimes we invoke basic Unix commands via the shell when there is also a Ruby API for doing it.
diff --git a/doc/install/README.md b/doc/install/README.md
new file mode 100644
index 00000000000..ec80e3cd62a
--- /dev/null
+++ b/doc/install/README.md
@@ -0,0 +1,4 @@
++ [Installation](installation.md)
++ [Requirements](requirements.md)
++ [Structure](structure.md)
++ [Database MySQL](database_mysql.md)
diff --git a/doc/install/database_mysql.md b/doc/install/database_mysql.md
index 4cf9b94c1a0..bf8183729e7 100644
--- a/doc/install/database_mysql.md
+++ b/doc/install/database_mysql.md
@@ -6,6 +6,9 @@ We do not recommend using MySQL due to various issues. For example, case [(in)se
# Install the database packages
sudo apt-get install -y mysql-server mysql-client libmysqlclient-dev
+
+ # Ensure you have MySQL version 5.5.14 or later
+ mysql --version
# Pick a database root password (can be anything), type it and press enter
# Retype the database root password and press enter
@@ -23,6 +26,10 @@ We do not recommend using MySQL due to various issues. For example, case [(in)se
# change $password in the command below to a real password you pick
mysql> CREATE USER 'git'@'localhost' IDENTIFIED BY '$password';
+ # Ensure you can use the InnoDB engine which is necessary to support long indexes.
+ # If this fails, check your MySQL config files (e.g. `/etc/mysql/*.cnf`, `/etc/mysql/conf.d/*`) for the setting "innodb = off"
+ mysql> SET storage_engine=INNODB;
+
# Create the GitLab production database
mysql> CREATE DATABASE IF NOT EXISTS `gitlabhq_production` DEFAULT CHARACTER SET `utf8` COLLATE `utf8_unicode_ci`;
diff --git a/doc/install/installation.md b/doc/install/installation.md
index a0eac76ab5b..addb21b50e0 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -128,7 +128,7 @@ GitLab Shell is an ssh access and repository management software developed speci
cd /home/git
# Clone gitlab shell
- sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-shell.git -b v1.8.0
+ sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-shell.git -b v1.9.1
cd gitlab-shell
@@ -173,7 +173,7 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
## Clone the Source
# Clone GitLab repository
- sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 6-6-stable gitlab
+ sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 6-7-stable gitlab
# Go to gitlab dir
cd /home/git/gitlab
diff --git a/doc/integration/external-issue-tracker.md b/doc/integration/external-issue-tracker.md
index 02eadfd410a..3212ebd64b5 100644
--- a/doc/integration/external-issue-tracker.md
+++ b/doc/integration/external-issue-tracker.md
@@ -5,3 +5,5 @@ GitLab has a great issue tracker but you can also use an external issue tracker
- textual references to PROJECT-1234 in comments, commit messages get turned into HTML links to the corresponding JIRA issue.
![jira screenshot](jira-intergration-points.png)
+
+You can configure the integration in the gitlab.yml configuration file.
diff --git a/doc/legal/README.md b/doc/legal/README.md
new file mode 100644
index 00000000000..ebfdad13540
--- /dev/null
+++ b/doc/legal/README.md
@@ -0,0 +1,2 @@
++ [Corporate contributor license agreement](corporate_contributor_license_agreement.md)
++ [Individual contributor license agreement](individual_contributor_license_agreement.md)
diff --git a/doc/permissions/permissions.md b/doc/permissions/permissions.md
index 73e1728a559..ac4bdefddd5 100644
--- a/doc/permissions/permissions.md
+++ b/doc/permissions/permissions.md
@@ -38,7 +38,7 @@ If a user is a GitLab administrator they receive all permissions.
|------|-----|--------|---------|------|-----|
|Browse group|✓|✓|✓|✓|✓|
|Edit group|||||✓|
-|create project in group|||||✓|
+|Create project in group|||||✓|
|Manage group members|||||✓|
|Remove group|||||✓|
diff --git a/doc/raketasks/README.md b/doc/raketasks/README.md
new file mode 100644
index 00000000000..9aa80af12cc
--- /dev/null
+++ b/doc/raketasks/README.md
@@ -0,0 +1,6 @@
++ [Backup restore](backup_restore.md)
++ [Cleanup](cleanup.md)
++ [Features](features.md)
++ [Maintenance](maintenance.md)
++ [User management](user_management.md)
++ [Web hooks](web_hooks.md)
diff --git a/doc/release/README.md b/doc/release/README.md
new file mode 100644
index 00000000000..22510be3f18
--- /dev/null
+++ b/doc/release/README.md
@@ -0,0 +1,2 @@
++ [Monthly](monthly.md)
++ [Security](security.md)
diff --git a/doc/release/monthly.md b/doc/release/monthly.md
index 28fc260b334..08149b4da86 100644
--- a/doc/release/monthly.md
+++ b/doc/release/monthly.md
@@ -58,19 +58,17 @@ Check if changed since last release (~22nd of last month depending on when last
After making the release branch new commits are cherry-picked from master. When the release gets closer we get more selective what is cherry-picked. The days of the month are approximately as follows:
-* 17th: feature freeze (stop merging new features in master)
-* 18th: UI freeze (stop merging changes to the user interface)
-* 19th: code freeze (stop merging non-essential code improvements)
-* 20th: release candidate 1 (VERSION x.x.0.rc1, tag and tweet about x.x.0.rc1)
-* 21st: optional release candidate 2 (x.x.0.rc2, only if rc1 had problems)
+* 1-7th: official merge window (see contributing guide)
+* 8-14th: work on bugfixes, sponsored features and GitLab EE
+* 15th: code freeze (stop merging into master except essential bugfixes)
+* 18th: release candidate 1 (VERSION x.x.0.rc1, tag and tweet about x.x.0.rc1, release on GitLab Cloud)
+* 20st: optional release candidate 2 (x.x.0.rc2, only if rc1 had problems)
* 22nd: release (VERSION x.x.0, create x-x-stable branch, tag, blog and tweet)
* 23nd: optional patch releases (x.x.1, x.x.2, etc., only if there are serious problems)
-* 24-end of month: release Enterprise Edition and upgrade GitLab Cloud
-* 1-7th: official merge window (see contributing guide)
-* 8-16th: bugfixes and sponsored features
+* 24-end of month: release GitLab EE and GitLab CI
# Write a blog post
* Mention what GitLab is on the second line: GitLab is open source software to collaborate on code.
* Select and thank the the Most Valuable Person (MVP) of this release.
-* Add a note if there are security fixes: This release fixes an important security issue and we advise everyone to upgrade as soon as possible. \ No newline at end of file
+* Add a note if there are security fixes: This release fixes an important security issue and we advise everyone to upgrade as soon as possible.
diff --git a/doc/security/README.md b/doc/security/README.md
new file mode 100644
index 00000000000..f8dd1291b9b
--- /dev/null
+++ b/doc/security/README.md
@@ -0,0 +1,2 @@
++ [Password length limits](password_length_limits.md)
++ [Rack attack](rack_attack.md)
diff --git a/doc/ssh/deploy_keys.md b/doc/ssh/deploy_keys.md
new file mode 100644
index 00000000000..56fe98bb101
--- /dev/null
+++ b/doc/ssh/deploy_keys.md
@@ -0,0 +1,12 @@
+Deploy keys allow read-only access one or multiple projects with a single SSH key.
+
+This is really useful for cloning repositories to your Continuous Integration (CI) server.
+By using a deploy keys you don't have to setup a dummy user account.
+
+If you are a project master or owner you can add a deploy key in the project settings under the section Deploy Keys.
+Press the 'New Deploy Key' button and upload a public ssh key.
+After this the machine that uses the corresponding private key has read-only access to the project.
+
+You can't add the same deploy key twice with the 'New Deploy Key' option.
+If you want to add the same key to another project please enable it in the list that says 'Deploy keys from projects available to you'.
+You need to be the owner of the deploy key to see it in this list.
diff --git a/doc/update/4.2-to-5.0.md b/doc/update/4.2-to-5.0.md
index 5bf8c367734..f8fb607e016 100644
--- a/doc/update/4.2-to-5.0.md
+++ b/doc/update/4.2-to-5.0.md
@@ -1,7 +1,7 @@
# From 4.2 to 5.0
## Warning
-GitLab 5.0 is affected by critical security vulnerability CVE-2013-4490. Please update to GitLab 5.4 immediately.
+GitLab 5.0 is affected by critical security vulnerability CVE-2013-4490.
## Important changes
diff --git a/doc/update/5.0-to-5.1.md b/doc/update/5.0-to-5.1.md
index 24d96e43bad..ba56507dd81 100644
--- a/doc/update/5.0-to-5.1.md
+++ b/doc/update/5.0-to-5.1.md
@@ -1,7 +1,7 @@
# From 5.0 to 5.1
## Warning
-GitLab 5.1 is affected by critical security vulnerability CVE-2013-4490. Please [update to GitLab 5.4 immediately](5.1-to-5.4.md).
+GitLab 5.1 is affected by critical security vulnerability CVE-2013-4490.
## Release notes:
diff --git a/doc/update/5.1-to-5.2.md b/doc/update/5.1-to-5.2.md
index e4eaee91b8e..466c815195f 100644
--- a/doc/update/5.1-to-5.2.md
+++ b/doc/update/5.1-to-5.2.md
@@ -1,7 +1,7 @@
# From 5.1 to 5.2
## Warning
-GitLab 5.2 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. Please [update to GitLab 5.4 directly](5.1-to-5.4.md).
+GitLab 5.2 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489.
### 0. Backup
diff --git a/doc/update/5.1-to-5.4.md b/doc/update/5.1-to-5.4.md
index 39cacd381a3..56f4854daf0 100644
--- a/doc/update/5.1-to-5.4.md
+++ b/doc/update/5.1-to-5.4.md
@@ -1,9 +1,6 @@
# From 5.1 to 5.4
Also works starting from 5.2.
-## Notice
-Security vulnerabilities CVE-2013-4490 and CVE-2013-4489 have been patched in the latest version of GitLab 5.4.
-
### 0. Backup
It's useful to make a backup just in case things go south:
diff --git a/doc/update/5.1-to-6.0.md b/doc/update/5.1-to-6.0.md
index fa0f9ce54b6..5b74b1f893d 100644
--- a/doc/update/5.1-to-6.0.md
+++ b/doc/update/5.1-to-6.0.md
@@ -1,7 +1,7 @@
# From 5.1 to 6.0
## Warning
-GitLab 6.0 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. Please [update to GitLab 6.2 immediately](6.0-to-6.2.md).
+GitLab 6.0 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489.
### Deprecations
diff --git a/doc/update/5.2-to-5.3.md b/doc/update/5.2-to-5.3.md
index 7f89f6bf887..e3c3016db64 100644
--- a/doc/update/5.2-to-5.3.md
+++ b/doc/update/5.2-to-5.3.md
@@ -1,7 +1,7 @@
# From 5.2 to 5.3
## Warning
-GitLab 5.3 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. Please [update to GitLab 5.4 directly](5.1-to-5.4.md).
+GitLab 5.3 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489.
### 0. Backup
diff --git a/doc/update/5.3-to-5.4.md b/doc/update/5.3-to-5.4.md
index 7a24c11c223..213ce77ec38 100644
--- a/doc/update/5.3-to-5.4.md
+++ b/doc/update/5.3-to-5.4.md
@@ -1,8 +1,5 @@
# From 5.3 to 5.4
-## Notice
-Security vulnerabilities CVE-2013-4490 and CVE-2013-4489 have been patched in the latest version of GitLab 5.4.
-
### 0. Backup
It's useful to make a backup just in case things go south:
diff --git a/doc/update/5.4-to-6.0.md b/doc/update/5.4-to-6.0.md
index 312e9a46080..c289fcb57fd 100644
--- a/doc/update/5.4-to-6.0.md
+++ b/doc/update/5.4-to-6.0.md
@@ -1,7 +1,7 @@
# From 5.4 to 6.0
## Warning
-GitLab 6.0 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. Please [update to GitLab 6.2 immediately](6.0-to-6.2.md).
+GitLab 6.0 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489.
### Deprecations
diff --git a/doc/update/6.0-to-6.1.md b/doc/update/6.0-to-6.1.md
index b7fd7634859..b4cc9203587 100644
--- a/doc/update/6.0-to-6.1.md
+++ b/doc/update/6.0-to-6.1.md
@@ -1,7 +1,7 @@
# From 6.0 to 6.1
## Warning
-GitLab 6.1 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489. Please [update to GitLab 6.2 directly](6.0-to-6.2.md).
+GitLab 6.1 is affected by critical security vulnerabilities CVE-2013-4490 and CVE-2013-4489.
# In 6.1 we remove a lot of deprecated code.
# You should update to 6.0 before installing 6.1 so all the necessary conversions are run.
diff --git a/doc/update/6.0-to-6.5.md b/doc/update/6.0-to-6.7.md
index 4a23fbfdd94..5023e34f189 100644
--- a/doc/update/6.0-to-6.5.md
+++ b/doc/update/6.0-to-6.7.md
@@ -1,4 +1,4 @@
-# From 6.0 to 6.5
+# From 6.0 to 6.7
# In 6.1 we remove a lot of deprecated code.
# You should update to 6.0 before installing 6.1 or higher so all the necessary conversions are run.
@@ -28,8 +28,20 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
```bash
cd /home/git/gitlab
sudo -u git -H git fetch --all
-sudo -u git -H git checkout 6-5-stable
-# For GitLab Enterprise Edition: sudo -u git -H git checkout 6-5-stable-ee
+```
+
+For Gitlab Community Edition:
+
+```bash
+sudo -u git -H git checkout 6-7-stable
+```
+
+OR
+
+For GitLab Enterprise Edition:
+
+```bash
+sudo -u git -H git checkout 6-7-stable-ee
```
@@ -45,7 +57,7 @@ sudo apt-get install logrotate
```bash
cd /home/git/gitlab-shell
sudo -u git -H git fetch
-sudo -u git -H git checkout v1.8.0 # Addresses multiple critical security vulnerabilities
+sudo -u git -H git checkout v1.9.1 # Addresses multiple critical security vulnerabilities
```
### 5. Install libs, migrations, etc.
@@ -60,11 +72,14 @@ sudo -u git -H bundle install --without development test postgres --deployment
sudo -u git -H bundle install --without development test mysql --deployment
+# Run database migrations
sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
+
+# Enable internal issue IDs (introduced in GitLab 6.1)
sudo -u git -H bundle exec rake migrate_iids RAILS_ENV=production
-sudo -u git -H bundle exec rake assets:clean RAILS_ENV=production
-sudo -u git -H bundle exec rake assets:precompile RAILS_ENV=production
-sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production
+
+# Clean up assets and cache
+sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production
```
### 6. Update config files
@@ -72,11 +87,11 @@ sudo -u git -H bundle exec rake cache:clear RAILS_ENV=production
TIP: to see what changed in gitlab.yml.example in this release use next command:
```
-git diff 6-0-stable:config/gitlab.yml.example 6-5-stable:config/gitlab.yml.example
+git diff 6-0-stable:config/gitlab.yml.example 6-7-stable:config/gitlab.yml.example
```
-* Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-5-stable/config/gitlab.yml.example but with your settings.
-* Make `/home/git/gitlab/config/unicorn.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-5-stable/config/unicorn.rb.example but with your settings.
+* Make `/home/git/gitlab/config/gitlab.yml` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-7-stable/config/gitlab.yml.example but with your settings.
+* Make `/home/git/gitlab/config/unicorn.rb` same as https://gitlab.com/gitlab-org/gitlab-ce/blob/6-7-stable/config/unicorn.rb.example but with your settings.
* Copy rack attack middleware config
```bash
diff --git a/doc/update/6.1-to-6.2.md b/doc/update/6.1-to-6.2.md
index 3c453a5ab42..c618e599dcb 100644
--- a/doc/update/6.1-to-6.2.md
+++ b/doc/update/6.1-to-6.2.md
@@ -1,8 +1,5 @@
# From 6.1 to 6.2
-## Notice
-Security vulnerabilities CVE-2013-4490 and CVE-2013-4489 have been patched in the latest version of GitLab 6.2.
-
# You should update to 6.1 before installing 6.2 so all the necessary conversions are run.
### 0. Backup
diff --git a/doc/update/6.6-to-6.7.md b/doc/update/6.6-to-6.7.md
index e4a0cafa911..8a16e5d67be 100644
--- a/doc/update/6.6-to-6.7.md
+++ b/doc/update/6.6-to-6.7.md
@@ -37,7 +37,7 @@ sudo -u git -H git checkout 6-7-stable-ee
```bash
cd /home/git/gitlab-shell
sudo -u git -H git fetch
-sudo -u git -H git checkout v1.8.0
+sudo -u git -H git checkout v1.9.1
```
### 4. Install libs, migrations, etc.
diff --git a/doc/update/README.md b/doc/update/README.md
new file mode 100644
index 00000000000..97afd71bbe3
--- /dev/null
+++ b/doc/update/README.md
@@ -0,0 +1,5 @@
++ [The indivual upgrade guides](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/update)
++ [Uprader](upgrader.md)
++ [Ruby](ruby.md)
++ [Patch versions](patch_versions.md)
++ [MySQL to Postgress](mysql_to_postgress.md)
diff --git a/doc/web_hooks/web_hooks.md b/doc/web_hooks/web_hooks.md
index 64cce45945e..f80891e264d 100644
--- a/doc/web_hooks/web_hooks.md
+++ b/doc/web_hooks/web_hooks.md
@@ -5,6 +5,7 @@ Project web hooks allow you to trigger an URL if new code is pushed or a new iss
You can configure web hook to listen for specific events like pushes, issues, merge requests.
GitLab will send POST request with data to web hook URL.
Web Hooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server.
+If you send a web hook to an SSL endpoint [the certificate will not be verified](https://gitlab.com/gitlab-org/gitlab-ce/blob/ccd617e58ea71c42b6b073e692447d0fe3c00be6/app/models/web_hook.rb#L35) since many people use self-signed certificates.
---
diff --git a/features/project/service.feature b/features/project/service.feature
index 46b983e8f9a..a5af065c9e7 100644
--- a/features/project/service.feature
+++ b/features/project/service.feature
@@ -37,6 +37,12 @@ Feature: Project Services
And I fill Assembla settings
Then I should see Assembla service settings saved
+ Scenario: Activate Slack service
+ When I visit project "Shop" services page
+ And I click Slack service link
+ And I fill Slack settings
+ Then I should see Slack service settings saved
+
Scenario: Activate email on push service
When I visit project "Shop" services page
And I click email on push service link
diff --git a/features/steps/dashboard/dashboard.rb b/features/steps/dashboard/dashboard.rb
index 3526006c94a..394acd3fe8f 100644
--- a/features/steps/dashboard/dashboard.rb
+++ b/features/steps/dashboard/dashboard.rb
@@ -25,7 +25,7 @@ class Dashboard < Spinach::FeatureSteps
find("#merge_request_target_project_id").value.should == @project.id.to_s
find("#merge_request_source_branch").value.should == "new_design"
find("#merge_request_target_branch").value.should == "master"
- find("#merge_request_title").value.should == "New Design"
+ find("#merge_request_title").value.should == "New design"
end
Given 'user with name "John Doe" joined project "Shop"' do
diff --git a/features/steps/project/redirects.rb b/features/steps/project/redirects.rb
index 76ffea1bb6f..cfa4ce82be3 100644
--- a/features/steps/project/redirects.rb
+++ b/features/steps/project/redirects.rb
@@ -4,7 +4,7 @@ class Spinach::Features::ProjectRedirects < Spinach::FeatureSteps
include SharedProject
step 'public project "Community"' do
- create :project, name: 'Community', visibility_level: Gitlab::VisibilityLevel::PUBLIC
+ create :project, :public, name: 'Community'
end
step 'private project "Enterprise"' do
diff --git a/features/steps/project/services.rb b/features/steps/project/services.rb
index 54b3f18e084..0594a08a5e7 100644
--- a/features/steps/project/services.rb
+++ b/features/steps/project/services.rb
@@ -100,4 +100,22 @@ class ProjectServices < Spinach::FeatureSteps
step 'I should see email on push service settings saved' do
find_field('Recipients').value.should == 'qa@company.name'
end
+
+ step 'I click Slack service link' do
+ click_link 'Slack'
+ end
+
+ step 'I fill Slack settings' do
+ check 'Active'
+ fill_in 'Subdomain', with: 'gitlab'
+ fill_in 'Room', with: '#gitlab'
+ fill_in 'Token', with: 'verySecret'
+ click_button 'Save'
+ end
+
+ step 'I should see Slack service settings saved' do
+ find_field('Subdomain').value.should == 'gitlab'
+ find_field('Room').value.should == '#gitlab'
+ find_field('Token').value.should == 'verySecret'
+ end
end
diff --git a/features/steps/public/projects.rb b/features/steps/public/projects.rb
index eb1d235f435..7c7311bb91c 100644
--- a/features/steps/public/projects.rb
+++ b/features/steps/public/projects.rb
@@ -4,7 +4,7 @@ class Spinach::Features::PublicProjectsFeature < Spinach::FeatureSteps
include SharedProject
step 'public empty project "Empty Public Project"' do
- create :empty_project, name: 'Empty Public Project', visibility_level: Gitlab::VisibilityLevel::PUBLIC
+ create :empty_project, :public, name: 'Empty Public Project'
end
step 'I should see project "Empty Public Project"' do
diff --git a/features/steps/shared/project.rb b/features/steps/shared/project.rb
index f35beab8af2..f8cb753b78f 100644
--- a/features/steps/shared/project.rb
+++ b/features/steps/shared/project.rb
@@ -79,7 +79,7 @@ module SharedProject
end
step 'internal project "Internal"' do
- create :project, name: 'Internal', visibility_level: Gitlab::VisibilityLevel::INTERNAL
+ create :project, :internal, name: 'Internal'
end
step 'I should see project "Internal"' do
@@ -91,7 +91,7 @@ module SharedProject
end
step 'public project "Community"' do
- create :project, name: 'Community', visibility_level: Gitlab::VisibilityLevel::PUBLIC
+ create :project, :public, name: 'Community'
end
step 'I should see project "Community"' do
@@ -112,14 +112,14 @@ module SharedProject
step '"John Doe" is authorized to internal project "Internal"' do
user = user_exists("John Doe", username: "john_doe")
project = Project.find_by(name: "Internal")
- project ||= create :project, name: 'Internal', visibility_level: Gitlab::VisibilityLevel::INTERNAL
+ project ||= create :project, :internal, name: 'Internal'
project.team << [user, :master]
end
step '"John Doe" is authorized to public project "Community"' do
user = user_exists("John Doe", username: "john_doe")
project = Project.find_by(name: "Community")
- project ||= create :project, name: 'Community', visibility_level: Gitlab::VisibilityLevel::PUBLIC
+ project ||= create :project, :public, name: 'Community'
project.team << [user, :master]
end
end
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index 8b4519af2d1..9fa8506926c 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -187,5 +187,9 @@ module API
end
end
end
+
+ class Label < Grape::Entity
+ expose :name
+ end
end
end
diff --git a/lib/api/internal.rb b/lib/api/internal.rb
index 69aad3748b3..bcf97574673 100644
--- a/lib/api/internal.rb
+++ b/lib/api/internal.rb
@@ -1,16 +1,12 @@
module API
# Internal access API
class Internal < Grape::API
-
- DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive }
- PUSH_COMMANDS = %w{ git-receive-pack }
-
namespace 'internal' do
- #
- # Check if ssh key has access to project code
+ # Check if git command is allowed to project
#
# Params:
- # key_id - SSH Key id
+ # key_id - ssh key id for Git over SSH
+ # user_id - user id for Git over HTTP
# project - project path with namespace
# action - git action (git-upload-pack or git-receive-pack)
# ref - branch name
@@ -22,43 +18,25 @@ module API
# the wiki repository as well.
project_path = params[:project]
project_path.gsub!(/\.wiki/,'') if project_path =~ /\.wiki/
-
- key = Key.find(params[:key_id])
project = Project.find_with_namespace(project_path)
- git_cmd = params[:action]
return false unless project
-
- if key.is_a? DeployKey
- key.projects.include?(project) && DOWNLOAD_COMMANDS.include?(git_cmd)
- else
- user = key.user
-
- return false if user.blocked?
-
- if Gitlab.config.ldap.enabled
- if user.ldap_user?
- # Check if LDAP user exists and match LDAP user_filter
- unless Gitlab::LDAP::Access.new.allowed?(user)
- return false
- end
- end
- end
-
- action = case git_cmd
- when *DOWNLOAD_COMMANDS
- then :download_code
- when *PUSH_COMMANDS
- then
- if project.protected_branch?(params[:ref])
- :push_code_to_protected_branches
- else
- :push_code
- end
- end
-
- user.can?(action, project)
- end
+ actor = if params[:key_id]
+ Key.find(params[:key_id])
+ elsif params[:user_id]
+ User.find(params[:user_id])
+ end
+
+ return false unless actor
+
+ Gitlab::GitAccess.new.allowed?(
+ actor,
+ params[:action],
+ project,
+ params[:ref],
+ params[:oldrev],
+ params[:newrev]
+ )
end
#
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index e2458198411..3a1a00d0719 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -125,6 +125,22 @@ module API
end
end
+ # Get a merge request's comments
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # merge_request_id (required) - ID of MR
+ # Examples:
+ # GET /projects/:id/merge_request/:merge_request_id/comments
+ #
+ get ":id/merge_request/:merge_request_id/comments" do
+ merge_request = user_project.merge_requests.find(params[:merge_request_id])
+
+ authorize! :read_merge_request, merge_request
+
+ present paginate(merge_request.notes), with: Entities::MRNote
+ end
+
# Post comment to merge request
#
# Parameters:
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 4d48d2194f8..9d290c75ba9 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -215,6 +215,17 @@ module API
@users = paginate @users
present @users, with: Entities::User
end
+
+ # Get a project labels
+ #
+ # Parameters:
+ # id (required) - The ID of a project
+ # Example Request:
+ # GET /projects/:id/labels
+ get ':id/labels' do
+ @labels = user_project.issues_labels
+ present @labels, with: Entities::Label
+ end
end
end
end
diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb
index 60c03ce1c04..c2f3b851c07 100644
--- a/lib/gitlab/backend/grack_auth.rb
+++ b/lib/gitlab/backend/grack_auth.rb
@@ -1,11 +1,9 @@
require_relative 'shell_env'
-require_relative 'grack_helpers'
module Grack
class Auth < Rack::Auth::Basic
- include Helpers
- attr_accessor :user, :project, :ref, :env
+ attr_accessor :user, :project, :env
def call(env)
@env = env
@@ -24,14 +22,16 @@ module Grack
@env['SCRIPT_NAME'] = ""
- auth!
+ if project
+ auth!
+ else
+ render_not_found
+ end
end
private
def auth!
- return render_not_found unless project
-
if @auth.provided?
return bad_request unless @auth.basic?
@@ -40,12 +40,8 @@ module Grack
# Allow authentication for GitLab CI service
# if valid token passed
- if login == "gitlab-ci-token" && project.gitlab_ci?
- token = project.gitlab_ci_service.token
-
- if token.present? && token == password && service_name == 'git-upload-pack'
- return @app.call(env)
- end
+ if gitlab_ci_request?(login, password)
+ return @app.call(env)
end
@user = authenticate_user(login, password)
@@ -53,23 +49,26 @@ module Grack
if @user
Gitlab::ShellEnv.set_env(@user)
@env['REMOTE_USER'] = @auth.username
- else
- return unauthorized
end
-
- else
- return unauthorized unless project.public?
end
- if authorized_git_request?
+ if authorized_request?
@app.call(env)
else
unauthorized
end
end
- def authorized_git_request?
- authorize_request(service_name)
+ def gitlab_ci_request?(login, password)
+ if login == "gitlab-ci-token" && project.gitlab_ci?
+ token = project.gitlab_ci_service.token
+
+ if token.present? && token == password && git_cmd == 'git-upload-pack'
+ return true
+ end
+ end
+
+ false
end
def authenticate_user(login, password)
@@ -77,31 +76,31 @@ module Grack
auth.find(login, password)
end
- def authorize_request(service)
- case service
- when 'git-upload-pack'
- can?(user, :download_code, project)
- when'git-receive-pack'
- refs.each do |ref|
- action = if project.protected_branch?(ref)
- :push_code_to_protected_branches
- else
- :push_code
- end
-
- return false unless can?(user, action, project)
+ def authorized_request?
+ case git_cmd
+ when *Gitlab::GitAccess::DOWNLOAD_COMMANDS
+ if user
+ Gitlab::GitAccess.new.download_allowed?(user, project)
+ elsif project.public?
+ # Allow clone/fetch for public projects
+ true
+ else
+ false
+ end
+ when *Gitlab::GitAccess::PUSH_COMMANDS
+ if user
+ # Skip user authorization on upload request.
+ # It will be serverd by update hook in repository
+ true
+ else
+ false
end
-
- # Never let git-receive-pack trough unauthenticated; it's
- # harmless but git < 1.8 doesn't like it
- return false if user.nil?
- true
else
false
end
end
- def service_name
+ def git_cmd
if @request.get?
@request.params['service']
elsif @request.post?
@@ -115,28 +114,17 @@ module Grack
@project ||= project_by_path(@request.path_info)
end
- def refs
- @refs ||= parse_refs
- end
-
- def parse_refs
- input = if @env["HTTP_CONTENT_ENCODING"] =~ /gzip/
- Zlib::GzipReader.new(@request.body).read
- else
- @request.body.read
- end
-
- # Need to reset seek point
- @request.body.rewind
-
- # Parse refs
- refs = input.force_encoding('ascii-8bit').scan(/refs\/heads\/([\/\w\.-]+)/n).flatten.compact
+ def project_by_path(path)
+ if m = /^([\w\.\/-]+)\.git/.match(path).to_a
+ path_with_namespace = m.last
+ path_with_namespace.gsub!(/\.wiki$/, '')
- # Cleanup grabare from refs
- # if push to multiple branches
- refs.map do |ref|
- ref.gsub(/00.*/, "")
+ Project.find_with_namespace(path_with_namespace)
end
end
+
+ def render_not_found
+ [404, {"Content-Type" => "text/plain"}, ["Not Found"]]
+ end
end
end
diff --git a/lib/gitlab/backend/grack_helpers.rb b/lib/gitlab/backend/grack_helpers.rb
deleted file mode 100644
index cb747fe0137..00000000000
--- a/lib/gitlab/backend/grack_helpers.rb
+++ /dev/null
@@ -1,28 +0,0 @@
-module Grack
- module Helpers
- def project_by_path(path)
- if m = /^([\w\.\/-]+)\.git/.match(path).to_a
- path_with_namespace = m.last
- path_with_namespace.gsub!(/\.wiki$/, '')
-
- Project.find_with_namespace(path_with_namespace)
- end
- end
-
- def render_not_found
- [404, {"Content-Type" => "text/plain"}, ["Not Found"]]
- end
-
- def can?(object, action, subject)
- abilities.allowed?(object, action, subject)
- end
-
- def abilities
- @abilities ||= begin
- abilities = Six.new
- abilities << Ability
- abilities
- end
- end
- end
-end
diff --git a/lib/gitlab/git_access.rb b/lib/gitlab/git_access.rb
new file mode 100644
index 00000000000..1ab8f9213a3
--- /dev/null
+++ b/lib/gitlab/git_access.rb
@@ -0,0 +1,74 @@
+module Gitlab
+ class GitAccess
+ DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive }
+ PUSH_COMMANDS = %w{ git-receive-pack }
+
+ attr_reader :params, :project, :git_cmd, :user
+
+ def allowed?(actor, cmd, project, ref = nil, oldrev = nil, newrev = nil)
+ case cmd
+ when *DOWNLOAD_COMMANDS
+ if actor.is_a? User
+ download_allowed?(actor, project)
+ elsif actor.is_a? DeployKey
+ actor.projects.include?(project)
+ elsif actor.is_a? Key
+ download_allowed?(actor.user, project)
+ else
+ raise 'Wrong actor'
+ end
+ when *PUSH_COMMANDS
+ if actor.is_a? User
+ push_allowed?(actor, project, ref, oldrev, newrev)
+ elsif actor.is_a? DeployKey
+ # Deploy key not allowed to push
+ return false
+ elsif actor.is_a? Key
+ push_allowed?(actor.user, project, ref, oldrev, newrev)
+ else
+ raise 'Wrong actor'
+ end
+ else
+ false
+ end
+ end
+
+ def download_allowed?(user, project)
+ if user && user_allowed?(user)
+ user.can?(:download_code, project)
+ else
+ false
+ end
+ end
+
+ def push_allowed?(user, project, ref, oldrev, newrev)
+ if user && user_allowed?(user)
+ action = if project.protected_branch?(ref)
+ :push_code_to_protected_branches
+ else
+ :push_code
+ end
+ user.can?(action, project)
+ else
+ false
+ end
+ end
+
+ private
+
+ def user_allowed?(user)
+ return false if user.blocked?
+
+ if Gitlab.config.ldap.enabled
+ if user.ldap_user?
+ # Check if LDAP user exists and match LDAP user_filter
+ unless Gitlab::LDAP::Access.new.allowed?(user)
+ return false
+ end
+ end
+ end
+
+ true
+ end
+ end
+end
diff --git a/lib/gitlab/markdown.rb b/lib/gitlab/markdown.rb
index e72f4f5d0ce..de14a3eca27 100644
--- a/lib/gitlab/markdown.rb
+++ b/lib/gitlab/markdown.rb
@@ -152,7 +152,7 @@ module Gitlab
#
# Returns boolean
def valid_emoji?(emoji)
- Emoji.names.include? emoji
+ Emoji.find_by_name emoji
end
# Private: Dispatches to a dedicated processing method based on reference
@@ -166,8 +166,8 @@ module Gitlab
end
def reference_user(identifier)
- if member = @project.team_members.find { |user| user.username == identifier }
- link_to("@#{identifier}", user_url(identifier), html_options.merge(class: "gfm gfm-team_member #{html_options[:class]}")) if member
+ if user = User.find_by_username(identifier)
+ link_to("@#{identifier}", user_url(identifier), html_options.merge(class: "gfm gfm-team_member #{html_options[:class]}"))
end
end
diff --git a/lib/gitlab/satellite/satellite.rb b/lib/gitlab/satellite/satellite.rb
index bcf3012bd92..bdfcf254e9e 100644
--- a/lib/gitlab/satellite/satellite.rb
+++ b/lib/gitlab/satellite/satellite.rb
@@ -1,5 +1,9 @@
module Gitlab
- class SatelliteNotExistError < StandardError; end
+ class SatelliteNotExistError < StandardError
+ def initialize(msg = "Satellite doesn't exist")
+ super
+ end
+ end
module Satellite
class Satellite
@@ -17,14 +21,9 @@ module Gitlab
Gitlab::Satellite::Logger.error(message)
end
- def raise_no_satellite
- raise SatelliteNotExistError.new("Satellite doesn't exist")
- end
-
def clear_and_update!
- raise_no_satellite unless exists?
+ raise SatelliteNotExistError unless exists?
- File.exists? path
@repo = nil
clear_working_dir!
delete_heads!
@@ -55,7 +54,7 @@ module Gitlab
# * Changes the current directory to the satellite's working dir
# * Yields
def lock
- raise_no_satellite unless exists?
+ raise SatelliteNotExistError unless exists?
File.open(lock_file, "w+") do |f|
begin
@@ -77,7 +76,7 @@ module Gitlab
end
def repo
- raise_no_satellite unless exists?
+ raise SatelliteNotExistError unless exists?
@repo ||= Grit::Repo.new(path)
end
diff --git a/lib/gitlab/upgrader.rb b/lib/gitlab/upgrader.rb
index 0fe4888665d..0846359f9b1 100644
--- a/lib/gitlab/upgrader.rb
+++ b/lib/gitlab/upgrader.rb
@@ -1,3 +1,4 @@
+require_relative "popen"
require_relative "version_info"
module Gitlab
diff --git a/lib/support/init.d/gitlab b/lib/support/init.d/gitlab
index c6e570784e0..3dd4465a6d8 100755
--- a/lib/support/init.d/gitlab
+++ b/lib/support/init.d/gitlab
@@ -40,7 +40,7 @@ test -f /etc/default/gitlab && . /etc/default/gitlab
# Switch to the app_user if it is not he/she who is running the script.
if [ "$USER" != "$app_user" ]; then
- sudo -u "$app_user" -H -i $0 "$@"; exit;
+ eval su - "$app_user" -c $(echo \")$0 "$@"$(echo \"); exit;
fi
# Switch to the gitlab path, exit on failure.
@@ -131,7 +131,7 @@ check_stale_pids(){
fi
fi
if [ "$spid" != "0" -a "$sidekiq_status" != "0" ]; then
- echo "Removing stale Sidekiq web server pid. This is most likely caused by the Sidekiq crashing the last time it ran."
+ echo "Removing stale Sidekiq job dispatcher pid. This is most likely caused by Sidekiq crashing the last time it ran."
if ! rm "$sidekiq_pid_path"; then
echo "Unable to remove stale pid, exiting"
exit 1
@@ -149,15 +149,15 @@ exit_if_not_running(){
}
## Starts Unicorn and Sidekiq if they're not running.
-start() {
+start_gitlab() {
check_stale_pids
if [ "$web_status" != "0" -a "$sidekiq_status" != "0" ]; then
echo -n "Starting both the GitLab Unicorn and Sidekiq"
elif [ "$web_status" != "0" ]; then
- echo -n "Starting GitLab Sidekiq"
- elif [ "$sidekiq_status" != "0" ]; then
echo -n "Starting GitLab Unicorn"
+ elif [ "$sidekiq_status" != "0" ]; then
+ echo -n "Starting GitLab Sidekiq"
fi
# Then check if the service is running. If it is: don't start again.
@@ -167,7 +167,7 @@ start() {
# Remove old socket if it exists
rm -f "$socket_path"/gitlab.socket 2>/dev/null
# Start the web server
- RAILS_ENV=$RAILS_ENV script/web start &
+ RAILS_ENV=$RAILS_ENV script/web start
fi
# If sidekiq is already running, don't start it again.
@@ -184,15 +184,15 @@ start() {
}
## Asks the Unicorn and the Sidekiq if they would be so kind as to stop, if not kills them.
-stop() {
+stop_gitlab() {
exit_if_not_running
if [ "$web_status" = "0" -a "$sidekiq_status" = "0" ]; then
echo -n "Shutting down both Unicorn and Sidekiq"
elif [ "$web_status" = "0" ]; then
- echo -n "Shutting down Sidekiq"
- elif [ "$sidekiq_status" = "0" ]; then
echo -n "Shutting down Unicorn"
+ elif [ "$sidekiq_status" = "0" ]; then
+ echo -n "Shutting down Sidekiq"
fi
# If the Unicorn web server is running, tell it to stop;
@@ -246,7 +246,7 @@ print_status() {
}
## Tells unicorn to reload it's config and Sidekiq to restart
-reload(){
+reload_gitlab(){
exit_if_not_running
if [ "$wpid" = "0" ];then
echo "The GitLab Unicorn Web server is not running thus its configuration can't be reloaded."
@@ -263,12 +263,12 @@ reload(){
}
## Restarts Sidekiq and Unicorn.
-restart(){
+restart_gitlab(){
check_status
if [ "$web_status" = "0" -o "$sidekiq_status" = "0" ]; then
- stop
+ stop_gitlab
fi
- start
+ start_gitlab
}
@@ -276,16 +276,16 @@ restart(){
case "$1" in
start)
- start
+ start_gitlab
;;
stop)
- stop
+ stop_gitlab
;;
restart)
- restart
+ restart_gitlab
;;
reload|force-reload)
- reload
+ reload_gitlab
;;
status)
print_status
diff --git a/lib/support/nginx/gitlab b/lib/support/nginx/gitlab
index 7a0f3efbb53..5bff362da0e 100644
--- a/lib/support/nginx/gitlab
+++ b/lib/support/nginx/gitlab
@@ -54,6 +54,14 @@ server {
proxy_pass http://gitlab;
}
+ # Enable gzip compression as per rails guide: http://guides.rubyonrails.org/asset_pipeline.html#gzip-compression
+ location ~ ^/(assets)/ {
+ root /home/git/gitlab/public;
+ gzip_static on; # to serve pre-gzipped version
+ expires max;
+ add_header Cache-Control public;
+ }
+
error_page 502 /502.html;
}
diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
index d4d5e48ce3f..3b9b2531bf7 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -677,7 +677,20 @@ namespace :gitlab do
end
def filter
- Net::LDAP::Filter.present?(ldap_config.uid)
+ uid_filter = Net::LDAP::Filter.present?(ldap_config.uid)
+ if user_filter
+ Net::LDAP::Filter.join(uid_filter, user_filter)
+ else
+ uid_filter
+ end
+ end
+
+ def user_filter
+ if ldap_config['user_filter'] && ldap_config.user_filter.present?
+ Net::LDAP::Filter.construct(ldap_config.user_filter)
+ else
+ nil
+ end
end
def ldap
@@ -742,7 +755,7 @@ namespace :gitlab do
end
def check_gitlab_shell
- required_version = Gitlab::VersionInfo.new(1, 8, 5)
+ required_version = Gitlab::VersionInfo.new(1, 9, 1)
current_version = Gitlab::VersionInfo.parse(gitlab_shell_version)
print "GitLab Shell version >= #{required_version} ? ... "
diff --git a/script/background_jobs b/script/background_jobs
index 06125c11ffe..52732f5532b 100755
--- a/script/background_jobs
+++ b/script/background_jobs
@@ -6,6 +6,11 @@ sidekiq_pidfile="$app_root/tmp/pids/sidekiq.pid"
sidekiq_logfile="$app_root/log/sidekiq.log"
gitlab_user=$(ls -l config.ru | awk '{print $3}')
+function warn
+{
+ echo "$@" 1>&2
+}
+
function stop
{
bundle exec sidekiqctl stop $sidekiq_pidfile >> $sidekiq_logfile 2>&1
@@ -35,6 +40,22 @@ function start_sidekiq
bundle exec sidekiq -q post_receive,mailer,system_hook,project_web_hook,gitlab_shell,common,default -e $RAILS_ENV -P $sidekiq_pidfile $@ >> $sidekiq_logfile 2>&1
}
+function load_ok
+{
+ sidekiq_pid=$(cat $sidekiq_pidfile)
+ if [[ -z $sidekiq_pid ]] ; then
+ warn "Could not find a PID in $sidekiq_pidfile"
+ exit 0
+ fi
+
+ if (ps -p $sidekiq_pid -o args | grep '\([0-9]\+\) of \1 busy' 1>&2) ; then
+ warn "Too many busy Sidekiq workers"
+ exit 1
+ fi
+
+ exit 0
+}
+
case "$1" in
stop)
stop
@@ -51,6 +72,9 @@ case "$1" in
killall)
killall
;;
+ load_ok)
+ load_ok
+ ;;
*)
- echo "Usage: RAILS_ENV=your_env $0 {stop|start|start_no_deamonize|restart|killall}"
+ echo "Usage: RAILS_ENV=your_env $0 {stop|start|start_no_deamonize|restart|killall|load_ok}"
esac
diff --git a/spec/controllers/profile_keys_controller_spec.rb b/spec/controllers/profile_keys_controller_spec.rb
index 121012d5d49..593d3e9eb56 100644
--- a/spec/controllers/profile_keys_controller_spec.rb
+++ b/spec/controllers/profile_keys_controller_spec.rb
@@ -24,6 +24,11 @@ describe Profiles::KeysController do
expect(response.body).to eq("")
end
+
+ it "should respond with text/plain content type" do
+ get :get_keys, username: user.username
+ expect(response.content_type).to eq("text/plain")
+ end
end
describe "user with keys" do
@@ -44,6 +49,11 @@ describe Profiles::KeysController do
expect(response.body).not_to eq("")
expect(response.body).to eq(user.all_ssh_keys.join("\n"))
end
+
+ it "should respond with text/plain content type" do
+ get :get_keys, username: user.username
+ expect(response.content_type).to eq("text/plain")
+ end
end
end
end
diff --git a/spec/factories.rb b/spec/factories.rb
index 7fc2b7c5e97..148477d6389 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -32,6 +32,18 @@ FactoryGirl.define do
path { name.downcase.gsub(/\s/, '_') }
namespace
creator
+
+ trait :public do
+ visibility_level Gitlab::VisibilityLevel::PUBLIC
+ end
+
+ trait :internal do
+ visibility_level Gitlab::VisibilityLevel::INTERNAL
+ end
+
+ trait :private do
+ visibility_level Gitlab::VisibilityLevel::PRIVATE
+ end
end
# Generates a test repository from the repository stored under `spec/seed_project.tar.gz`.
@@ -146,6 +158,11 @@ FactoryGirl.define do
state :reopened
end
+ trait :simple do
+ source_branch "simple_merge_request"
+ target_branch "master"
+ end
+
factory :closed_merge_request, traits: [:closed]
factory :reopened_merge_request, traits: [:reopened]
factory :merge_request_with_diffs, traits: [:with_diffs]
@@ -161,7 +178,6 @@ FactoryGirl.define do
factory :note_on_issue, traits: [:on_issue], aliases: [:votable_note]
factory :note_on_merge_request, traits: [:on_merge_request]
factory :note_on_merge_request_diff, traits: [:on_merge_request, :on_diff]
- factory :note_on_merge_request_with_attachment, traits: [:on_merge_request, :with_attachment]
trait :on_commit do
project factory: :project
diff --git a/spec/features/notes_on_merge_requests_spec.rb b/spec/features/notes_on_merge_requests_spec.rb
index a3d8c462bf6..25a86b11fa9 100644
--- a/spec/features/notes_on_merge_requests_spec.rb
+++ b/spec/features/notes_on_merge_requests_spec.rb
@@ -1,14 +1,12 @@
require 'spec_helper'
describe "On a merge request", js: true do
- let!(:project) { create(:project) }
- let!(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
- let!(:note) { create(:note_on_merge_request_with_attachment, project: project) }
+ let!(:merge_request) { create(:merge_request, :simple) }
+ let!(:project) { merge_request.source_project }
+ let!(:note) { create(:note_on_merge_request, :with_attachment, project: project) }
before do
- login_as :user
- project.team << [@user, :master]
-
+ login_as :admin
visit project_merge_request_path(project, merge_request)
end
@@ -134,22 +132,20 @@ describe "On a merge request", js: true do
end
end
-describe "On a merge request diff", js: true, focus: true do
- let!(:project) { create(:project) }
- let!(:merge_request) { create(:merge_request_with_diffs, source_project: project, target_project: project) }
+describe "On a merge request diff", js: true do
+ let(:merge_request) { create(:merge_request, :with_diffs, :simple) }
+ let(:project) { merge_request.source_project }
before do
- login_as :user
- project.team << [@user, :master]
+ login_as :admin
visit diffs_project_merge_request_path(project, merge_request)
end
-
subject { page }
describe "when adding a note" do
before do
- find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_172_185"]').click
+ find('a[data-line-code="8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7"]').click
end
describe "the notes holder" do
@@ -160,13 +156,13 @@ describe "On a merge request diff", js: true, focus: true do
describe "the note form" do
it "shouldn't add a second form for same row" do
- find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_172_185"]').click
+ find('a[data-line-code="8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7"]').click
- should have_css("tr[id='4735dfc552ad7bf15ca468adc3cad9d05b624490_172_185'] + .js-temp-notes-holder form", count: 1)
+ should have_css("tr[id='8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7'] + .js-temp-notes-holder form", count: 1)
end
it "should be removed when canceled" do
- within(".diff-file form[rel$='4735dfc552ad7bf15ca468adc3cad9d05b624490_172_185']") do
+ within(".diff-file form[rel$='8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7']") do
find(".js-close-discussion-note-form").trigger("click")
end
@@ -176,12 +172,9 @@ describe "On a merge request diff", js: true, focus: true do
end
describe "with muliple note forms" do
- let!(:project) { create(:project) }
- let!(:merge_request) { create(:merge_request_with_diffs, source_project: project, target_project: project) }
-
before do
- find('a[data-line-code="4735dfc552ad7bf15ca468adc3cad9d05b624490_172_185"]').click
- find('a[data-line-code="342e16cbbd482ac2047dc679b2749d248cc1428f_18_17"]').click
+ find('a[data-line-code="8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7"]').click
+ find('a[data-line-code="8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_10_10"]').click
end
it { should have_css(".js-temp-notes-holder", count: 2) }
@@ -189,12 +182,12 @@ describe "On a merge request diff", js: true, focus: true do
describe "previewing them separately" do
before do
# add two separate texts and trigger previews on both
- within("tr[id='4735dfc552ad7bf15ca468adc3cad9d05b624490_172_185'] + .js-temp-notes-holder") do
- fill_in "note[note]", with: "One comment on line 185"
+ within("tr[id='8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_7_7'] + .js-temp-notes-holder") do
+ fill_in "note[note]", with: "One comment on line 7"
find(".js-note-preview-button").trigger("click")
end
- within("tr[id='342e16cbbd482ac2047dc679b2749d248cc1428f_18_17'] + .js-temp-notes-holder") do
- fill_in "note[note]", with: "Another comment on line 17"
+ within("tr[id='8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_10_10'] + .js-temp-notes-holder") do
+ fill_in "note[note]", with: "Another comment on line 10"
find(".js-note-preview-button").trigger("click")
end
end
@@ -202,14 +195,14 @@ describe "On a merge request diff", js: true, focus: true do
describe "posting a note" do
before do
- within("tr[id='342e16cbbd482ac2047dc679b2749d248cc1428f_18_17'] + .js-temp-notes-holder") do
- fill_in "note[note]", with: "Another comment on line 17"
+ within("tr[id='8ec9a00bfd09b3190ac6b22251dbb1aa95a0579d_10_10'] + .js-temp-notes-holder") do
+ fill_in "note[note]", with: "Another comment on line 10"
click_button("Add Comment")
end
end
it 'should be added as discussion' do
- should have_content("Another comment on line 17")
+ should have_content("Another comment on line 10")
should have_css(".notes_holder")
should have_css(".notes_holder .note", count: 1)
should have_link("Reply")
diff --git a/spec/features/security/group/internal_group_access_spec.rb b/spec/features/security/group/internal_group_access_spec.rb
index 0c354f02456..79a6aee41b5 100644
--- a/spec/features/security/group/internal_group_access_spec.rb
+++ b/spec/features/security/group/internal_group_access_spec.rb
@@ -16,7 +16,7 @@ describe "Group with internal project access" do
group.add_user(reporter, Gitlab::Access::REPORTER)
group.add_user(guest, Gitlab::Access::GUEST)
- create(:project, group: group, visibility_level: Gitlab::VisibilityLevel::INTERNAL)
+ create(:project, :internal, group: group)
end
describe "GET /groups/:path" do
diff --git a/spec/features/security/group/mixed_group_access_spec.rb b/spec/features/security/group/mixed_group_access_spec.rb
index 82e816e388a..028cd32d2bb 100644
--- a/spec/features/security/group/mixed_group_access_spec.rb
+++ b/spec/features/security/group/mixed_group_access_spec.rb
@@ -16,8 +16,8 @@ describe "Group access" do
group.add_user(reporter, Gitlab::Access::REPORTER)
group.add_user(guest, Gitlab::Access::GUEST)
- create(:project, path: "internal_project", group: group, visibility_level: Gitlab::VisibilityLevel::INTERNAL)
- create(:project, path: "public_project", group: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+ create(:project, :internal, path: "internal_project", group: group)
+ create(:project, :public, path: "public_project", group: group)
end
describe "GET /groups/:path" do
diff --git a/spec/features/security/group/public_group_access_spec.rb b/spec/features/security/group/public_group_access_spec.rb
index a9c0afbb60f..f0ed7649eb5 100644
--- a/spec/features/security/group/public_group_access_spec.rb
+++ b/spec/features/security/group/public_group_access_spec.rb
@@ -16,7 +16,7 @@ describe "Group with public project access" do
group.add_user(reporter, Gitlab::Access::REPORTER)
group.add_user(guest, Gitlab::Access::GUEST)
- create(:project, group: group, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
+ create(:project, :public, group: group)
end
describe "GET /groups/:path" do
diff --git a/spec/features/security/project/internal_access_spec.rb b/spec/features/security/project/internal_access_spec.rb
index 8bb1e259efa..152cf66dcfd 100644
--- a/spec/features/security/project/internal_access_spec.rb
+++ b/spec/features/security/project/internal_access_spec.rb
@@ -1,23 +1,18 @@
require 'spec_helper'
describe "Internal Project Access" do
- let(:project) { create(:project) }
+ let(:project) { create(:project, :internal) }
let(:master) { create(:user) }
let(:guest) { create(:user) }
let(:reporter) { create(:user) }
before do
- # internal project
- project.visibility_level = Gitlab::VisibilityLevel::INTERNAL
- project.save!
-
# full access
project.team << [master, :master]
# readonly
project.team << [reporter, :reporter]
-
end
describe "Project should be internal" do
diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb
index 76f9e753dd2..0bd2ccafcc1 100644
--- a/spec/finders/merge_requests_finder_spec.rb
+++ b/spec/finders/merge_requests_finder_spec.rb
@@ -1,13 +1,15 @@
require 'spec_helper'
describe MergeRequestsFinder do
- let(:user) { create :user }
+ let(:user) { create :user }
let(:user2) { create :user }
+
let(:project1) { create(:project) }
let(:project2) { create(:project) }
- let(:merge_request1) { create(:merge_request, author: user, source_project: project1, target_project: project2) }
- let(:merge_request2) { create(:merge_request, author: user, source_project: project2, target_project: project1) }
- let(:merge_request3) { create(:merge_request, author: user, source_project: project2, target_project: project2) }
+
+ let!(:merge_request1) { create(:merge_request, :simple, author: user, source_project: project1, target_project: project2) }
+ let!(:merge_request2) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project1) }
+ let!(:merge_request3) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project2) }
before do
project1.team << [user, :master]
@@ -15,13 +17,7 @@ describe MergeRequestsFinder do
project2.team << [user2, :developer]
end
- describe :execute do
- before :each do
- merge_request1
- merge_request2
- merge_request3
- end
-
+ describe "#execute" do
it 'should filter by scope' do
params = { scope: 'authored', state: 'opened' }
merge_requests = MergeRequestsFinder.new.execute(user, params)
diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb
index cc6ee82ab75..6e3ae4d615b 100644
--- a/spec/finders/projects_finder_spec.rb
+++ b/spec/finders/projects_finder_spec.rb
@@ -4,10 +4,10 @@ describe ProjectsFinder do
let(:user) { create :user }
let(:group) { create :group }
- let(:project1) { create(:empty_project, group: group, visibility_level: Project::PUBLIC) }
- let(:project2) { create(:empty_project, group: group, visibility_level: Project::INTERNAL) }
- let(:project3) { create(:empty_project, group: group, visibility_level: Project::PRIVATE) }
- let(:project4) { create(:empty_project, group: group, visibility_level: Project::PRIVATE) }
+ let(:project1) { create(:empty_project, :public, group: group) }
+ let(:project2) { create(:empty_project, :internal, group: group) }
+ let(:project3) { create(:empty_project, :private, group: group) }
+ let(:project4) { create(:empty_project, :private, group: group) }
context 'non authenticated' do
subject { ProjectsFinder.new.execute(nil, group: group) }
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index f990ed659b8..22d60429ccd 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -229,6 +229,7 @@ describe Notify do
end
context 'for merge requests' do
+ let(:merge_author) { create(:user) }
let(:merge_request) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project) }
let(:merge_request_with_description) { create(:merge_request, author: current_user, assignee: assignee, source_project: project, target_project: project, description: Faker::Lorem.sentence) }
@@ -288,7 +289,30 @@ describe Notify do
it 'contains a link to the merge request' do
should have_body_text /#{project_merge_request_path project, merge_request}/
end
+ end
+
+ describe 'that are merged' do
+ subject { Notify.merged_merge_request_email(recipient.id, merge_request.id, merge_author.id) }
+
+ it_behaves_like 'a multiple recipients email'
+
+ it 'is sent as the merge author' do
+ sender = subject.header[:from].addrs[0]
+ sender.display_name.should eq(merge_author.name)
+ sender.address.should eq(gitlab_sender)
+ end
+
+ it 'has the correct subject' do
+ should have_subject /#{merge_request.title} \(!#{merge_request.iid}\)/
+ end
+ it 'contains the new status' do
+ should have_body_text /merged/i
+ end
+
+ it 'contains a link to the merge request' do
+ should have_body_text /#{project_merge_request_path project, merge_request}/
+ end
end
end
end
diff --git a/spec/models/concerns/issuable_spec.rb b/spec/models/concerns/issuable_spec.rb
index 0827e4f162b..9cbc8990676 100644
--- a/spec/models/concerns/issuable_spec.rb
+++ b/spec/models/concerns/issuable_spec.rb
@@ -25,11 +25,6 @@ describe Issue, "Issuable" do
it { described_class.should respond_to(:assigned) }
end
- it "has an :author_id_of_changes accessor" do
- issue.should respond_to(:author_id_of_changes)
- issue.should respond_to(:author_id_of_changes=)
- end
-
describe ".search" do
let!(:searchable_issue) { create(:issue, title: "Searchable issue") }
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 6bae5951b7b..839350bafbf 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -47,6 +47,7 @@ describe Project do
it { should have_many(:hooks).dependent(:destroy) }
it { should have_many(:protected_branches).dependent(:destroy) }
it { should have_one(:forked_project_link).dependent(:destroy) }
+ it { should have_one(:slack_service).dependent(:destroy) }
end
describe "Mass assignment" do
diff --git a/spec/models/slack_message_spec.rb b/spec/models/slack_message_spec.rb
new file mode 100644
index 00000000000..b39cd4edf82
--- /dev/null
+++ b/spec/models/slack_message_spec.rb
@@ -0,0 +1,56 @@
+require_relative '../../app/models/project_services/slack_message'
+
+describe SlackMessage do
+ subject { SlackMessage.new(args) }
+
+ let(:args) {
+ {
+ after: 'after',
+ before: 'before',
+ project_name: 'project_name',
+ ref: 'refs/heads/master',
+ user_name: 'user_name',
+ project_url: 'url'
+ }
+ }
+
+ context 'push' do
+ before do
+ args[:commits] = [
+ { message: 'message1', url: 'url1', id: 'abcdefghi' },
+ { message: 'message2', url: 'url2', id: '123456789' },
+ ]
+ end
+
+ it 'returns a message regarding pushes' do
+ subject.compose.should ==
+ 'user_name pushed to branch <url/commits/master|master> of ' <<
+ '<url|project_name> (<url/compare/before...after|Compare changes>)' <<
+ "\n - message1 (<url1|abcdef>)" <<
+ "\n - message2 (<url2|123456>)"
+ end
+ end
+
+ context 'new branch' do
+ before do
+ args[:before] = '000000'
+ end
+
+ it 'returns a message regarding a new branch' do
+ subject.compose.should ==
+ 'user_name pushed new branch <url/commits/master|master> to ' <<
+ '<url|project_name>'
+ end
+ end
+
+ context 'removed branch' do
+ before do
+ args[:after] = '000000'
+ end
+
+ it 'returns a message regarding a removed branch' do
+ subject.compose.should ==
+ 'user_name removed branch master from <url|project_name>'
+ end
+ end
+end
diff --git a/spec/models/slack_service_spec.rb b/spec/models/slack_service_spec.rb
new file mode 100644
index 00000000000..387455cb25e
--- /dev/null
+++ b/spec/models/slack_service_spec.rb
@@ -0,0 +1,69 @@
+# == 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)
+# subdomain :string(255)
+# room :string(255)
+# api_key :string(255)
+#
+
+require 'spec_helper'
+
+describe SlackService do
+ describe "Associations" do
+ it { should belong_to :project }
+ it { should have_one :service_hook }
+ end
+
+ describe "Validations" do
+ context "active" do
+ before do
+ subject.active = true
+ end
+
+ it { should validate_presence_of :room }
+ it { should validate_presence_of :subdomain }
+ it { should validate_presence_of :token }
+ end
+ end
+
+ describe "Execute" do
+ let(:slack) { SlackService.new }
+ let(:user) { create(:user) }
+ let(:project) { create(:project) }
+ let(:sample_data) { GitPushService.new.sample_data(project, user) }
+ let(:subdomain) { 'gitlab' }
+ let(:token) { 'verySecret' }
+ let(:api_url) {
+ "https://#{subdomain}.slack.com/services/hooks/incoming-webhook?token=#{token}"
+ }
+
+ before do
+ slack.stub(
+ project: project,
+ project_id: project.id,
+ room: '#gitlab',
+ service_hook: true,
+ subdomain: subdomain,
+ token: token
+ )
+
+ WebMock.stub_request(:post, api_url)
+ end
+
+ it "should call Slack API" do
+ slack.execute(sample_data)
+
+ WebMock.should have_requested(:post, api_url).once
+ end
+ end
+end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index fd8d7133ae9..fef6314f23a 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -292,6 +292,20 @@ describe User do
end
end
+ describe 'search' do
+ let(:user1) { create(:user, username: 'James', email: 'james@testing.com') }
+ let(:user2) { create(:user, username: 'jameson', email: 'jameson@example.com') }
+
+ it "should be case insensitive" do
+ User.search(user1.username.upcase).to_a.should == [user1]
+ User.search(user1.username.downcase).to_a.should == [user1]
+ User.search(user2.username.upcase).to_a.should == [user2]
+ User.search(user2.username.downcase).to_a.should == [user2]
+ User.search(user1.username.downcase).to_a.count.should == 2
+ User.search(user2.username.downcase).to_a.count.should == 1
+ end
+ end
+
describe 'by_username_or_id' do
let(:user1) { create(:user, username: 'foo') }
diff --git a/spec/observers/activity_observer_spec.rb b/spec/observers/activity_observer_spec.rb
deleted file mode 100644
index dc14ab86b6d..00000000000
--- a/spec/observers/activity_observer_spec.rb
+++ /dev/null
@@ -1,61 +0,0 @@
-require 'spec_helper'
-
-describe ActivityObserver do
- let(:project) { create(:project) }
-
- before { Thread.current[:current_user] = create(:user) }
-
- def self.it_should_be_valid_event
- it { @event.should_not be_nil }
- it { @event.project.should == project }
- end
-
- describe "Issue created" do
- before do
- Issue.observers.enable :activity_observer do
- @issue = create(:issue, project: project)
- @event = Event.last
- end
- end
-
- it_should_be_valid_event
- it { @event.action.should == Event::CREATED }
- it { @event.target.should == @issue }
- end
-
- describe "Issue commented" do
- before do
- Note.observers.enable :activity_observer do
- @issue = create(:issue, project: project)
- @note = create(:note, noteable: @issue, project: project, author: @issue.author)
- @event = Event.last
- end
- end
-
- it_should_be_valid_event
- it { @event.action.should == Event::COMMENTED }
- it { @event.target.should == @note }
- end
-
- describe "Ignore system notes" do
- let(:author) { create(:user) }
- let!(:issue) { create(:issue, project: project) }
- let!(:other) { create(:issue) }
-
- it "should not create events for status change notes" do
- expect do
- Note.observers.enable :activity_observer do
- Note.create_status_change_note(issue, project, author, 'reopened', nil)
- end
- end.to_not change { Event.count }
- end
-
- it "should not create events for cross-reference notes" do
- expect do
- Note.observers.enable :activity_observer do
- Note.create_cross_reference_note(issue, other, author, issue.project)
- end
- end.to_not change { Event.count }
- end
- end
-end
diff --git a/spec/observers/merge_request_observer_spec.rb b/spec/observers/merge_request_observer_spec.rb
index 6ad7c4d81da..18df8b78513 100644
--- a/spec/observers/merge_request_observer_spec.rb
+++ b/spec/observers/merge_request_observer_spec.rb
@@ -120,7 +120,7 @@ describe MergeRequestObserver do
end
before do
- @merge_request = create(:merge_request, source_project: project, source_project: project)
+ @merge_request = create(:merge_request, source_project: project, target_project: project)
@event = Event.last
end
diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb
index c55025d72b5..e9422cd2643 100644
--- a/spec/requests/api/issues_spec.rb
+++ b/spec/requests/api/issues_spec.rb
@@ -100,16 +100,4 @@ describe API::API do
response.status.should == 405
end
end
-
- describe "PUT /projects/:id/issues/:issue_id to test observer on close" do
- before { enable_observers }
- after { disable_observers }
-
- it "should create an activity event when an issue is closed" do
- Event.should_receive(:create)
-
- put api("/projects/#{project.id}/issues/#{issue.id}", user),
- state_event: "close"
- end
- end
end
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 1a9e4809e7d..138f218d46c 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -7,6 +7,7 @@ describe API::API do
let(:user) { create(:user) }
let!(:project) {create(:project, creator_id: user.id, namespace: user.namespace) }
let!(:merge_request) { create(:merge_request, author: user, assignee: user, source_project: project, target_project: project, title: "Test") }
+ let!(:note) { create(:note_on_merge_request, author: user, project: project, noteable: merge_request, note: "a comment on a MR") }
before {
project.team << [user, :reporters]
}
@@ -205,4 +206,20 @@ describe API::API do
response.status.should == 404
end
end
+
+ describe "GET :id/merge_request/:merge_request_id/comments" do
+ it "should return merge_request comments" do
+ get api("/projects/#{project.id}/merge_request/#{merge_request.id}/comments", user)
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.length.should == 1
+ json_response.first['note'].should == "a comment on a MR"
+ json_response.first['author']['id'].should == user.id
+ end
+
+ it "should return a 404 error if merge_request_id not found" do
+ get api("/projects/#{project.id}/merge_request/999/comments", user)
+ response.status.should == 404
+ end
+ end
end
diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb
index cb30c98b4d2..7fe65639657 100644
--- a/spec/requests/api/projects_spec.rb
+++ b/spec/requests/api/projects_spec.rb
@@ -13,6 +13,7 @@ describe API::API do
let(:snippet) { create(:project_snippet, author: user, project: project, title: 'example') }
let(:users_project) { create(:users_project, user: user, project: project, project_access: UsersProject::MASTER) }
let(:users_project2) { create(:users_project, user: user3, project: project, project_access: UsersProject::DEVELOPER) }
+ let(:issue_with_labels) { create(:issue, author: user, assignee: user, project: project, :label_list => "label1, label2") }
describe "GET /projects" do
before { project }
@@ -133,7 +134,7 @@ describe API::API do
end
it "should set a project as public" do
- project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::PUBLIC })
+ project = attributes_for(:project, :public)
post api("/projects", user), project
json_response['public'].should be_true
json_response['visibility_level'].should == Gitlab::VisibilityLevel::PUBLIC
@@ -147,21 +148,21 @@ describe API::API do
end
it "should set a project as internal" do
- project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::INTERNAL })
+ project = attributes_for(:project, :internal)
post api("/projects", user), project
json_response['public'].should be_false
json_response['visibility_level'].should == Gitlab::VisibilityLevel::INTERNAL
end
it "should set a project as internal overriding :public" do
- project = attributes_for(:project, { public: true, visibility_level: Gitlab::VisibilityLevel::INTERNAL })
+ project = attributes_for(:project, :internal, { public: true })
post api("/projects", user), project
json_response['public'].should be_false
json_response['visibility_level'].should == Gitlab::VisibilityLevel::INTERNAL
end
it "should set a project as private" do
- project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
+ project = attributes_for(:project, :private)
post api("/projects", user), project
json_response['public'].should be_false
json_response['visibility_level'].should == Gitlab::VisibilityLevel::PRIVATE
@@ -215,7 +216,7 @@ describe API::API do
end
it "should set a project as public" do
- project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::PUBLIC })
+ project = attributes_for(:project, :public)
post api("/projects/user/#{user.id}", admin), project
json_response['public'].should be_true
json_response['visibility_level'].should == Gitlab::VisibilityLevel::PUBLIC
@@ -229,21 +230,21 @@ describe API::API do
end
it "should set a project as internal" do
- project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::INTERNAL })
+ project = attributes_for(:project, :internal)
post api("/projects/user/#{user.id}", admin), project
json_response['public'].should be_false
json_response['visibility_level'].should == Gitlab::VisibilityLevel::INTERNAL
end
it "should set a project as internal overriding :public" do
- project = attributes_for(:project, { public: true, visibility_level: Gitlab::VisibilityLevel::INTERNAL })
+ project = attributes_for(:project, :internal, { public: true })
post api("/projects/user/#{user.id}", admin), project
json_response['public'].should be_false
json_response['visibility_level'].should == Gitlab::VisibilityLevel::INTERNAL
end
it "should set a project as private" do
- project = attributes_for(:project, { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
+ project = attributes_for(:project, :private)
post api("/projects/user/#{user.id}", admin), project
json_response['public'].should be_false
json_response['visibility_level'].should == Gitlab::VisibilityLevel::PRIVATE
@@ -490,10 +491,10 @@ describe API::API do
describe :fork_admin do
let(:project_fork_target) { create(:project) }
- let(:project_fork_source) { create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
+ let(:project_fork_source) { create(:project, :public) }
describe "POST /projects/:id/fork/:forked_from_id" do
- let(:new_project_fork_source) { create(:project, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
+ let(:new_project_fork_source) { create(:project, :public) }
it "shouldn't available for non admin users" do
post api("/projects/#{project_fork_target.id}/fork/#{project_fork_source.id}", user)
@@ -562,10 +563,10 @@ describe API::API do
let!(:post) { create(:empty_project, name: "#{query}_post", creator_id: user.id, namespace: user.namespace) }
let!(:pre_post) { create(:empty_project, name: "pre_#{query}_post", creator_id: user.id, namespace: user.namespace) }
let!(:unfound) { create(:empty_project, name: 'unfound', creator_id: user.id, namespace: user.namespace) }
- let!(:internal) { create(:empty_project, name: "internal #{query}", visibility_level: Gitlab::VisibilityLevel::INTERNAL) }
- let!(:unfound_internal) { create(:empty_project, name: 'unfound internal', visibility_level: Gitlab::VisibilityLevel::INTERNAL) }
- let!(:public) { create(:empty_project, name: "public #{query}", visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
- let!(:unfound_public) { create(:empty_project, name: 'unfound public', visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
+ let!(:internal) { create(:empty_project, :internal, name: "internal #{query}") }
+ let!(:unfound_internal) { create(:empty_project, :internal, name: 'unfound internal') }
+ let!(:public) { create(:empty_project, :public, name: "public #{query}") }
+ let!(:unfound_public) { create(:empty_project, :public, name: 'unfound public') }
context "when unauthenticated" do
it "should return authentication error" do
@@ -632,4 +633,16 @@ describe API::API do
end
end
end
+
+ describe "GET /projects/:id/labels" do
+ before { issue_with_labels }
+
+ it "should return project labels" do
+ get api("/projects/#{project.id}/labels", user)
+ response.status.should == 200
+ json_response.should be_an Array
+ json_response.first['name'].should == issue_with_labels.labels.first.name
+ json_response.last['name'].should == issue_with_labels.labels.last.name
+ end
+ end
end
diff --git a/spec/seed_project.tar.gz b/spec/seed_project.tar.gz
index 92b9587e3f7..8d32a927da8 100644
--- a/spec/seed_project.tar.gz
+++ b/spec/seed_project.tar.gz
Binary files differ
diff --git a/spec/services/event_create_service_spec.rb b/spec/services/event_create_service_spec.rb
new file mode 100644
index 00000000000..713aa3e7e74
--- /dev/null
+++ b/spec/services/event_create_service_spec.rb
@@ -0,0 +1,103 @@
+require 'spec_helper'
+
+describe EventCreateService do
+ let(:service) { EventCreateService.new }
+
+ describe 'Issues' do
+ describe :open_issue do
+ let(:issue) { create(:issue) }
+
+ it { service.open_issue(issue, issue.author).should be_true }
+
+ it "should create new event" do
+ expect { service.open_issue(issue, issue.author) }.to change { Event.count }
+ end
+ end
+
+ describe :close_issue do
+ let(:issue) { create(:issue) }
+
+ it { service.close_issue(issue, issue.author).should be_true }
+
+ it "should create new event" do
+ expect { service.close_issue(issue, issue.author) }.to change { Event.count }
+ end
+ end
+
+ describe :reopen_issue do
+ let(:issue) { create(:issue) }
+
+ it { service.reopen_issue(issue, issue.author).should be_true }
+
+ it "should create new event" do
+ expect { service.reopen_issue(issue, issue.author) }.to change { Event.count }
+ end
+ end
+ end
+
+ describe 'Merge Requests' do
+ describe :open_mr do
+ let(:merge_request) { create(:merge_request) }
+
+ it { service.open_mr(merge_request, merge_request.author).should be_true }
+
+ it "should create new event" do
+ expect { service.open_mr(merge_request, merge_request.author) }.to change { Event.count }
+ end
+ end
+
+ describe :close_mr do
+ let(:merge_request) { create(:merge_request) }
+
+ it { service.close_mr(merge_request, merge_request.author).should be_true }
+
+ it "should create new event" do
+ expect { service.close_mr(merge_request, merge_request.author) }.to change { Event.count }
+ end
+ end
+
+ describe :merge_mr do
+ let(:merge_request) { create(:merge_request) }
+
+ it { service.merge_mr(merge_request, merge_request.author).should be_true }
+
+ it "should create new event" do
+ expect { service.merge_mr(merge_request, merge_request.author) }.to change { Event.count }
+ end
+ end
+
+ describe :reopen_mr do
+ let(:merge_request) { create(:merge_request) }
+
+ it { service.reopen_mr(merge_request, merge_request.author).should be_true }
+
+ it "should create new event" do
+ expect { service.reopen_mr(merge_request, merge_request.author) }.to change { Event.count }
+ end
+ end
+ end
+
+ describe 'Milestone' do
+ let(:user) { create :user }
+
+ describe :open_milestone do
+ let(:milestone) { create(:milestone) }
+
+ it { service.open_milestone(milestone, user).should be_true }
+
+ it "should create new event" do
+ expect { service.open_milestone(milestone, user) }.to change { Event.count }
+ end
+ end
+
+ describe :close_mr do
+ let(:milestone) { create(:milestone) }
+
+ it { service.close_milestone(milestone, user).should be_true }
+
+ it "should create new event" do
+ expect { service.close_milestone(milestone, user) }.to change { Event.count }
+ end
+ end
+ end
+end
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index 077ad8b6e12..fbd73a7086f 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -32,6 +32,7 @@ describe NotificationService do
describe 'Notes' do
context 'issue note' do
let(:issue) { create(:issue, assignee: create(:user)) }
+ let(:mentioned_issue) { create(:issue, assignee: issue.assignee) }
let(:note) { create(:note_on_issue, noteable: issue, project_id: issue.project_id, note: '@mention referenced') }
before do
@@ -50,6 +51,13 @@ describe NotificationService do
notification.new_note(note)
end
+ it 'filters out "mentioned in" notes' do
+ mentioned_note = Note.create_cross_reference_note(mentioned_issue, issue, issue.author, issue.project)
+
+ Notify.should_not_receive(:note_issue_email)
+ notification.new_note(mentioned_note)
+ end
+
def should_email(user_id)
Notify.should_receive(:note_issue_email).with(user_id, note.id)
end
@@ -233,15 +241,15 @@ describe NotificationService do
should_email(@u_watcher.id)
should_not_email(@u_participating.id)
should_not_email(@u_disabled.id)
- notification.merge_mr(merge_request)
+ notification.merge_mr(merge_request, @u_disabled)
end
def should_email(user_id)
- Notify.should_receive(:merged_merge_request_email).with(user_id, merge_request.id)
+ Notify.should_receive(:merged_merge_request_email).with(user_id, merge_request.id, @u_disabled.id)
end
def should_not_email(user_id)
- Notify.should_not_receive(:merged_merge_request_email).with(user_id, merge_request.id)
+ Notify.should_not_receive(:merged_merge_request_email).with(user_id, merge_request.id, @u_disabled.id)
end
end
end
diff --git a/spec/services/projects_create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index f2a784df103..f2a784df103 100644
--- a/spec/services/projects_create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
diff --git a/spec/services/project_transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb
index 109b429967e..109b429967e 100644
--- a/spec/services/project_transfer_service_spec.rb
+++ b/spec/services/projects/transfer_service_spec.rb
diff --git a/spec/services/projects_update_service_spec.rb b/spec/services/projects/update_service_spec.rb
index 1854c0d8233..1854c0d8233 100644
--- a/spec/services/projects_update_service_spec.rb
+++ b/spec/services/projects/update_service_spec.rb
diff --git a/spec/services/search_service_spec.rb b/spec/services/search_service_spec.rb
index 457cb3c0ca3..b467282a5d6 100644
--- a/spec/services/search_service_spec.rb
+++ b/spec/services/search_service_spec.rb
@@ -1,28 +1,26 @@
require 'spec_helper'
describe 'Search::GlobalService' do
- let(:found_namespace) { create(:namespace, name: 'searchable namespace', path:'another_thing') }
let(:user) { create(:user, namespace: found_namespace) }
- let!(:found_project) { create(:project, name: 'searchable_project', creator_id: user.id, namespace: found_namespace, visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
+ let(:public_user) { create(:user, namespace: public_namespace) }
+ let(:internal_user) { create(:user, namespace: internal_namespace) }
+ let(:found_namespace) { create(:namespace, name: 'searchable namespace', path:'another_thing') }
let(:unfound_namespace) { create(:namespace, name: 'unfound namespace', path: 'yet_something_else') }
- let!(:unfound_project) { create(:project, name: 'unfound_project', creator_id: user.id, namespace: unfound_namespace, visibility_level: Gitlab::VisibilityLevel::PRIVATE) }
+ let(:internal_namespace) { create(:namespace, name: 'searchable internal namespace', path: 'something_internal') }
+ let(:public_namespace) { create(:namespace, name: 'searchable public namespace', path: 'something_public') }
- let(:internal_namespace) { create(:namespace, path: 'something_internal',name: 'searchable internal namespace') }
- let(:internal_user) { create(:user, namespace: internal_namespace) }
- let!(:internal_project) { create(:project, name: 'searchable_internal_project', creator_id: internal_user.id, namespace: internal_namespace, visibility_level: Gitlab::VisibilityLevel::INTERNAL) }
-
- let(:public_namespace) { create(:namespace, path: 'something_public',name: 'searchable public namespace') }
- let(:public_user) { create(:user, namespace: public_namespace) }
- let!(:public_project) { create(:project, name: 'searchable_public_project', creator_id: public_user.id, namespace: public_namespace, visibility_level: Gitlab::VisibilityLevel::PUBLIC) }
+ let!(:found_project) { create(:project, :private, name: 'searchable_project', creator_id: user.id, namespace: found_namespace) }
+ let!(:unfound_project) { create(:project, :private, name: 'unfound_project', creator_id: user.id, namespace: unfound_namespace) }
+ let!(:internal_project) { create(:project, :internal, name: 'searchable_internal_project', creator_id: internal_user.id, namespace: internal_namespace) }
+ let!(:public_project) { create(:project, :public, name: 'searchable_public_project', creator_id: public_user.id, namespace: public_namespace) }
describe '#execute' do
context 'unauthenticated' do
it 'should return public projects only' do
context = Search::GlobalService.new(nil, search: "searchable")
results = context.execute
- results[:projects].should have(1).items
- results[:projects].should include(public_project)
+ results[:projects].should match_array [public_project]
end
end
@@ -30,24 +28,19 @@ describe 'Search::GlobalService' do
it 'should return public, internal and private projects' do
context = Search::GlobalService.new(user, search: "searchable")
results = context.execute
- results[:projects].should have(3).items
- results[:projects].should include(public_project)
- results[:projects].should include(found_project)
- results[:projects].should include(internal_project)
+ results[:projects].should match_array [public_project, found_project, internal_project]
end
it 'should return only public & internal projects' do
context = Search::GlobalService.new(internal_user, search: "searchable")
results = context.execute
- results[:projects].should have(2).items
- results[:projects].should include(internal_project)
- results[:projects].should include(public_project)
+ results[:projects].should match_array [internal_project, public_project]
end
it 'namespace name should be searchable' do
context = Search::GlobalService.new(user, search: "searchable namespace")
results = context.execute
- results[:projects].should == [found_project]
+ results[:projects].should match_array [found_project]
end
end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index dd008ed02ad..e6b1f816df0 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -1,63 +1,50 @@
-require 'rubygems'
-require 'spork'
+# This file is copied to spec/ when you run 'rails generate rspec:install'
+ENV["RAILS_ENV"] ||= 'test'
+require File.expand_path("../../config/environment", __FILE__)
-Spork.prefork do
- require 'simplecov' unless ENV['CI']
+require 'simplecov' unless ENV['CI']
- if ENV['TRAVIS']
- require 'coveralls'
- Coveralls.wear!
- end
-
- # This file is copied to spec/ when you run 'rails generate rspec:install'
- ENV["RAILS_ENV"] ||= 'test'
- require File.expand_path("../../config/environment", __FILE__)
- require 'rspec/rails'
- require 'capybara/rails'
- require 'capybara/rspec'
- require 'webmock/rspec'
- require 'email_spec'
- require 'sidekiq/testing/inline'
- require 'capybara/poltergeist'
-
- # Loading more in this block will cause your tests to run faster. However,
-
- # if you change any configuration or code from libraries loaded here, you'll
- # need to restart spork for it take effect.
- Capybara.javascript_driver = :poltergeist
- Capybara.default_wait_time = 10
-
- # Requires supporting ruby files with custom matchers and macros, etc,
- # in spec/support/ and its subdirectories.
- Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
-
- WebMock.disable_net_connect!(allow_localhost: true)
-
- RSpec.configure do |config|
- config.mock_with :rspec
-
- config.include LoginHelpers, type: :feature
- config.include LoginHelpers, type: :request
- config.include FactoryGirl::Syntax::Methods
- config.include Devise::TestHelpers, type: :controller
-
- config.include TestEnv
-
- # If you're not using ActiveRecord, or you'd prefer not to run each of your
- # examples within a transaction, remove the following line or assign false
- # instead of true.
- config.use_transactional_fixtures = false
-
- config.before(:suite) do
- TestEnv.init(observers: false, init_repos: true, repos: false)
- end
- config.before(:each) do
- TestEnv.setup_stubs
- end
- end
+if ENV['TRAVIS']
+ require 'coveralls'
+ Coveralls.wear!
end
-Spork.each_run do
- # This code will be run each time you run your specs.
+require 'rspec/rails'
+require 'capybara/rails'
+require 'capybara/rspec'
+require 'webmock/rspec'
+require 'email_spec'
+require 'sidekiq/testing/inline'
+require 'capybara/poltergeist'
+
+Capybara.javascript_driver = :poltergeist
+Capybara.default_wait_time = 10
+
+# Requires supporting ruby files with custom matchers and macros, etc,
+# in spec/support/ and its subdirectories.
+Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
+
+WebMock.disable_net_connect!(allow_localhost: true)
+RSpec.configure do |config|
+ config.mock_with :rspec
+
+ config.include LoginHelpers, type: :feature
+ config.include LoginHelpers, type: :request
+ config.include FactoryGirl::Syntax::Methods
+ config.include Devise::TestHelpers, type: :controller
+
+ config.include TestEnv
+
+ # If you're not using ActiveRecord, or you'd prefer not to run each of your
+ # examples within a transaction, remove the following line or assign false
+ # instead of true.
+ config.use_transactional_fixtures = false
+
+ config.before(:suite) do
+ TestEnv.init(observers: false, init_repos: true, repos: false)
+ end
+ config.before(:each) do
+ TestEnv.setup_stubs
+ end
end
diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb
index e2c3f648ccf..d237f7ad094 100644
--- a/spec/support/test_env.rb
+++ b/spec/support/test_env.rb
@@ -29,7 +29,6 @@ module TestEnv
disable_mailer if opts[:mailer] == false
setup_stubs
-
clear_test_repo_dir if opts[:init_repos] == true
setup_test_repos(opts) if opts[:repos] == true
end
@@ -91,7 +90,7 @@ module TestEnv
size: 12.45
)
- ActivityObserver.any_instance.stub(
+ BaseObserver.any_instance.stub(
current_user: double("current_user", id: 1)
)
end
@@ -165,8 +164,7 @@ module TestEnv
def clear_test_repo_dir
setup_stubs
- # Use tmp dir for FS manipulations
- repos_path = testing_path()
+
# Remove tmp/test-git-base-path
FileUtils.rm_rf Gitlab.config.gitlab_shell.repos_path