summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTomasz Maczukin <tomasz@maczukin.pl>2016-01-13 20:53:42 +0100
committerTomasz Maczukin <tomasz@maczukin.pl>2016-01-13 20:53:42 +0100
commitc9a16619798236e95ef8078b9f2e935c38126f97 (patch)
tree99f84905ecfa360a29cf97a4da694d0531f0a740
parent13032b713d0943c2b7e2f2a3b886ef06be8e88ef (diff)
parent0e344aa2299d2f6911282de5d4808c70d658d372 (diff)
downloadgitlab-ce-c9a16619798236e95ef8078b9f2e935c38126f97.tar.gz
Merge branch 'master' into ci/api-builds
* master: (76 commits) Add Changelog entry for build traces data integrity fix Update doc_styleguide.md [ci skip] Added hint that you can search users by name, username, or email. Add changelog Randomize metrics sample intervals Make the metrics sampler interval configurable Don't automatically require awesome_print Disable colorization if STDOUT is not a tty Block the reported user before destroying the record changes `$quote-gray` to `$secondary-text` makes message plural for multiple MRs and removes from loop. Duh. Prepare Installation and Update docs for 8.4 RC1 Mention channel/key bug in irkerd docs Revert "Remove the `:coffee` and `:coffeescript` Haml filters" gets merge request discussion working again adds back in discussion.haml.html for issues commenting and closing/reopening properly. removing last chunk of MR ajax changes, rest will be in another MR reverting more MR ajax files, will appear in different commit reverting MR ajax changes, which will be in a different MR reverting _mr_title.html.haml ...
-rw-r--r--CHANGELOG26
-rw-r--r--CONTRIBUTING.md4
-rw-r--r--GITLAB_WORKHORSE_VERSION2
-rw-r--r--Gemfile8
-rw-r--r--Gemfile.lock84
-rw-r--r--app/assets/javascripts/issue.js.coffee12
-rw-r--r--app/assets/javascripts/logo.js.coffee1
-rw-r--r--app/assets/javascripts/merge_request.js.coffee22
-rw-r--r--app/assets/javascripts/notes.js.coffee14
-rw-r--r--app/assets/stylesheets/framework/lists.scss6
-rw-r--r--app/assets/stylesheets/framework/variables.scss1
-rw-r--r--app/assets/stylesheets/pages/issues.scss5
-rw-r--r--app/assets/stylesheets/pages/projects.scss5
-rw-r--r--app/controllers/admin/abuse_reports_controller.rb6
-rw-r--r--app/controllers/admin/application_settings_controller.rb1
-rw-r--r--app/controllers/application_controller.rb2
-rw-r--r--app/controllers/ci/lints_controller.rb6
-rw-r--r--app/finders/issuable_finder.rb4
-rw-r--r--app/helpers/application_helper.rb4
-rw-r--r--app/helpers/issues_helper.rb9
-rw-r--r--app/helpers/notes_helper.rb2
-rw-r--r--app/helpers/sorting_helper.rb4
-rw-r--r--app/models/abuse_report.rb5
-rw-r--r--app/models/concerns/sortable.rb3
-rw-r--r--app/models/hooks/web_hook.rb4
-rw-r--r--app/models/issue.rb4
-rw-r--r--app/models/merge_request.rb2
-rw-r--r--app/models/project_services/hipchat_service.rb8
-rw-r--r--app/models/project_services/irker_service.rb7
-rw-r--r--app/services/create_tag_service.rb1
-rw-r--r--app/services/system_hooks_service.rb6
-rw-r--r--app/views/admin/application_settings/_form.html.haml7
-rw-r--r--app/views/admin/labels/index.html.haml2
-rw-r--r--app/views/admin/projects/show.html.haml2
-rw-r--r--app/views/admin/users/_head.html.haml4
-rw-r--r--app/views/admin/users/show.html.haml16
-rw-r--r--app/views/ci/lints/show.html.haml6
-rw-r--r--app/views/dashboard/milestones/show.html.haml2
-rw-r--r--app/views/groups/group_members/_new_group_member.html.haml2
-rw-r--r--app/views/projects/issues/_closed_by_box.html.haml6
-rw-r--r--app/views/projects/issues/_discussion.html.haml6
-rw-r--r--app/views/projects/issues/_merge_requests.html.haml6
-rw-r--r--app/views/projects/issues/show.html.haml3
-rw-r--r--app/views/projects/merge_requests/_discussion.html.haml4
-rw-r--r--app/views/projects/notes/_edit_form.html.haml4
-rw-r--r--app/views/projects/notes/_form.html.haml2
-rw-r--r--app/views/projects/project_members/_new_project_member.html.haml2
-rw-r--r--app/views/shared/issuable/_filter.html.haml14
-rw-r--r--config/gitlab.yml.example5
-rw-r--r--config/initializers/1_settings.rb3
-rw-r--r--db/migrate/20160106162223_add_index_milestones_title.rb5
-rw-r--r--db/migrate/20160113111034_add_metrics_sample_interval.rb6
-rw-r--r--db/schema.rb508
-rw-r--r--doc/README.md2
-rw-r--r--doc/api/projects.md17
-rw-r--r--doc/ci/docker/using_docker_images.md2
-rw-r--r--doc/development/doc_styleguide.md231
-rw-r--r--doc/install/installation.md6
-rw-r--r--doc/integration/ldap.md5
-rw-r--r--doc/integration/shibboleth.md4
-rw-r--r--doc/release/patch.md2
-rw-r--r--doc/system_hooks/system_hooks.md6
-rw-r--r--doc/update/8.2-to-8.3.md2
-rw-r--r--doc/update/8.3-to-8.4.md148
-rw-r--r--doc/update/patch_versions.md1
-rw-r--r--doc_styleguide.md25
-rw-r--r--lib/api/entities.rb1
-rw-r--r--lib/api/projects.rb17
-rw-r--r--lib/banzai/filter/reference_filter.rb4
-rw-r--r--lib/gitlab/gitlab_import/importer.rb2
-rw-r--r--lib/gitlab/ldap/access.rb8
-rw-r--r--lib/gitlab/ldap/adapter.rb24
-rw-r--r--lib/gitlab/ldap/config.rb4
-rw-r--r--lib/gitlab/metrics.rb17
-rw-r--r--lib/gitlab/metrics/rack_middleware.rb6
-rw-r--r--lib/gitlab/metrics/sampler.rb30
-rw-r--r--lib/gitlab/metrics/sidekiq_middleware.rb7
-rw-r--r--lib/gitlab/metrics/subscribers/action_view.rb10
-rw-r--r--lib/gitlab/metrics/transaction.rb32
-rw-r--r--lib/tasks/gitlab/task_helpers.rake2
-rw-r--r--spec/features/ci_lint_spec.rb8
-rw-r--r--spec/features/issues_spec.rb12
-rw-r--r--spec/helpers/application_helper_spec.rb4
-rw-r--r--spec/javascripts/issue_spec.js.coffee2
-rw-r--r--spec/lib/gitlab/metrics/rack_middleware_spec.rb2
-rw-r--r--spec/lib/gitlab/metrics/sampler_spec.rb22
-rw-r--r--spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb17
-rw-r--r--spec/lib/gitlab/metrics/subscribers/action_view_spec.rb9
-rw-r--r--spec/lib/gitlab/metrics/transaction_spec.rb44
-rw-r--r--spec/lib/gitlab/metrics_spec.rb9
-rw-r--r--spec/models/abuse_report_spec.rb16
-rw-r--r--spec/services/system_hooks_service_spec.rb32
92 files changed, 1155 insertions, 520 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 9ff4820c12c..b430d4981a9 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,11 @@
Please view this file on the master branch, on stable branches it's out of date.
v 8.4.0 (unreleased)
+ - Autocomplete data is now always loaded, instead of when focusing a comment text area (Yorick Peterse)
+ - Improved performance of finding issues for an entire group (Yorick Peterse)
+ - Added custom application performance measuring system powered by InfluxDB (Yorick Peterse)
+ - Bump fog to 1.36.0 (Stan Hu)
+ - Add user's last used IP addresses to admin page (Stan Hu)
- Add housekeeping function to project settings page
- The default GitLab logo now acts as a loading indicator
- Fix caching issue where build status was not updating in project dashboard (Stan Hu)
@@ -26,6 +31,9 @@ v 8.4.0 (unreleased)
- Show 'All' tab by default in the builds page
- Add Open Graph and Twitter Card data to all pages
- Fix API project lookups when querying with a namespace with dots (Stan Hu)
+ - Enable forcing Two-Factor authentication sitewide, with optional grace period
+ - Import GitHub Pull Requests into GitLab
+ - Change single user API endpoint to return more detailed data (Michael Potthoff)
- Update version check images to use SVG
- Validate README format before displaying
- Enable Microsoft Azure OAuth2 support (Janis Meybohm)
@@ -33,21 +41,29 @@ v 8.4.0 (unreleased)
- Add file finder feature in tree view (Kyungchul Shin)
- Ajax filter by message for commits page
- API: Add support for deleting a tag via the API (Robert Schilling)
+ - Allow subsequent validations in CI Linter
+ - Fix Encoding::CompatibilityError bug when markdown content has some complex URL (Jason Lee)
+
+v 8.3.4
+ - Use gitlab-workhorse 0.5.4 (fixes API routing bug)
-v 8.3.3 (unreleased)
+v 8.3.3
- Preserve CE behavior with JIRA integration by only calling API if URL is set
- Fix duplicated branch creation/deletion events when using Web UI (Stan Hu)
+ - Add configurable LDAP server query timeout
- Get "Merge when build succeeds" to work when commits were pushed to MR target branch while builds were running
- Suppress e-mails on failed builds if allow_failure is set (Stan Hu)
- Fix project transfer e-mail sending incorrect paths in e-mail notification (Stan Hu)
+ - Better support for referencing and closing issues in Asana service (Mike Wyatt)
- Enable "Add key" button when user fills in a proper key (Stan Hu)
- Fix error in processing reply-by-email messages (Jason Lee)
- Fix Error 500 when visiting build page of project with nil runners_token (Stan Hu)
+ - Use WOFF versions of SourceSansPro fonts
+ - Fix regression when builds were not generated for tags created through web/api interface
+ - Fix: maintain milestone filter between Open and Closed tabs (Greg Smethells)
+ - Fix missing artifacts and build traces for build created before 8.3
v 8.3.2
- - Change single user API endpoint to return more detailed data (Michael Potthoff)
-
-v 8.3.2 (unreleased)
- Disable --follow in `git log` to avoid loading duplicate commit data in infinite scroll (Stan Hu)
- Add support for Google reCAPTCHA in user registration
@@ -56,8 +72,6 @@ v 8.3.1
- Fix Error 500 when doing a search in dashboard before visiting any project (Stan Hu)
- Fix LDAP identity and user retrieval when special characters are used
- Move Sidekiq-cron configuration to gitlab.yml
- - Enable forcing Two-Factor authentication sitewide, with optional grace period
- - Import GitHub Pull Requests into GitLab
v 8.3.0
- Bump rack-attack to 4.3.1 for security fix (Stan Hu)
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b9c2b3d2f8e..1eabbdc5cad 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -334,9 +334,9 @@ merge request:
1. [CoffeeScript](https://github.com/thoughtbot/guides/tree/master/style/coffeescript)
1. [Shell commands](doc/development/shell_commands.md) created by GitLab
contributors to enhance security
-1. [Markdown](http://www.cirosantilli.com/markdown-styleguide)
1. [Database Migrations](doc/development/migration_style_guide.md)
-1. [Documentation styleguide](doc_styleguide.md)
+1. [Markdown](http://www.cirosantilli.com/markdown-styleguide)
+1. [Documentation styleguide](doc/development/doc_styleguide.md)
1. Interface text should be written subjectively instead of objectively. It
should be the GitLab core team addressing a person. It should be written in
present time and never use past tense (has been/was). For example instead
diff --git a/GITLAB_WORKHORSE_VERSION b/GITLAB_WORKHORSE_VERSION
index 4b9fcbec101..7d8568351b4 100644
--- a/GITLAB_WORKHORSE_VERSION
+++ b/GITLAB_WORKHORSE_VERSION
@@ -1 +1 @@
-0.5.1
+0.5.4
diff --git a/Gemfile b/Gemfile
index aa912867dda..a9a8bed1064 100644
--- a/Gemfile
+++ b/Gemfile
@@ -22,6 +22,7 @@ gem 'devise', '~> 3.5.3'
gem 'devise-async', '~> 0.9.0'
gem 'doorkeeper', '~> 2.2.0'
gem 'omniauth', '~> 1.2.2'
+gem 'omniauth-azure-oauth2', '~> 0.0.6'
gem 'omniauth-bitbucket', '~> 0.0.2'
gem 'omniauth-cas3', '~> 1.1.2'
gem 'omniauth-facebook', '~> 3.0.0'
@@ -32,8 +33,7 @@ gem 'omniauth-kerberos', '~> 0.3.0', group: :kerberos
gem 'omniauth-saml', '~> 1.4.0'
gem 'omniauth-shibboleth', '~> 1.2.0'
gem 'omniauth-twitter', '~> 1.2.0'
-gem 'omniauth_crowd'
-gem 'omniauth-azure-oauth2'
+gem 'omniauth_crowd', '~> 2.2.0'
gem 'rack-oauth2', '~> 1.2.1'
# reCAPTCHA protection
@@ -80,7 +80,7 @@ gem "carrierwave", '~> 0.9.0'
gem 'dropzonejs-rails', '~> 0.7.1'
# for aws storage
-gem "fog", "~> 1.25.0"
+gem "fog", "~> 1.36.0"
gem "unf", '~> 0.1.4'
# Authorization
@@ -247,7 +247,7 @@ group :development, :test do
gem 'byebug', platform: :mri
gem 'pry-rails'
- gem 'awesome_print', '~> 1.2.0'
+ gem 'awesome_print', '~> 1.2.0', require: false
gem 'fuubar', '~> 2.0.0'
gem 'database_cleaner', '~> 1.4.0'
diff --git a/Gemfile.lock b/Gemfile.lock
index 96bf2bd1a2e..f1bba7f437e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -219,21 +219,45 @@ GEM
flowdock (0.7.1)
httparty (~> 0.7)
multi_json
- fog (1.25.0)
+ fog (1.36.0)
+ fog-aliyun (>= 0.1.0)
+ fog-atmos
+ fog-aws (>= 0.6.0)
fog-brightbox (~> 0.4)
- fog-core (~> 1.25)
+ fog-core (~> 1.32)
+ fog-dynect (~> 0.0.2)
+ fog-ecloud (~> 0.1)
+ fog-google (<= 0.1.0)
fog-json
+ fog-local
+ fog-powerdns (>= 0.1.1)
fog-profitbricks
fog-radosgw (>= 0.0.2)
+ fog-riakcs
fog-sakuracloud (>= 0.0.4)
+ fog-serverlove
fog-softlayer
+ fog-storm_on_demand
fog-terremark
fog-vmfusion
fog-voxel
+ fog-xenserver
fog-xml (~> 0.1.1)
ipaddress (~> 0.5)
nokogiri (~> 1.5, >= 1.5.11)
- opennebula
+ fog-aliyun (0.1.0)
+ fog-core (~> 1.27)
+ fog-json (~> 1.0)
+ ipaddress (~> 0.8)
+ xml-simple (~> 1.1)
+ fog-atmos (0.1.0)
+ fog-core
+ fog-xml
+ fog-aws (0.8.1)
+ fog-core (~> 1.27)
+ fog-json (~> 1.0)
+ fog-xml (~> 0.1)
+ ipaddress (~> 0.8)
fog-brightbox (0.10.1)
fog-core (~> 1.22)
fog-json
@@ -242,21 +266,48 @@ GEM
builder
excon (~> 0.45)
formatador (~> 0.2)
+ fog-dynect (0.0.2)
+ fog-core
+ fog-json
+ fog-xml
+ fog-ecloud (0.3.0)
+ fog-core
+ fog-xml
+ fog-google (0.1.0)
+ fog-core
+ fog-json
+ fog-xml
fog-json (1.0.2)
fog-core (~> 1.0)
multi_json (~> 1.10)
+ fog-local (0.2.1)
+ fog-core (~> 1.27)
+ fog-powerdns (0.1.1)
+ fog-core (~> 1.27)
+ fog-json (~> 1.0)
+ fog-xml (~> 0.1)
fog-profitbricks (0.0.5)
fog-core
fog-xml
nokogiri
- fog-radosgw (0.0.4)
+ fog-radosgw (0.0.5)
fog-core (>= 1.21.0)
fog-json
fog-xml (>= 0.0.1)
- fog-sakuracloud (1.5.0)
+ fog-riakcs (0.1.0)
+ fog-core
+ fog-json
+ fog-xml
+ fog-sakuracloud (1.7.5)
+ fog-core
+ fog-json
+ fog-serverlove (0.1.2)
+ fog-core
+ fog-json
+ fog-softlayer (1.0.3)
fog-core
fog-json
- fog-softlayer (1.0.2)
+ fog-storm_on_demand (0.1.1)
fog-core
fog-json
fog-terremark (0.1.0)
@@ -268,6 +319,9 @@ GEM
fog-voxel (0.1.0)
fog-core
fog-xml
+ fog-xenserver (0.2.2)
+ fog-core
+ fog-xml
fog-xml (0.1.2)
fog-core
nokogiri (~> 1.5, >= 1.5.11)
@@ -377,7 +431,7 @@ GEM
influxdb (0.2.3)
cause
json
- ipaddress (0.8.0)
+ ipaddress (0.8.2)
jquery-atwho-rails (1.3.2)
jquery-rails (4.0.5)
rails-dom-testing (~> 1.0)
@@ -492,10 +546,6 @@ GEM
activesupport
nokogiri (>= 1.4.4)
omniauth (~> 1.0)
- opennebula (4.14.2)
- json
- nokogiri
- rbvmomi
org-ruby (0.9.12)
rubypants (~> 0.2)
orm_adapter (0.5.0)
@@ -571,10 +621,6 @@ GEM
ffi (>= 0.5.0)
rblineprof (0.3.6)
debugger-ruby_core_source (~> 1.3)
- rbvmomi (1.8.2)
- builder
- nokogiri (>= 1.4.1)
- trollop
rdoc (3.12.2)
json (~> 1.4)
recaptcha (1.0.2)
@@ -773,7 +819,6 @@ GEM
multi_json (~> 1.7)
twitter-stream (~> 0.1)
tins (1.6.0)
- trollop (2.1.2)
turbolinks (2.5.3)
coffee-rails
twitter-stream (0.1.16)
@@ -822,6 +867,7 @@ GEM
builder
expression_parser
rinku
+ xml-simple (1.1.5)
xpath (2.0.0)
nokogiri (~> 1.3)
@@ -877,7 +923,7 @@ DEPENDENCIES
ffaker (~> 2.0.0)
flay
flog
- fog (~> 1.25.0)
+ fog (~> 1.36.0)
font-awesome-rails (~> 4.2)
foreman
fuubar (~> 2.0.0)
@@ -919,7 +965,7 @@ DEPENDENCIES
oauth2 (~> 1.0.0)
octokit (~> 3.7.0)
omniauth (~> 1.2.2)
- omniauth-azure-oauth2
+ omniauth-azure-oauth2 (~> 0.0.6)
omniauth-bitbucket (~> 0.0.2)
omniauth-cas3 (~> 1.1.2)
omniauth-facebook (~> 3.0.0)
@@ -930,7 +976,7 @@ DEPENDENCIES
omniauth-saml (~> 1.4.0)
omniauth-shibboleth (~> 1.2.0)
omniauth-twitter (~> 1.2.0)
- omniauth_crowd
+ omniauth_crowd (~> 2.2.0)
org-ruby (~> 0.9.12)
paranoia (~> 2.0)
pg (~> 0.18.2)
diff --git a/app/assets/javascripts/issue.js.coffee b/app/assets/javascripts/issue.js.coffee
index c256ec8f41b..0d26c58a81d 100644
--- a/app/assets/javascripts/issue.js.coffee
+++ b/app/assets/javascripts/issue.js.coffee
@@ -16,12 +16,16 @@ class @Issue
$(document).on 'tasklist:changed', '.detail-page-description .js-task-list-container', @updateTaskList
initIssueBtnEventListeners: ->
+ _this = @
issueFailMessage = 'Unable to update this issue at this time.'
$('a.btn-close, a.btn-reopen').on 'click', (e) ->
e.preventDefault()
e.stopImmediatePropagation()
$this = $(this)
isClose = $this.hasClass('btn-close')
+ shouldSubmit = $this.hasClass('btn-comment')
+ if shouldSubmit
+ _this.submitNoteForm($this.closest('form'))
$this.prop('disabled', true)
url = $this.attr('href')
$.ajax
@@ -32,12 +36,13 @@ class @Issue
new Flash(issueFailMessage, 'alert')
success: (data, textStatus, jqXHR) ->
if data.saved
- $this.addClass('hidden')
if isClose
+ $('a.btn-close').addClass('hidden')
$('a.btn-reopen').removeClass('hidden')
$('div.status-box-closed').removeClass('hidden')
$('div.status-box-open').addClass('hidden')
else
+ $('a.btn-reopen').addClass('hidden')
$('a.btn-close').removeClass('hidden')
$('div.status-box-closed').addClass('hidden')
$('div.status-box-open').removeClass('hidden')
@@ -45,6 +50,11 @@ class @Issue
new Flash(issueFailMessage, 'alert')
$this.prop('disabled', false)
+ submitNoteForm: (form) =>
+ noteText = form.find("textarea.js-note-text").val()
+ if noteText.trim().length > 0
+ form.submit()
+
disableTaskList: ->
$('.detail-page-description .js-task-list-container').taskList('disable')
$(document).off 'tasklist:changed', '.detail-page-description .js-task-list-container'
diff --git a/app/assets/javascripts/logo.js.coffee b/app/assets/javascripts/logo.js.coffee
index e864a674cdd..a5879c8b793 100644
--- a/app/assets/javascripts/logo.js.coffee
+++ b/app/assets/javascripts/logo.js.coffee
@@ -21,6 +21,7 @@ start = ->
clearHighlights()
pieceIndex = 0
pieces.reverse() unless pieces[0] == firstPiece
+ clearInterval(currentTimer) if currentTimer
currentTimer = setInterval(work, delay)
stop = ->
diff --git a/app/assets/javascripts/merge_request.js.coffee b/app/assets/javascripts/merge_request.js.coffee
index 9047587db81..ed0bf2b3f48 100644
--- a/app/assets/javascripts/merge_request.js.coffee
+++ b/app/assets/javascripts/merge_request.js.coffee
@@ -19,6 +19,7 @@ class @MergeRequest
# Prevent duplicate event bindings
@disableTaskList()
+ @initMRBtnListeners()
if $("a.btn-close").length
@initTaskList()
@@ -43,6 +44,27 @@ class @MergeRequest
$('.detail-page-description .js-task-list-container').taskList('enable')
$(document).on 'tasklist:changed', '.detail-page-description .js-task-list-container', @updateTaskList
+ initMRBtnListeners: ->
+ _this = @
+ $('a.btn-close, a.btn-reopen').on 'click', (e) ->
+ $this = $(this)
+ if $this.data('submitted')
+ return
+ e.preventDefault()
+ e.stopImmediatePropagation()
+ shouldSubmit = $this.hasClass('btn-comment')
+ console.log("shouldSubmit")
+ if shouldSubmit
+ _this.submitNoteForm($this.closest('form'),$this)
+
+ submitNoteForm: (form, $button) =>
+ noteText = form.find("textarea.js-note-text").val()
+ if noteText.trim().length > 0
+ form.submit()
+ $button.data('submitted',true)
+ $button.trigger('click')
+
+
disableTaskList: ->
$('.detail-page-description .js-task-list-container').taskList('disable')
$(document).off 'tasklist:changed', '.detail-page-description .js-task-list-container'
diff --git a/app/assets/javascripts/notes.js.coffee b/app/assets/javascripts/notes.js.coffee
index 9e5204bfeeb..8ba00ecbbab 100644
--- a/app/assets/javascripts/notes.js.coffee
+++ b/app/assets/javascripts/notes.js.coffee
@@ -33,8 +33,6 @@ class @Notes
$(document).on "click", ".note-edit-cancel", @cancelEdit
# Reopen and close actions for Issue/MR combined with note form submit
- $(document).on "click", ".js-note-target-reopen", @targetReopen
- $(document).on "click", ".js-note-target-close", @targetClose
$(document).on "click", ".js-comment-button", @updateCloseButton
$(document).on "keyup", ".js-note-text", @updateTargetButtons
@@ -512,17 +510,6 @@ class @Notes
visibilityChange: =>
@refresh()
- targetReopen: (e) =>
- @submitNoteForm($(e.target).parents('form'))
-
- targetClose: (e) =>
- @submitNoteForm($(e.target).parents('form'))
-
- submitNoteForm: (form) =>
- noteText = form.find(".js-note-text").val()
- if noteText.trim().length > 0
- form.submit()
-
updateCloseButton: (e) =>
textarea = $(e.target)
form = textarea.parents('form')
@@ -531,7 +518,6 @@ class @Notes
updateTargetButtons: (e) =>
textarea = $(e.target)
form = textarea.parents('form')
-
if textarea.val().trim().length > 0
form.find('.js-note-target-reopen').text('Comment & reopen')
form.find('.js-note-target-close').text('Comment & close')
diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss
index 1c74e525a60..bbdb1c038c5 100644
--- a/app/assets/stylesheets/framework/lists.scss
+++ b/app/assets/stylesheets/framework/lists.scss
@@ -74,7 +74,7 @@
/** light list with border-bottom between li **/
-ul.bordered-list {
+ul.bordered-list, ul.unstyled-list {
@include basic-list;
&.top-list {
@@ -88,6 +88,10 @@ ul.bordered-list {
}
}
+ul.unstyled-list > li {
+ border-bottom: none;
+}
+
ul.task-list {
li.task-list-item {
list-style-type: none;
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index af75123b0af..d0ff3248ce1 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -24,6 +24,7 @@ $gl-gray: #5a5a5a;
$gl-padding: 16px;
$gl-padding-top:10px;
$gl-avatar-size: 46px;
+$secondary-text: #7f8fa4;
/*
* Color schema
diff --git a/app/assets/stylesheets/pages/issues.scss b/app/assets/stylesheets/pages/issues.scss
index a02a3a72e79..1e1af662850 100644
--- a/app/assets/stylesheets/pages/issues.scss
+++ b/app/assets/stylesheets/pages/issues.scss
@@ -144,3 +144,8 @@ form.edit-issue {
.issue-form .select2-container {
width: 250px !important;
}
+
+.issue-closed-by-widget {
+ color: $secondary-text;
+ margin-left: 52px;
+} \ No newline at end of file
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index d32509b7d49..f24b71963a8 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -295,10 +295,9 @@
border: 1px solid #c6cacf !important;
background-color: #e4e7ed !important;
- text-transform: uppercase;
+ text-transform: none;
color: #313236 !important;
- font-size: 13px;
- font-weight: 600;
+ font-size: 15px;
}
.dropdown-menu {
diff --git a/app/controllers/admin/abuse_reports_controller.rb b/app/controllers/admin/abuse_reports_controller.rb
index 38a5a9fca08..2463cfa87be 100644
--- a/app/controllers/admin/abuse_reports_controller.rb
+++ b/app/controllers/admin/abuse_reports_controller.rb
@@ -6,11 +6,9 @@ class Admin::AbuseReportsController < Admin::ApplicationController
def destroy
abuse_report = AbuseReport.find(params[:id])
- if params[:remove_user]
- abuse_report.user.destroy
- end
-
+ abuse_report.remove_user if params[:remove_user]
abuse_report.destroy
+
render nothing: true
end
end
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index 44d06b6a647..91f7d78bd73 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -73,6 +73,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:metrics_pool_size,
:metrics_timeout,
:metrics_method_call_threshold,
+ :metrics_sample_interval,
:recaptcha_enabled,
:recaptcha_site_key,
:recaptcha_private_key,
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index d9a37a4d45f..81cb1367e2c 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -286,7 +286,7 @@ class ApplicationController < ActionController::Base
end
def set_filters_params
- params[:sort] ||= 'created_desc'
+ params[:sort] ||= 'id_desc'
params[:scope] = 'all' if params[:scope].blank?
params[:state] = 'opened' if params[:state].blank?
diff --git a/app/controllers/ci/lints_controller.rb b/app/controllers/ci/lints_controller.rb
index e782a51e7eb..a7af3cb8345 100644
--- a/app/controllers/ci/lints_controller.rb
+++ b/app/controllers/ci/lints_controller.rb
@@ -6,11 +6,13 @@ module Ci
end
def create
- if params[:content].blank?
+ @content = params[:content]
+
+ if @content.blank?
@status = false
@error = "Please provide content of .gitlab-ci.yml"
else
- @config_processor = Ci::GitlabCiYamlProcessor.new params[:content]
+ @config_processor = Ci::GitlabCiYamlProcessor.new(@content)
@stages = @config_processor.stages
@builds = @config_processor.builds
@status = true
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index 3d5e8b6fbe7..4d56b48e3f8 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -79,9 +79,9 @@ class IssuableFinder
if project?
@projects = project
elsif current_user && params[:authorized_only].presence && !current_user_related?
- @projects = current_user.authorized_projects
+ @projects = current_user.authorized_projects.reorder(nil)
else
- @projects = ProjectsFinder.new.execute(current_user)
+ @projects = ProjectsFinder.new.execute(current_user).reorder(nil)
end
end
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 2b9bad9c9ea..436fbcd4138 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -205,7 +205,7 @@ module ApplicationHelper
def time_ago_with_tooltip(time, placement: 'top', html_class: 'time_ago', skip_js: false)
element = content_tag :time, time.to_s,
class: "#{html_class} js-timeago js-timeago-pending",
- datetime: time.getutc.iso8601,
+ datetime: time.to_time.getutc.iso8601,
title: time.in_time_zone.to_s(:medium),
data: { toggle: 'tooltip', placement: placement, container: 'body' }
@@ -266,7 +266,7 @@ module ApplicationHelper
state: params[:state],
scope: params[:scope],
label_name: params[:label_name],
- milestone_id: params[:milestone_id],
+ milestone_title: params[:milestone_title],
assignee_id: params[:assignee_id],
author_id: params[:author_id],
sort: params[:sort],
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index a7080ddfefb..43262d579e9 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -103,9 +103,12 @@ module IssuesHelper
content_tag :div, "",
class: "icon emoji-icon emoji-#{unicode}",
- "data-emoji" => name,
- "data-aliases" => aliases.join(" "),
- "data-unicode-name" => unicode
+ title: name,
+ data: {
+ aliases: aliases.join(' '),
+ emoji: name,
+ unicode_name: unicode
+ }
end
def emoji_author_list(notes, current_user)
diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb
index 5f0c921413a..53c543c28c5 100644
--- a/app/helpers/notes_helper.rb
+++ b/app/helpers/notes_helper.rb
@@ -67,7 +67,7 @@ module NotesHelper
line_type: line_type
}
- button_tag class: 'btn reply-btn js-discussion-reply-button',
+ button_tag class: 'btn btn-nr reply-btn js-discussion-reply-button',
data: data, title: 'Add a reply' do
link_text = icon('comment')
link_text << ' Reply'
diff --git a/app/helpers/sorting_helper.rb b/app/helpers/sorting_helper.rb
index 99d7df64a83..241179b0212 100644
--- a/app/helpers/sorting_helper.rb
+++ b/app/helpers/sorting_helper.rb
@@ -63,11 +63,11 @@ module SortingHelper
end
def sort_value_oldest_created
- 'created_asc'
+ 'id_asc'
end
def sort_value_recently_created
- 'created_desc'
+ 'id_desc'
end
def sort_value_milestone_soon
diff --git a/app/models/abuse_report.rb b/app/models/abuse_report.rb
index 55864236b2f..2bc15c60d57 100644
--- a/app/models/abuse_report.rb
+++ b/app/models/abuse_report.rb
@@ -19,6 +19,11 @@ class AbuseReport < ActiveRecord::Base
validates :message, presence: true
validates :user_id, uniqueness: true
+ def remove_user
+ user.block
+ user.destroy
+ end
+
def notify
return unless self.persisted?
diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb
index 7391a77383c..8b47b9e0abd 100644
--- a/app/models/concerns/sortable.rb
+++ b/app/models/concerns/sortable.rb
@@ -11,6 +11,7 @@ module Sortable
default_scope { order_id_desc }
scope :order_id_desc, -> { reorder(id: :desc) }
+ scope :order_id_asc, -> { reorder(id: :asc) }
scope :order_created_desc, -> { reorder(created_at: :desc) }
scope :order_created_asc, -> { reorder(created_at: :asc) }
scope :order_updated_desc, -> { reorder(updated_at: :desc) }
@@ -28,6 +29,8 @@ module Sortable
when 'updated_desc' then order_updated_desc
when 'created_asc' then order_created_asc
when 'created_desc' then order_created_desc
+ when 'id_desc' then order_id_desc
+ when 'id_asc' then order_id_asc
else
all
end
diff --git a/app/models/hooks/web_hook.rb b/app/models/hooks/web_hook.rb
index d0aadfc330a..3bb50c63cac 100644
--- a/app/models/hooks/web_hook.rb
+++ b/app/models/hooks/web_hook.rb
@@ -48,8 +48,8 @@ class WebHook < ActiveRecord::Base
else
post_url = url.gsub("#{parsed_url.userinfo}@", "")
auth = {
- username: URI.decode(parsed_url.user),
- password: URI.decode(parsed_url.password),
+ username: CGI.unescape(parsed_url.user),
+ password: CGI.unescape(parsed_url.password),
}
response = WebHook.post(post_url,
body: data.to_json,
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 80ecd15077f..f52e47f3e62 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -33,7 +33,9 @@ class Issue < ActiveRecord::Base
belongs_to :project
validates :project, presence: true
- scope :of_group, ->(group) { where(project_id: group.project_ids) }
+ scope :of_group,
+ ->(group) { where(project_id: group.projects.select(:id).reorder(nil)) }
+
scope :cared, ->(user) { where(assignee_id: user) }
scope :open_for, ->(user) { opened.assigned_to(user) }
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 5723ff36e02..c63d0c01653 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -131,7 +131,7 @@ class MergeRequest < ActiveRecord::Base
validate :validate_branches
validate :validate_fork
- scope :of_group, ->(group) { where("source_project_id in (:group_project_ids) OR target_project_id in (:group_project_ids)", group_project_ids: group.project_ids) }
+ scope :of_group, ->(group) { where("source_project_id in (:group_project_ids) OR target_project_id in (:group_project_ids)", group_project_ids: group.projects.select(:id).reorder(nil)) }
scope :by_branch, ->(branch_name) { where("(source_branch LIKE :branch) OR (target_branch LIKE :branch)", branch: branch_name) }
scope :cared, ->(user) { where('assignee_id = :user OR author_id = :user', user: user.id) }
scope :by_milestone, ->(milestone) { where(milestone_id: milestone) }
diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb
index 32a81808930..0e3fa4a40fe 100644
--- a/app/models/project_services/hipchat_service.rb
+++ b/app/models/project_services/hipchat_service.rb
@@ -120,13 +120,13 @@ class HipchatService < Service
message << "#{push[:user_name]} "
if Gitlab::Git.blank_ref?(before)
message << "pushed new #{ref_type} <a href=\""\
- "#{project_url}/commits/#{URI.escape(ref)}\">#{ref}</a>"\
+ "#{project_url}/commits/#{CGI.escape(ref)}\">#{ref}</a>"\
" to #{project_link}\n"
elsif Gitlab::Git.blank_ref?(after)
message << "removed #{ref_type} <b>#{ref}</b> from <a href=\"#{project.web_url}\">#{project_name}</a> \n"
else
message << "pushed to #{ref_type} <a href=\""\
- "#{project.web_url}/commits/#{URI.escape(ref)}\">#{ref}</a> "
+ "#{project.web_url}/commits/#{CGI.escape(ref)}\">#{ref}</a> "
message << "of <a href=\"#{project.web_url}\">#{project.name_with_namespace.gsub!(/\s/,'')}</a> "
message << "(<a href=\"#{project.web_url}/compare/#{before}...#{after}\">Compare changes</a>)"
@@ -255,8 +255,8 @@ class HipchatService < Service
status = data[:commit][:status]
duration = data[:commit][:duration]
- branch_link = "<a href=\"#{project_url}/commits/#{URI.escape(ref)}\">#{ref}</a>"
- commit_link = "<a href=\"#{project_url}/commit/#{URI.escape(sha)}/builds\">#{Commit.truncate_sha(sha)}</a>"
+ branch_link = "<a href=\"#{project_url}/commits/#{CGI.escape(ref)}\">#{ref}</a>"
+ commit_link = "<a href=\"#{project_url}/commit/#{CGI.escape(sha)}/builds\">#{Commit.truncate_sha(sha)}</a>"
"#{project_link}: Commit #{commit_link} of #{branch_link} #{ref_type} by #{user_name} #{humanized_status(status)} in #{duration} second(s)"
end
diff --git a/app/models/project_services/irker_service.rb b/app/models/project_services/irker_service.rb
index bd9b580038f..04c714bfaad 100644
--- a/app/models/project_services/irker_service.rb
+++ b/app/models/project_services/irker_service.rb
@@ -73,9 +73,10 @@ class IrkerService < Service
'irc[s]://irc.network.net[:port]/#channel. Special cases: if '\
'you want the channel to be a nickname instead, append ",isnick" to ' \
'the channel name; if the channel is protected by a secret password, ' \
- ' append "?key=secretpassword" to the URI. Note that if you specify a ' \
- ' default IRC URI to prepend before each recipient, you can just give ' \
- ' a channel name.' },
+ ' append "?key=secretpassword" to the URI (Note that due to a bug, if you ' \
+ ' want to use a password, you have to omit the "#" on the channel). If you ' \
+ ' specify a default IRC URI to prepend before each recipient, you can just ' \
+ ' give a channel name.' },
{ type: 'checkbox', name: 'colorize_messages' },
]
end
diff --git a/app/services/create_tag_service.rb b/app/services/create_tag_service.rb
index 2452999382a..55985380d31 100644
--- a/app/services/create_tag_service.rb
+++ b/app/services/create_tag_service.rb
@@ -23,6 +23,7 @@ class CreateTagService < BaseService
EventCreateService.new.push(project, current_user, push_data)
project.execute_hooks(push_data.dup, :tag_push_hooks)
project.execute_services(push_data.dup, :tag_push_hooks)
+ CreateCommitBuildsService.new.execute(project, current_user, push_data)
if release_description
CreateReleaseService.new(@project, @current_user).
diff --git a/app/services/system_hooks_service.rb b/app/services/system_hooks_service.rb
index 6dc854ec33d..ea2b26ccb52 100644
--- a/app/services/system_hooks_service.rb
+++ b/app/services/system_hooks_service.rb
@@ -47,7 +47,8 @@ class SystemHooksService
data.merge!({
name: model.name,
email: model.email,
- user_id: model.id
+ user_id: model.id,
+ username: model.username
})
when ProjectMember
data.merge!(project_member_data(model))
@@ -99,8 +100,10 @@ class SystemHooksService
project_path: model.project.path,
project_path_with_namespace: model.project.path_with_namespace,
project_id: model.project.id,
+ user_username: model.user.username,
user_name: model.user.name,
user_email: model.user.email,
+ user_id: model.user.id,
access_level: model.human_access,
project_visibility: Project.visibility_levels.key(model.project.visibility_level_field).downcase
}
@@ -111,6 +114,7 @@ class SystemHooksService
group_name: model.group.name,
group_path: model.group.path,
group_id: model.group.id,
+ user_username: model.user.username,
user_name: model.user.name,
user_email: model.user.email,
user_id: model.user.id,
diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml
index 81337432ab7..83f6814d822 100644
--- a/app/views/admin/application_settings/_form.html.haml
+++ b/app/views/admin/application_settings/_form.html.haml
@@ -202,6 +202,13 @@
.help-block
A method call is only tracked when it takes longer to complete than
the given amount of milliseconds.
+ .form-group
+ = f.label :metrics_sample_interval, 'Sampler Interval (sec)', class: 'control-label col-sm-2'
+ .col-sm-10
+ = f.number_field :metrics_sample_interval, class: 'form-control'
+ .help-block
+ The sampling interval in seconds. Sampled data includes memory usage,
+ retained Ruby objects, file descriptors and so on.
%fieldset
%legend Spam and Anti-bot Protection
diff --git a/app/views/admin/labels/index.html.haml b/app/views/admin/labels/index.html.haml
index d67454c03e7..3c57e3dc174 100644
--- a/app/views/admin/labels/index.html.haml
+++ b/app/views/admin/labels/index.html.haml
@@ -1,5 +1,5 @@
- page_title "Labels"
-= link_to new_admin_label_path, class: "pull-right btn btn-new" do
+= link_to new_admin_label_path, class: "pull-right btn btn-nr btn-new" do
New label
%h3.page-title
Labels
diff --git a/app/views/admin/projects/show.html.haml b/app/views/admin/projects/show.html.haml
index 0c986af4a95..d734e60682a 100644
--- a/app/views/admin/projects/show.html.haml
+++ b/app/views/admin/projects/show.html.haml
@@ -1,7 +1,7 @@
- page_title @project.name_with_namespace, "Projects"
%h3.page-title
Project: #{@project.name_with_namespace}
- = link_to edit_project_path(@project), class: "btn pull-right" do
+ = link_to edit_project_path(@project), class: "btn btn-nr pull-right" do
%i.fa.fa-pencil-square-o
Edit
%hr
diff --git a/app/views/admin/users/_head.html.haml b/app/views/admin/users/_head.html.haml
index 5e17b018163..bc44b1b1d8e 100644
--- a/app/views/admin/users/_head.html.haml
+++ b/app/views/admin/users/_head.html.haml
@@ -7,8 +7,8 @@
.pull-right
- unless @user == current_user || @user.blocked?
- = link_to 'Impersonate', impersonate_admin_user_path(@user), method: :post, class: "btn btn-grouped btn-info"
- = link_to edit_admin_user_path(@user), class: "btn btn-grouped" do
+ = link_to 'Impersonate', impersonate_admin_user_path(@user), method: :post, class: "btn btn-nr btn-grouped btn-info"
+ = link_to edit_admin_user_path(@user), class: "btn btn-nr btn-grouped" do
%i.fa.fa-pencil-square-o
Edit
%hr
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index 2c2450d4117..2bdbae19588 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -71,6 +71,14 @@
No
%li
+ %span.light Current sign-in IP:
+ %strong
+ - if @user.current_sign_in_ip
+ = @user.current_sign_in_ip
+ - else
+ never
+
+ %li
%span.light Current sign-in at:
%strong
- if @user.current_sign_in_at
@@ -79,6 +87,14 @@
never
%li
+ %span.light Last sign-in IP:
+ %strong
+ - if @user.last_sign_in_ip
+ = @user.last_sign_in_ip
+ - else
+ never
+
+ %li
%span.light Last sign-in at:
%strong
- if @user.last_sign_in_at
diff --git a/app/views/ci/lints/show.html.haml b/app/views/ci/lints/show.html.haml
index a144c43be47..0044d779c31 100644
--- a/app/views/ci/lints/show.html.haml
+++ b/app/views/ci/lints/show.html.haml
@@ -4,12 +4,12 @@
.row
= form_tag ci_lint_path, method: :post do
.form-group
- = label_tag :content, 'Content of .gitlab-ci.yml', class: 'control-label text-nowrap'
+ = label_tag(:content, 'Content of .gitlab-ci.yml', class: 'control-label text-nowrap')
.col-sm-12
- = text_area_tag :content, nil, class: 'form-control span1', rows: 7, require: true
+ = text_area_tag(:content, @content, class: 'form-control span1', rows: 7, require: true)
.col-sm-12
.pull-left.prepend-top-10
- = submit_tag 'Validate', class: 'btn btn-success submit-yml'
+ = submit_tag('Validate', class: 'btn btn-success submit-yml')
.row.prepend-top-20
.col-sm-12
diff --git a/app/views/dashboard/milestones/show.html.haml b/app/views/dashboard/milestones/show.html.haml
index 4316c358dcb..49a558e8ac9 100644
--- a/app/views/dashboard/milestones/show.html.haml
+++ b/app/views/dashboard/milestones/show.html.haml
@@ -16,7 +16,7 @@
- if @milestone.complete? && @milestone.active?
.alert.alert-success.prepend-top-default
- %span All issues for this milestone are closed. You may close the milestone now.
+ %span All issues for this milestone are closed. Navigate to the project to close the milestone.
.table-holder
%table.table
diff --git a/app/views/groups/group_members/_new_group_member.html.haml b/app/views/groups/group_members/_new_group_member.html.haml
index 3361d7e2a8d..e7ab4f2409b 100644
--- a/app/views/groups/group_members/_new_group_member.html.haml
+++ b/app/views/groups/group_members/_new_group_member.html.haml
@@ -4,7 +4,7 @@
.col-sm-10
= users_select_tag(:user_ids, multiple: true, class: 'input-large', scope: :all, email_user: true)
.help-block
- Search for existing users or invite new ones using their email address.
+ Search for users by name, username, or email, or invite new ones using their email address.
.form-group
= f.label :access_level, "Group Access", class: 'control-label'
diff --git a/app/views/projects/issues/_closed_by_box.html.haml b/app/views/projects/issues/_closed_by_box.html.haml
index de415ae51a4..38469ed4774 100644
--- a/app/views/projects/issues/_closed_by_box.html.haml
+++ b/app/views/projects/issues/_closed_by_box.html.haml
@@ -1,2 +1,4 @@
-.issue-closed-by-widget.gray-content-block.second-block.white
- This issue will be closed automatically when merge request #{markdown(merge_requests_sentence(@closed_by_merge_requests), pipeline: :gfm)} is accepted.
+.issue-closed-by-widget.second-block
+ - pluralized_mr_this = merge_request_count > 1 ? "these" : "this"
+ - pluralized_mr_is = merge_request_count > 1 ? "are" : "is"
+ When #{pluralized_mr_this} merge #{"request".pluralize(merge_request_count)} #{pluralized_mr_is} accepted, this issue will be closed automatically.
diff --git a/app/views/projects/issues/_discussion.html.haml b/app/views/projects/issues/_discussion.html.haml
index dc434cf38c4..673020a4e30 100644
--- a/app/views/projects/issues/_discussion.html.haml
+++ b/app/views/projects/issues/_discussion.html.haml
@@ -1,9 +1,7 @@
- content_for :note_actions do
- if can?(current_user, :update_issue, @issue)
- - if @issue.closed?
- = link_to 'Reopen Issue', issue_path(@issue, issue: {state_event: :reopen}, status_only: true), method: :put, class: 'btn btn-nr btn-grouped btn-reopen js-note-target-reopen', title: 'Reopen Issue'
- - else
- = link_to 'Close Issue', issue_path(@issue, issue: {state_event: :close}, status_only: true), method: :put, class: 'btn btn-nr btn-grouped btn-close js-note-target-close', title: 'Close Issue'
+ = link_to 'Reopen Issue', issue_path(@issue, issue: {state_event: :reopen}, status_only: true, format: 'json'), data: {no_turbolink: true}, class: "btn btn-nr btn-grouped btn-reopen btn-comment js-note-target-reopen #{issue_button_visibility(@issue, false)}", title: 'Reopen Issue'
+ = link_to 'Close Issue', issue_path(@issue, issue: {state_event: :close}, status_only: true, format: 'json'), data: {no_turbolink: true}, class: "btn btn-nr btn-grouped btn-close btn-comment js-note-target-close #{issue_button_visibility(@issue, true)}", title: 'Close Issue'
#notes
= render 'projects/notes/notes_with_form'
diff --git a/app/views/projects/issues/_merge_requests.html.haml b/app/views/projects/issues/_merge_requests.html.haml
index 254968e4f67..640a1962ffc 100644
--- a/app/views/projects/issues/_merge_requests.html.haml
+++ b/app/views/projects/issues/_merge_requests.html.haml
@@ -1,7 +1,7 @@
-if @merge_requests.any?
%h2.merge-requests-title
= pluralize(@merge_requests.count, 'Related Merge Request')
- %ul.bordered-list
+ %ul.unstyled-list
- has_any_ci = @merge_requests.any?(&:ci_commit)
- @merge_requests.each do |merge_request|
%li
@@ -11,7 +11,7 @@
- elsif has_any_ci
= icon('blank fw')
%span.merge-request-id
- \##{merge_request.iid}
+ \!#{merge_request.iid}
%span.merge-request-info
%strong
= link_to_gfm merge_request.title, merge_request_path(merge_request), class: "row_title"
@@ -24,3 +24,5 @@
MERGED
- elsif merge_request.closed?
CLOSED
+ - if @closed_by_merge_requests.present?
+ = render partial: 'projects/issues/closed_by_box', locals: {merge_request_count: @merge_requests.count}
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index f931a0d3b92..7ed898ce72f 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -53,9 +53,6 @@
.gray-content-block.second-block.oneline-block
= render 'votes/votes_block', votable: @issue
- - if @closed_by_merge_requests.present?
- = render 'projects/issues/closed_by_box'
-
.row
%section.col-md-9
.issuable-discussion
diff --git a/app/views/projects/merge_requests/_discussion.html.haml b/app/views/projects/merge_requests/_discussion.html.haml
index bff3c3b283d..1c7de94acfd 100644
--- a/app/views/projects/merge_requests/_discussion.html.haml
+++ b/app/views/projects/merge_requests/_discussion.html.haml
@@ -1,8 +1,8 @@
- content_for :note_actions do
- if can?(current_user, :update_merge_request, @merge_request)
- if @merge_request.open?
- = link_to 'Close', merge_request_path(@merge_request, merge_request: {state_event: :close }), method: :put, class: "btn btn-nr btn-grouped btn-close close-mr-link js-note-target-close", title: "Close merge request"
+ = link_to 'Close', merge_request_path(@merge_request, merge_request: {state_event: :close }), method: :put, class: "btn btn-nr btn-comment btn-grouped btn-close close-mr-link js-note-target-close", title: "Close merge request"
- if @merge_request.closed?
- = link_to 'Reopen', merge_request_path(@merge_request, merge_request: {state_event: :reopen }), method: :put, class: "btn btn-nr btn-grouped btn-reopen reopen-mr-link js-note-target-reopen", title: "Reopen merge request"
+ = link_to 'Reopen', merge_request_path(@merge_request, merge_request: {state_event: :reopen }), method: :put, class: "btn btn-nr btn-comment btn-grouped btn-reopen reopen-mr-link js-note-target-reopen", title: "Reopen merge request"
#notes= render "projects/notes/notes_with_form"
diff --git a/app/views/projects/notes/_edit_form.html.haml b/app/views/projects/notes/_edit_form.html.haml
index 3ccda1b381c..5d78652befa 100644
--- a/app/views/projects/notes/_edit_form.html.haml
+++ b/app/views/projects/notes/_edit_form.html.haml
@@ -6,5 +6,5 @@
= render 'projects/notes/hints'
.note-form-actions
- = f.submit 'Save Comment', class: 'btn btn-primary btn-save btn-grouped js-comment-button'
- = link_to 'Cancel', '#', class: 'btn btn-cancel note-edit-cancel'
+ = f.submit 'Save Comment', class: 'btn btn-nr btn-save btn-grouped js-comment-button'
+ = link_to 'Cancel', '#', class: 'btn btn-nr btn-cancel note-edit-cancel'
diff --git a/app/views/projects/notes/_form.html.haml b/app/views/projects/notes/_form.html.haml
index acb6dc52a8e..f10a4145d62 100644
--- a/app/views/projects/notes/_form.html.haml
+++ b/app/views/projects/notes/_form.html.haml
@@ -15,4 +15,4 @@
.note-form-actions.clearfix
= f.submit 'Add Comment', class: "btn btn-nr btn-create comment-btn btn-grouped js-comment-button"
= yield(:note_actions)
- %a.btn.btn-cancel.js-close-discussion-note-form Cancel
+ %a.btn.btn-nr.btn-cancel.js-close-discussion-note-form Cancel
diff --git a/app/views/projects/project_members/_new_project_member.html.haml b/app/views/projects/project_members/_new_project_member.html.haml
index d708b01a114..f0f3bb3c177 100644
--- a/app/views/projects/project_members/_new_project_member.html.haml
+++ b/app/views/projects/project_members/_new_project_member.html.haml
@@ -4,7 +4,7 @@
.col-sm-10
= users_select_tag(:user_ids, multiple: true, class: 'input-large', scope: :all, email_user: true)
.help-block
- Search for existing users or invite new ones using their email address.
+ Search for users by name, username, or email, or invite new ones using their email address.
.form-group
= f.label :access_level, "Project Access", class: 'control-label'
diff --git a/app/views/shared/issuable/_filter.html.haml b/app/views/shared/issuable/_filter.html.haml
index be06738eac9..0e3e9275fc1 100644
--- a/app/views/shared/issuable/_filter.html.haml
+++ b/app/views/shared/issuable/_filter.html.haml
@@ -1,25 +1,29 @@
.issues-filters
.issues-state-filters
%ul.center-top-menu
+ - if defined?(type) && type == :merge_requests
+ - page_context_word = 'merge requests'
+ - else
+ - page_context_word = 'issues'
%li{class: ("active" if params[:state] == 'opened')}
- = link_to page_filter_path(state: 'opened') do
+ = link_to page_filter_path(state: 'opened'), title: "Filter by #{page_context_word} that are currently opened." do
#{state_filters_text_for(:opened, @project)}
- if defined?(type) && type == :merge_requests
%li{class: ("active" if params[:state] == 'merged')}
- = link_to page_filter_path(state: 'merged') do
+ = link_to page_filter_path(state: 'merged'), title: 'Filter by merge requests that are currently merged.' do
#{state_filters_text_for(:merged, @project)}
%li{class: ("active" if params[:state] == 'closed')}
- = link_to page_filter_path(state: 'closed') do
+ = link_to page_filter_path(state: 'closed'), title: 'Filter by merge requests that are currently closed and unmerged.' do
#{state_filters_text_for(:closed, @project)}
- else
%li{class: ("active" if params[:state] == 'closed')}
- = link_to page_filter_path(state: 'closed') do
+ = link_to page_filter_path(state: 'closed'), title: 'Filter by issues that are currently closed.' do
#{state_filters_text_for(:closed, @project)}
%li{class: ("active" if params[:state] == 'all')}
- = link_to page_filter_path(state: 'all') do
+ = link_to page_filter_path(state: 'all'), title: "Show all #{page_context_word}." do
#{state_filters_text_for(:all, @project)}
.issues-details-filters.gray-content-block
diff --git a/config/gitlab.yml.example b/config/gitlab.yml.example
index 2d9f730c183..d6e2c9380a5 100644
--- a/config/gitlab.yml.example
+++ b/config/gitlab.yml.example
@@ -204,6 +204,11 @@ production: &base
bind_dn: '_the_full_dn_of_the_user_you_will_bind_with'
password: '_the_password_of_the_bind_user'
+ # Set a timeout, in seconds, for LDAP queries. This helps avoid blocking
+ # a request if the LDAP server becomes unresponsive.
+ # A value of 0 means there is no timeout.
+ timeout: 10
+
# This setting specifies if LDAP server is Active Directory LDAP server.
# For non AD servers it skips the AD specific queries.
# If your LDAP server is not AD, set this to false.
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index 4fbd84ee890..d625a909bf1 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -11,7 +11,7 @@ class Settings < Settingslogic
# get host without www, thanks to http://stackoverflow.com/a/6674363/1233435
def get_host_without_www(url)
- url = URI.encode(url)
+ url = CGI.escape(url)
uri = URI.parse(url)
uri = URI.parse("http://#{url}") if uri.scheme.nil?
host = uri.host.downcase
@@ -108,6 +108,7 @@ if Settings.ldap['enabled'] || Rails.env.test?
Settings.ldap['servers'].each do |key, server|
server['label'] ||= 'LDAP'
+ server['timeout'] ||= 10.seconds
server['block_auto_created_users'] = false if server['block_auto_created_users'].nil?
server['allow_username_or_email_login'] = false if server['allow_username_or_email_login'].nil?
server['active_directory'] = true if server['active_directory'].nil?
diff --git a/db/migrate/20160106162223_add_index_milestones_title.rb b/db/migrate/20160106162223_add_index_milestones_title.rb
new file mode 100644
index 00000000000..767885e2aac
--- /dev/null
+++ b/db/migrate/20160106162223_add_index_milestones_title.rb
@@ -0,0 +1,5 @@
+class AddIndexMilestonesTitle < ActiveRecord::Migration
+ def change
+ add_index :milestones, :title
+ end
+end
diff --git a/db/migrate/20160113111034_add_metrics_sample_interval.rb b/db/migrate/20160113111034_add_metrics_sample_interval.rb
new file mode 100644
index 00000000000..b741f5d2c75
--- /dev/null
+++ b/db/migrate/20160113111034_add_metrics_sample_interval.rb
@@ -0,0 +1,6 @@
+class AddMetricsSampleInterval < ActiveRecord::Migration
+ def change
+ add_column :application_settings, :metrics_sample_interval, :integer,
+ default: 15
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 2ded8a45e18..ecbe575bf83 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20160106164438) do
+ActiveRecord::Schema.define(version: 20160113111034) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -32,23 +32,23 @@ ActiveRecord::Schema.define(version: 20160106164438) do
t.text "sign_in_text"
t.datetime "created_at"
t.datetime "updated_at"
- t.string "home_page_url", limit: 255
- t.integer "default_branch_protection", default: 2
- t.boolean "twitter_sharing_enabled", default: true
+ t.string "home_page_url"
+ t.integer "default_branch_protection", default: 2
+ t.boolean "twitter_sharing_enabled", default: true
t.text "restricted_visibility_levels"
- t.boolean "version_check_enabled", default: true
- t.integer "max_attachment_size", default: 10, null: false
+ t.boolean "version_check_enabled", default: true
+ t.integer "max_attachment_size", default: 10, null: false
t.integer "default_project_visibility"
t.integer "default_snippet_visibility"
t.text "restricted_signup_domains"
- t.boolean "user_oauth_applications", default: true
- t.string "after_sign_out_path", limit: 255
- t.integer "session_expire_delay", default: 10080, null: false
+ t.boolean "user_oauth_applications", default: true
+ t.string "after_sign_out_path"
+ t.integer "session_expire_delay", default: 10080, null: false
t.text "import_sources"
t.text "help_page_text"
- t.string "admin_notification_email", limit: 255
- t.boolean "shared_runners_enabled", default: true, null: false
- t.integer "max_artifacts_size", default: 100, null: false
+ t.string "admin_notification_email"
+ t.boolean "shared_runners_enabled", default: true, null: false
+ t.integer "max_artifacts_size", default: 100, null: false
t.string "runners_registration_token"
t.boolean "require_two_factor_authentication", default: false
t.integer "two_factor_grace_period", default: 48
@@ -60,14 +60,15 @@ ActiveRecord::Schema.define(version: 20160106164438) do
t.boolean "recaptcha_enabled", default: false
t.string "recaptcha_site_key"
t.string "recaptcha_private_key"
- t.integer "metrics_port", default: 8089
+ t.integer "metrics_port", default: 8089
+ t.integer "metrics_sample_interval", default: 15
end
create_table "audit_events", force: :cascade do |t|
- t.integer "author_id", null: false
- t.string "type", limit: 255, null: false
- t.integer "entity_id", null: false
- t.string "entity_type", limit: 255, null: false
+ t.integer "author_id", null: false
+ t.string "type", null: false
+ t.integer "entity_id", null: false
+ t.string "entity_type", null: false
t.text "details"
t.datetime "created_at"
t.datetime "updated_at"
@@ -78,14 +79,14 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "audit_events", ["type"], name: "index_audit_events_on_type", using: :btree
create_table "broadcast_messages", force: :cascade do |t|
- t.text "message", null: false
+ t.text "message", null: false
t.datetime "starts_at"
t.datetime "ends_at"
t.integer "alert_type"
t.datetime "created_at"
t.datetime "updated_at"
- t.string "color", limit: 255
- t.string "font", limit: 255
+ t.string "color"
+ t.string "font"
end
create_table "ci_application_settings", force: :cascade do |t|
@@ -97,7 +98,7 @@ ActiveRecord::Schema.define(version: 20160106164438) do
create_table "ci_builds", force: :cascade do |t|
t.integer "project_id"
- t.string "status", limit: 255
+ t.string "status"
t.datetime "finished_at"
t.text "trace"
t.datetime "created_at"
@@ -108,19 +109,19 @@ ActiveRecord::Schema.define(version: 20160106164438) do
t.integer "commit_id"
t.text "commands"
t.integer "job_id"
- t.string "name", limit: 255
- t.boolean "deploy", default: false
+ t.string "name"
+ t.boolean "deploy", default: false
t.text "options"
- t.boolean "allow_failure", default: false, null: false
- t.string "stage", limit: 255
+ t.boolean "allow_failure", default: false, null: false
+ t.string "stage"
t.integer "trigger_request_id"
t.integer "stage_idx"
t.boolean "tag"
- t.string "ref", limit: 255
+ t.string "ref"
t.integer "user_id"
- t.string "type", limit: 255
- t.string "target_url", limit: 255
- t.string "description", limit: 255
+ t.string "type"
+ t.string "target_url"
+ t.string "description"
t.text "artifacts_file"
t.integer "gl_project_id"
end
@@ -139,13 +140,13 @@ ActiveRecord::Schema.define(version: 20160106164438) do
create_table "ci_commits", force: :cascade do |t|
t.integer "project_id"
- t.string "ref", limit: 255
- t.string "sha", limit: 255
- t.string "before_sha", limit: 255
+ t.string "ref"
+ t.string "sha"
+ t.string "before_sha"
t.text "push_data"
t.datetime "created_at"
t.datetime "updated_at"
- t.boolean "tag", default: false
+ t.boolean "tag", default: false
t.text "yaml_errors"
t.datetime "committed_at"
t.integer "gl_project_id"
@@ -172,16 +173,16 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "ci_events", ["project_id"], name: "index_ci_events_on_project_id", using: :btree
create_table "ci_jobs", force: :cascade do |t|
- t.integer "project_id", null: false
+ t.integer "project_id", null: false
t.text "commands"
- t.boolean "active", default: true, null: false
+ t.boolean "active", default: true, null: false
t.datetime "created_at"
t.datetime "updated_at"
- t.string "name", limit: 255
- t.boolean "build_branches", default: true, null: false
- t.boolean "build_tags", default: false, null: false
- t.string "job_type", limit: 255, default: "parallel"
- t.string "refs", limit: 255
+ t.string "name"
+ t.boolean "build_branches", default: true, null: false
+ t.boolean "build_tags", default: false, null: false
+ t.string "job_type", default: "parallel"
+ t.string "refs"
t.datetime "deleted_at"
end
@@ -189,25 +190,25 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "ci_jobs", ["project_id"], name: "index_ci_jobs_on_project_id", using: :btree
create_table "ci_projects", force: :cascade do |t|
- t.string "name", limit: 255
- t.integer "timeout", default: 3600, null: false
+ t.string "name"
+ t.integer "timeout", default: 3600, null: false
t.datetime "created_at"
t.datetime "updated_at"
- t.string "token", limit: 255
- t.string "default_ref", limit: 255
- t.string "path", limit: 255
- t.boolean "always_build", default: false, null: false
+ t.string "token"
+ t.string "default_ref"
+ t.string "path"
+ t.boolean "always_build", default: false, null: false
t.integer "polling_interval"
- t.boolean "public", default: false, null: false
- t.string "ssh_url_to_repo", limit: 255
+ t.boolean "public", default: false, null: false
+ t.string "ssh_url_to_repo"
t.integer "gitlab_id"
- t.boolean "allow_git_fetch", default: true, null: false
- t.string "email_recipients", limit: 255, default: "", null: false
- t.boolean "email_add_pusher", default: true, null: false
- t.boolean "email_only_broken_builds", default: true, null: false
- t.string "skip_refs", limit: 255
- t.string "coverage_regex", limit: 255
- t.boolean "shared_runners_enabled", default: false
+ t.boolean "allow_git_fetch", default: true, null: false
+ t.string "email_recipients", default: "", null: false
+ t.boolean "email_add_pusher", default: true, null: false
+ t.boolean "email_only_broken_builds", default: true, null: false
+ t.string "skip_refs"
+ t.string "coverage_regex"
+ t.boolean "shared_runners_enabled", default: false
t.text "generated_yaml_config"
end
@@ -226,34 +227,34 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "ci_runner_projects", ["runner_id"], name: "index_ci_runner_projects_on_runner_id", using: :btree
create_table "ci_runners", force: :cascade do |t|
- t.string "token", limit: 255
+ t.string "token"
t.datetime "created_at"
t.datetime "updated_at"
- t.string "description", limit: 255
+ t.string "description"
t.datetime "contacted_at"
- t.boolean "active", default: true, null: false
- t.boolean "is_shared", default: false
- t.string "name", limit: 255
- t.string "version", limit: 255
- t.string "revision", limit: 255
- t.string "platform", limit: 255
- t.string "architecture", limit: 255
+ t.boolean "active", default: true, null: false
+ t.boolean "is_shared", default: false
+ t.string "name"
+ t.string "version"
+ t.string "revision"
+ t.string "platform"
+ t.string "architecture"
end
create_table "ci_services", force: :cascade do |t|
- t.string "type", limit: 255
- t.string "title", limit: 255
- t.integer "project_id", null: false
+ t.string "type"
+ t.string "title"
+ t.integer "project_id", null: false
t.datetime "created_at"
t.datetime "updated_at"
- t.boolean "active", default: false, null: false
+ t.boolean "active", default: false, null: false
t.text "properties"
end
add_index "ci_services", ["project_id"], name: "index_ci_services_on_project_id", using: :btree
create_table "ci_sessions", force: :cascade do |t|
- t.string "session_id", limit: 255, null: false
+ t.string "session_id", null: false
t.text "data"
t.datetime "created_at"
t.datetime "updated_at"
@@ -265,9 +266,9 @@ ActiveRecord::Schema.define(version: 20160106164438) do
create_table "ci_taggings", force: :cascade do |t|
t.integer "tag_id"
t.integer "taggable_id"
- t.string "taggable_type", limit: 255
+ t.string "taggable_type"
t.integer "tagger_id"
- t.string "tagger_type", limit: 255
+ t.string "tagger_type"
t.string "context", limit: 128
t.datetime "created_at"
end
@@ -276,8 +277,8 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "ci_taggings", ["taggable_id", "taggable_type", "context"], name: "index_ci_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree
create_table "ci_tags", force: :cascade do |t|
- t.string "name", limit: 255
- t.integer "taggings_count", default: 0
+ t.string "name"
+ t.integer "taggings_count", default: 0
end
add_index "ci_tags", ["name"], name: "index_ci_tags_on_name", unique: true, using: :btree
@@ -291,7 +292,7 @@ ActiveRecord::Schema.define(version: 20160106164438) do
end
create_table "ci_triggers", force: :cascade do |t|
- t.string "token", limit: 255
+ t.string "token"
t.integer "project_id"
t.datetime "deleted_at"
t.datetime "created_at"
@@ -304,19 +305,19 @@ ActiveRecord::Schema.define(version: 20160106164438) do
create_table "ci_variables", force: :cascade do |t|
t.integer "project_id"
- t.string "key", limit: 255
+ t.string "key"
t.text "value"
t.text "encrypted_value"
- t.string "encrypted_value_salt", limit: 255
- t.string "encrypted_value_iv", limit: 255
+ t.string "encrypted_value_salt"
+ t.string "encrypted_value_iv"
t.integer "gl_project_id"
end
add_index "ci_variables", ["gl_project_id"], name: "index_ci_variables_on_gl_project_id", using: :btree
create_table "ci_web_hooks", force: :cascade do |t|
- t.string "url", limit: 255, null: false
- t.integer "project_id", null: false
+ t.string "url", null: false
+ t.integer "project_id", null: false
t.datetime "created_at"
t.datetime "updated_at"
end
@@ -331,8 +332,8 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "deploy_keys_projects", ["project_id"], name: "index_deploy_keys_projects_on_project_id", using: :btree
create_table "emails", force: :cascade do |t|
- t.integer "user_id", null: false
- t.string "email", limit: 255, null: false
+ t.integer "user_id", null: false
+ t.string "email", null: false
t.datetime "created_at"
t.datetime "updated_at"
end
@@ -341,9 +342,9 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "emails", ["user_id"], name: "index_emails_on_user_id", using: :btree
create_table "events", force: :cascade do |t|
- t.string "target_type", limit: 255
+ t.string "target_type"
t.integer "target_id"
- t.string "title", limit: 255
+ t.string "title"
t.text "data"
t.integer "project_id"
t.datetime "created_at"
@@ -369,8 +370,8 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "forked_project_links", ["forked_to_project_id"], name: "index_forked_project_links_on_forked_to_project_id", unique: true, using: :btree
create_table "identities", force: :cascade do |t|
- t.string "extern_uid", limit: 255
- t.string "provider", limit: 255
+ t.string "extern_uid"
+ t.string "provider"
t.integer "user_id"
t.datetime "created_at"
t.datetime "updated_at"
@@ -380,17 +381,17 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "identities", ["user_id"], name: "index_identities_on_user_id", using: :btree
create_table "issues", force: :cascade do |t|
- t.string "title", limit: 255
+ t.string "title"
t.integer "assignee_id"
t.integer "author_id"
t.integer "project_id"
t.datetime "created_at"
t.datetime "updated_at"
- t.integer "position", default: 0
- t.string "branch_name", limit: 255
+ t.integer "position", default: 0
+ t.string "branch_name"
t.text "description"
t.integer "milestone_id"
- t.string "state", limit: 255
+ t.string "state"
t.integer "iid"
t.integer "updated_by_id"
end
@@ -410,10 +411,10 @@ ActiveRecord::Schema.define(version: 20160106164438) do
t.datetime "created_at"
t.datetime "updated_at"
t.text "key"
- t.string "title", limit: 255
- t.string "type", limit: 255
- t.string "fingerprint", limit: 255
- t.boolean "public", default: false, null: false
+ t.string "title"
+ t.string "type"
+ t.string "fingerprint"
+ t.boolean "public", default: false, null: false
end
add_index "keys", ["created_at", "id"], name: "index_keys_on_created_at_and_id", using: :btree
@@ -422,7 +423,7 @@ ActiveRecord::Schema.define(version: 20160106164438) do
create_table "label_links", force: :cascade do |t|
t.integer "label_id"
t.integer "target_id"
- t.string "target_type", limit: 255
+ t.string "target_type"
t.datetime "created_at"
t.datetime "updated_at"
end
@@ -431,22 +432,22 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "label_links", ["target_id", "target_type"], name: "index_label_links_on_target_id_and_target_type", using: :btree
create_table "labels", force: :cascade do |t|
- t.string "title", limit: 255
- t.string "color", limit: 255
+ t.string "title"
+ t.string "color"
t.integer "project_id"
t.datetime "created_at"
t.datetime "updated_at"
- t.boolean "template", default: false
+ t.boolean "template", default: false
end
add_index "labels", ["project_id"], name: "index_labels_on_project_id", using: :btree
create_table "lfs_objects", force: :cascade do |t|
- t.string "oid", limit: 255, null: false
- t.integer "size", null: false
+ t.string "oid", null: false
+ t.integer "size", null: false
t.datetime "created_at"
t.datetime "updated_at"
- t.string "file", limit: 255
+ t.string "file"
end
add_index "lfs_objects", ["oid"], name: "index_lfs_objects_on_oid", unique: true, using: :btree
@@ -461,17 +462,17 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "lfs_objects_projects", ["project_id"], name: "index_lfs_objects_projects_on_project_id", using: :btree
create_table "members", force: :cascade do |t|
- t.integer "access_level", null: false
- t.integer "source_id", null: false
- t.string "source_type", limit: 255, null: false
+ t.integer "access_level", null: false
+ t.integer "source_id", null: false
+ t.string "source_type", null: false
t.integer "user_id"
- t.integer "notification_level", null: false
- t.string "type", limit: 255
+ t.integer "notification_level", null: false
+ t.string "type"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "created_by_id"
- t.string "invite_email", limit: 255
- t.string "invite_token", limit: 255
+ t.string "invite_email"
+ t.string "invite_token"
t.datetime "invite_accepted_at"
end
@@ -483,10 +484,10 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "members", ["user_id"], name: "index_members_on_user_id", using: :btree
create_table "merge_request_diffs", force: :cascade do |t|
- t.string "state", limit: 255
+ t.string "state"
t.text "st_commits"
t.text "st_diffs"
- t.integer "merge_request_id", null: false
+ t.integer "merge_request_id", null: false
t.datetime "created_at"
t.datetime "updated_at"
end
@@ -494,26 +495,26 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "merge_request_diffs", ["merge_request_id"], name: "index_merge_request_diffs_on_merge_request_id", unique: true, using: :btree
create_table "merge_requests", force: :cascade do |t|
- t.string "target_branch", limit: 255, null: false
- t.string "source_branch", limit: 255, null: false
- t.integer "source_project_id", null: false
+ t.string "target_branch", null: false
+ t.string "source_branch", null: false
+ t.integer "source_project_id", null: false
t.integer "author_id"
t.integer "assignee_id"
- t.string "title", limit: 255
+ t.string "title"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "milestone_id"
- t.string "state", limit: 255
- t.string "merge_status", limit: 255
- t.integer "target_project_id", null: false
+ t.string "state"
+ t.string "merge_status"
+ t.integer "target_project_id", null: false
t.integer "iid"
t.text "description"
- t.integer "position", default: 0
+ t.integer "position", default: 0
t.datetime "locked_at"
t.integer "updated_by_id"
- t.string "merge_error", limit: 255
+ t.string "merge_error"
t.text "merge_params"
- t.boolean "merge_when_build_succeeds", default: false, null: false
+ t.boolean "merge_when_build_succeeds", default: false, null: false
t.integer "merge_user_id"
end
@@ -529,13 +530,13 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "merge_requests", ["title"], name: "index_merge_requests_on_title", using: :btree
create_table "milestones", force: :cascade do |t|
- t.string "title", limit: 255, null: false
- t.integer "project_id", null: false
+ t.string "title", null: false
+ t.integer "project_id", null: false
t.text "description"
t.date "due_date"
t.datetime "created_at"
t.datetime "updated_at"
- t.string "state", limit: 255
+ t.string "state"
t.integer "iid"
end
@@ -543,16 +544,17 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "milestones", ["due_date"], name: "index_milestones_on_due_date", using: :btree
add_index "milestones", ["project_id", "iid"], name: "index_milestones_on_project_id_and_iid", unique: true, using: :btree
add_index "milestones", ["project_id"], name: "index_milestones_on_project_id", using: :btree
+ add_index "milestones", ["title"], name: "index_milestones_on_title", using: :btree
create_table "namespaces", force: :cascade do |t|
- t.string "name", limit: 255, null: false
- t.string "path", limit: 255, null: false
+ t.string "name", null: false
+ t.string "path", null: false
t.integer "owner_id"
t.datetime "created_at"
t.datetime "updated_at"
- t.string "type", limit: 255
- t.string "description", limit: 255, default: "", null: false
- t.string "avatar", limit: 255
+ t.string "type"
+ t.string "description", default: "", null: false
+ t.string "avatar"
end
add_index "namespaces", ["created_at", "id"], name: "index_namespaces_on_created_at_and_id", using: :btree
@@ -563,19 +565,19 @@ ActiveRecord::Schema.define(version: 20160106164438) do
create_table "notes", force: :cascade do |t|
t.text "note"
- t.string "noteable_type", limit: 255
+ t.string "noteable_type"
t.integer "author_id"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "project_id"
- t.string "attachment", limit: 255
- t.string "line_code", limit: 255
- t.string "commit_id", limit: 255
+ t.string "attachment"
+ t.string "line_code"
+ t.string "commit_id"
t.integer "noteable_id"
- t.boolean "system", default: false, null: false
+ t.boolean "system", default: false, null: false
t.text "st_diff"
t.integer "updated_by_id"
- t.boolean "is_award", default: false, null: false
+ t.boolean "is_award", default: false, null: false
end
add_index "notes", ["author_id"], name: "index_notes_on_author_id", using: :btree
@@ -591,14 +593,14 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "notes", ["updated_at"], name: "index_notes_on_updated_at", using: :btree
create_table "oauth_access_grants", force: :cascade do |t|
- t.integer "resource_owner_id", null: false
- t.integer "application_id", null: false
- t.string "token", limit: 255, null: false
- t.integer "expires_in", null: false
- t.text "redirect_uri", null: false
- t.datetime "created_at", null: false
+ t.integer "resource_owner_id", null: false
+ t.integer "application_id", null: false
+ t.string "token", null: false
+ t.integer "expires_in", null: false
+ t.text "redirect_uri", null: false
+ t.datetime "created_at", null: false
t.datetime "revoked_at"
- t.string "scopes", limit: 255
+ t.string "scopes"
end
add_index "oauth_access_grants", ["token"], name: "index_oauth_access_grants_on_token", unique: true, using: :btree
@@ -606,12 +608,12 @@ ActiveRecord::Schema.define(version: 20160106164438) do
create_table "oauth_access_tokens", force: :cascade do |t|
t.integer "resource_owner_id"
t.integer "application_id"
- t.string "token", limit: 255, null: false
- t.string "refresh_token", limit: 255
+ t.string "token", null: false
+ t.string "refresh_token"
t.integer "expires_in"
t.datetime "revoked_at"
- t.datetime "created_at", null: false
- t.string "scopes", limit: 255
+ t.datetime "created_at", null: false
+ t.string "scopes"
end
add_index "oauth_access_tokens", ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true, using: :btree
@@ -619,15 +621,15 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "oauth_access_tokens", ["token"], name: "index_oauth_access_tokens_on_token", unique: true, using: :btree
create_table "oauth_applications", force: :cascade do |t|
- t.string "name", limit: 255, null: false
- t.string "uid", limit: 255, null: false
- t.string "secret", limit: 255, null: false
- t.text "redirect_uri", null: false
- t.string "scopes", limit: 255, default: "", null: false
+ t.string "name", null: false
+ t.string "uid", null: false
+ t.string "secret", null: false
+ t.text "redirect_uri", null: false
+ t.string "scopes", default: "", null: false
t.datetime "created_at"
t.datetime "updated_at"
t.integer "owner_id"
- t.string "owner_type", limit: 255
+ t.string "owner_type"
end
add_index "oauth_applications", ["owner_id", "owner_type"], name: "index_oauth_applications_on_owner_id_and_owner_type", using: :btree
@@ -639,39 +641,39 @@ ActiveRecord::Schema.define(version: 20160106164438) do
end
create_table "projects", force: :cascade do |t|
- t.string "name", limit: 255
- t.string "path", limit: 255
+ t.string "name"
+ t.string "path"
t.text "description"
t.datetime "created_at"
t.datetime "updated_at"
t.integer "creator_id"
- t.boolean "issues_enabled", default: true, null: false
- t.boolean "wall_enabled", default: true, null: false
- t.boolean "merge_requests_enabled", default: true, null: false
- t.boolean "wiki_enabled", default: true, null: false
+ t.boolean "issues_enabled", default: true, null: false
+ t.boolean "wall_enabled", default: true, null: false
+ t.boolean "merge_requests_enabled", default: true, null: false
+ t.boolean "wiki_enabled", default: true, null: false
t.integer "namespace_id"
- t.string "issues_tracker", limit: 255, default: "gitlab", null: false
- t.string "issues_tracker_id", limit: 255
- t.boolean "snippets_enabled", default: true, null: false
+ t.string "issues_tracker", default: "gitlab", null: false
+ t.string "issues_tracker_id"
+ t.boolean "snippets_enabled", default: true, null: false
t.datetime "last_activity_at"
- t.string "import_url", limit: 255
- t.integer "visibility_level", default: 0, null: false
- t.boolean "archived", default: false, null: false
- t.string "avatar", limit: 255
- t.string "import_status", limit: 255
- t.float "repository_size", default: 0.0
- t.integer "star_count", default: 0, null: false
- t.string "import_type", limit: 255
- t.string "import_source", limit: 255
- t.integer "commit_count", default: 0
+ t.string "import_url"
+ t.integer "visibility_level", default: 0, null: false
+ t.boolean "archived", default: false, null: false
+ t.string "avatar"
+ t.string "import_status"
+ t.float "repository_size", default: 0.0
+ t.integer "star_count", default: 0, null: false
+ t.string "import_type"
+ t.string "import_source"
+ t.integer "commit_count", default: 0
t.text "import_error"
t.integer "ci_id"
- t.boolean "builds_enabled", default: true, null: false
- t.boolean "shared_runners_enabled", default: true, null: false
+ t.boolean "builds_enabled", default: true, null: false
+ t.boolean "shared_runners_enabled", default: true, null: false
t.string "runners_token"
t.string "build_coverage_regex"
- t.boolean "build_allow_git_fetch", default: true, null: false
- t.integer "build_timeout", default: 3600, null: false
+ t.boolean "build_allow_git_fetch", default: true, null: false
+ t.integer "build_timeout", default: 3600, null: false
end
add_index "projects", ["builds_enabled", "shared_runners_enabled"], name: "index_projects_on_builds_enabled_and_shared_runners_enabled", using: :btree
@@ -687,17 +689,17 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "projects", ["visibility_level"], name: "index_projects_on_visibility_level", using: :btree
create_table "protected_branches", force: :cascade do |t|
- t.integer "project_id", null: false
- t.string "name", limit: 255, null: false
+ t.integer "project_id", null: false
+ t.string "name", null: false
t.datetime "created_at"
t.datetime "updated_at"
- t.boolean "developers_can_push", default: false, null: false
+ t.boolean "developers_can_push", default: false, null: false
end
add_index "protected_branches", ["project_id"], name: "index_protected_branches_on_project_id", using: :btree
create_table "releases", force: :cascade do |t|
- t.string "tag", limit: 255
+ t.string "tag"
t.text "description"
t.integer "project_id"
t.datetime "created_at"
@@ -710,30 +712,30 @@ ActiveRecord::Schema.define(version: 20160106164438) do
create_table "sent_notifications", force: :cascade do |t|
t.integer "project_id"
t.integer "noteable_id"
- t.string "noteable_type", limit: 255
+ t.string "noteable_type"
t.integer "recipient_id"
- t.string "commit_id", limit: 255
- t.string "reply_key", limit: 255, null: false
- t.string "line_code", limit: 255
+ t.string "commit_id"
+ t.string "reply_key", null: false
+ t.string "line_code"
end
add_index "sent_notifications", ["reply_key"], name: "index_sent_notifications_on_reply_key", unique: true, using: :btree
create_table "services", force: :cascade do |t|
- t.string "type", limit: 255
- t.string "title", limit: 255
+ t.string "type"
+ t.string "title"
t.integer "project_id"
t.datetime "created_at"
t.datetime "updated_at"
- t.boolean "active", default: false, null: false
+ t.boolean "active", default: false, null: false
t.text "properties"
- t.boolean "template", default: false
- t.boolean "push_events", default: true
- t.boolean "issues_events", default: true
- t.boolean "merge_requests_events", default: true
- t.boolean "tag_push_events", default: true
- t.boolean "note_events", default: true, null: false
- t.boolean "build_events", default: false, null: false
+ t.boolean "template", default: false
+ t.boolean "push_events", default: true
+ t.boolean "issues_events", default: true
+ t.boolean "merge_requests_events", default: true
+ t.boolean "tag_push_events", default: true
+ t.boolean "note_events", default: true, null: false
+ t.boolean "build_events", default: false, null: false
end
add_index "services", ["created_at", "id"], name: "index_services_on_created_at_and_id", using: :btree
@@ -741,16 +743,16 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "services", ["template"], name: "index_services_on_template", using: :btree
create_table "snippets", force: :cascade do |t|
- t.string "title", limit: 255
+ t.string "title"
t.text "content"
- t.integer "author_id", null: false
+ t.integer "author_id", null: false
t.integer "project_id"
t.datetime "created_at"
t.datetime "updated_at"
- t.string "file_name", limit: 255
+ t.string "file_name"
t.datetime "expires_at"
- t.string "type", limit: 255
- t.integer "visibility_level", default: 0, null: false
+ t.string "type"
+ t.integer "visibility_level", default: 0, null: false
end
add_index "snippets", ["author_id"], name: "index_snippets_on_author_id", using: :btree
@@ -763,7 +765,7 @@ ActiveRecord::Schema.define(version: 20160106164438) do
create_table "subscriptions", force: :cascade do |t|
t.integer "user_id"
t.integer "subscribable_id"
- t.string "subscribable_type", limit: 255
+ t.string "subscribable_type"
t.boolean "subscribed"
t.datetime "created_at"
t.datetime "updated_at"
@@ -774,10 +776,10 @@ ActiveRecord::Schema.define(version: 20160106164438) do
create_table "taggings", force: :cascade do |t|
t.integer "tag_id"
t.integer "taggable_id"
- t.string "taggable_type", limit: 255
+ t.string "taggable_type"
t.integer "tagger_id"
- t.string "tagger_type", limit: 255
- t.string "context", limit: 255
+ t.string "tagger_type"
+ t.string "context"
t.datetime "created_at"
end
@@ -785,67 +787,67 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "taggings", ["taggable_id", "taggable_type", "context"], name: "index_taggings_on_taggable_id_and_taggable_type_and_context", using: :btree
create_table "tags", force: :cascade do |t|
- t.string "name", limit: 255
- t.integer "taggings_count", default: 0
+ t.string "name"
+ t.integer "taggings_count", default: 0
end
add_index "tags", ["name"], name: "index_tags_on_name", unique: true, using: :btree
create_table "users", force: :cascade do |t|
- t.string "email", limit: 255, default: "", null: false
- t.string "encrypted_password", limit: 255, default: "", null: false
- t.string "reset_password_token", limit: 255
+ t.string "email", default: "", null: false
+ t.string "encrypted_password", default: "", null: false
+ t.string "reset_password_token"
t.datetime "reset_password_sent_at"
t.datetime "remember_created_at"
- t.integer "sign_in_count", default: 0
+ t.integer "sign_in_count", default: 0
t.datetime "current_sign_in_at"
t.datetime "last_sign_in_at"
- t.string "current_sign_in_ip", limit: 255
- t.string "last_sign_in_ip", limit: 255
- t.datetime "created_at"
- t.datetime "updated_at"
- t.string "name", limit: 255
- t.boolean "admin", default: false, null: false
- t.integer "projects_limit", default: 10
- t.string "skype", limit: 255, default: "", null: false
- t.string "linkedin", limit: 255, default: "", null: false
- t.string "twitter", limit: 255, default: "", null: false
- t.string "authentication_token", limit: 255
- t.integer "theme_id", default: 1, null: false
- t.string "bio", limit: 255
- t.integer "failed_attempts", default: 0
+ t.string "current_sign_in_ip"
+ t.string "last_sign_in_ip"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ t.string "name"
+ t.boolean "admin", default: false, null: false
+ t.integer "projects_limit", default: 10
+ t.string "skype", default: "", null: false
+ t.string "linkedin", default: "", null: false
+ t.string "twitter", default: "", null: false
+ t.string "authentication_token"
+ t.integer "theme_id", default: 1, null: false
+ t.string "bio"
+ t.integer "failed_attempts", default: 0
t.datetime "locked_at"
- t.string "username", limit: 255
- t.boolean "can_create_group", default: true, null: false
- t.boolean "can_create_team", default: true, null: false
- t.string "state", limit: 255
- t.integer "color_scheme_id", default: 1, null: false
- t.integer "notification_level", default: 1, null: false
+ t.string "username"
+ t.boolean "can_create_group", default: true, null: false
+ t.boolean "can_create_team", default: true, null: false
+ t.string "state"
+ t.integer "color_scheme_id", default: 1, null: false
+ t.integer "notification_level", default: 1, null: false
t.datetime "password_expires_at"
t.integer "created_by_id"
t.datetime "last_credential_check_at"
- t.string "avatar", limit: 255
- t.string "confirmation_token", limit: 255
+ t.string "avatar"
+ t.string "confirmation_token"
t.datetime "confirmed_at"
t.datetime "confirmation_sent_at"
- t.string "unconfirmed_email", limit: 255
- t.boolean "hide_no_ssh_key", default: false
- t.string "website_url", limit: 255, default: "", null: false
- t.string "notification_email", limit: 255
- t.boolean "hide_no_password", default: false
- t.boolean "password_automatically_set", default: false
- t.string "location", limit: 255
- t.string "encrypted_otp_secret", limit: 255
- t.string "encrypted_otp_secret_iv", limit: 255
- t.string "encrypted_otp_secret_salt", limit: 255
- t.boolean "otp_required_for_login", default: false, null: false
+ t.string "unconfirmed_email"
+ t.boolean "hide_no_ssh_key", default: false
+ t.string "website_url", default: "", null: false
+ t.string "notification_email"
+ t.boolean "hide_no_password", default: false
+ t.boolean "password_automatically_set", default: false
+ t.string "location"
+ t.string "encrypted_otp_secret"
+ t.string "encrypted_otp_secret_iv"
+ t.string "encrypted_otp_secret_salt"
+ t.boolean "otp_required_for_login", default: false, null: false
t.text "otp_backup_codes"
- t.string "public_email", limit: 255, default: "", null: false
- t.integer "dashboard", default: 0
- t.integer "project_view", default: 0
+ t.string "public_email", default: "", null: false
+ t.integer "dashboard", default: 0
+ t.integer "project_view", default: 0
t.integer "consumed_timestep"
- t.integer "layout", default: 0
- t.boolean "hide_project_limit", default: false
+ t.integer "layout", default: 0
+ t.boolean "hide_project_limit", default: false
t.string "unlock_token"
t.datetime "otp_grace_period_started_at"
end
@@ -872,19 +874,19 @@ ActiveRecord::Schema.define(version: 20160106164438) do
add_index "users_star_projects", ["user_id"], name: "index_users_star_projects_on_user_id", using: :btree
create_table "web_hooks", force: :cascade do |t|
- t.string "url", limit: 255
+ t.string "url"
t.integer "project_id"
t.datetime "created_at"
t.datetime "updated_at"
- t.string "type", limit: 255, default: "ProjectHook"
+ t.string "type", default: "ProjectHook"
t.integer "service_id"
- t.boolean "push_events", default: true, null: false
- t.boolean "issues_events", default: false, null: false
- t.boolean "merge_requests_events", default: false, null: false
- t.boolean "tag_push_events", default: false
- t.boolean "note_events", default: false, null: false
- t.boolean "enable_ssl_verification", default: true
- t.boolean "build_events", default: false, null: false
+ t.boolean "push_events", default: true, null: false
+ t.boolean "issues_events", default: false, null: false
+ t.boolean "merge_requests_events", default: false, null: false
+ t.boolean "tag_push_events", default: false
+ t.boolean "note_events", default: false, null: false
+ t.boolean "enable_ssl_verification", default: true
+ t.boolean "build_events", default: false, null: false
end
add_index "web_hooks", ["created_at", "id"], name: "index_web_hooks_on_created_at_and_id", using: :btree
diff --git a/doc/README.md b/doc/README.md
index 25fe3abcb9a..7d4f84857e0 100644
--- a/doc/README.md
+++ b/doc/README.md
@@ -70,6 +70,8 @@
## Contributor documentation
+- [Documentation styleguide](development/doc_styleguide.md) Use this styleguide if you are
+ contributing to documentation.
- [Development](development/README.md) Explains the architecture and the guidelines for shell commands.
- [Legal](legal/README.md) Contributor license agreements.
- [Release](release/README.md) How to make the monthly and security releases.
diff --git a/doc/api/projects.md b/doc/api/projects.md
index 37d74216c1b..241229221db 100644
--- a/doc/api/projects.md
+++ b/doc/api/projects.md
@@ -76,7 +76,10 @@ Parameters:
"updated_at": "2013-09-30T13: 46: 02Z"
},
"archived": false,
- "avatar_url": "http://example.com/uploads/project/avatar/4/uploads/avatar.png"
+ "avatar_url": "http://example.com/uploads/project/avatar/4/uploads/avatar.png",
+ "shared_runners_enabled": true,
+ "forks_count": 0,
+ "star_count": 0
},
{
"id": 6,
@@ -129,7 +132,11 @@ Parameters:
}
},
"archived": false,
- "avatar_url": null
+ "avatar_url": null,
+ "shared_runners_enabled": true,
+ "forks_count": 0,
+ "star_count": 0,
+ "runners_token": "b8547b1dc37721d05889db52fa2f02"
}
]
```
@@ -244,7 +251,11 @@ Parameters:
}
},
"archived": false,
- "avatar_url": "http://example.com/uploads/project/avatar/3/uploads/avatar.png"
+ "avatar_url": "http://example.com/uploads/project/avatar/3/uploads/avatar.png",
+ "shared_runners_enabled": true,
+ "forks_count": 0,
+ "star_count": 0,
+ "runners_token": "b8bc4a7a29eb76ea83cf79e4908c2b"
}
```
diff --git a/doc/ci/docker/using_docker_images.md b/doc/ci/docker/using_docker_images.md
index 31458d61674..63fe840b369 100644
--- a/doc/ci/docker/using_docker_images.md
+++ b/doc/ci/docker/using_docker_images.md
@@ -174,7 +174,7 @@ The alias hostname for the service is made from the image name following these
rules:
1. Everything after `:` is stripped
-2. Backslash (`/`) is replaced with double underscores (`__`)
+2. Slash (`/`) is replaced with double underscores (`__`)
## Configuring services
diff --git a/doc/development/doc_styleguide.md b/doc/development/doc_styleguide.md
new file mode 100644
index 00000000000..0bd32b78201
--- /dev/null
+++ b/doc/development/doc_styleguide.md
@@ -0,0 +1,231 @@
+# Documentation styleguide
+
+This styleguide recommends best practices to improve documentation and to keep
+it organized and easy to find.
+
+## Naming
+
+- When creating a new document and it has more than one word in its name,
+ make sure to use underscores instead of spaces or dashes (`-`). For example,
+ a proper naming would be `import_projects_from_github.md`. The same rule
+ applies to images.
+
+## Text
+
+- Split up long lines, this makes it much easier to review and edit. Only
+ double line breaks are shown as a full line break in [GitLab markdown][gfm].
+ 80-100 characters is a good line length
+- Make sure that the documentation is added in the correct directory and that
+ there's a link to it somewhere useful
+- Do not duplicate information
+- Be brief and clear
+- Unless there's a logical reason not to, add documents in alphabetical order
+- Write in US English
+- Use [single spaces][] instead of double spaces
+
+## Formatting
+
+- Use dashes (`-`) for unordered lists instead of asterisks (`*`)
+- Use the number one (`1`) for ordered lists
+- Use underscores (`_`) to mark a word or text in italics
+- Use double asterisks (`**`) to mark a word or text in bold
+- When using lists, prefer not to end each item with a period. You can use
+ them if there are multiple sentences, just keep the last sentence without
+ a period
+
+## Headings
+
+- Add only one H1 title in each document, by adding `#` at the beginning of
+ it (when using markdown). For subheadings, use `##`, `###` and so on
+- Avoid putting numbers in headings. Numbers shift, hence documentation anchor
+ links shift too, which eventually leads to dead links. If you think it is
+ compelling to add numbers in headings, make sure to at least discuss it with
+ someone in the Merge Request
+- When introducing a new document, be careful for the headings to be
+ grammatically and syntactically correct. It is advised to mention one or all
+ of the following GitLab members for a review: `@axil`, `@rspeicher`,
+ `@dblessing`, `@ashleys`, `@nearlythere`. This is to ensure that no document
+ with wrong heading is going live without an audit, thus preventing dead links
+ and redirection issues when corrected
+- Leave exactly one newline after a heading
+
+## Links
+
+- If a link makes the paragraph to span across multiple lines, do not use
+ the regular Markdown approach: `[Text](https://example.com)`. Instead use
+ `[Text][identifier]` and at the very bottom of the document add:
+ `[identifier]: https://example.com`. This is another way to create Markdown
+ links which keeps the document clear and concise. Bonus points if you also
+ add an alternative text: `[identifier]: https://example.com "Alternative text"`
+ that appears when hovering your mouse on a link
+
+## Images
+
+- Place images in a separate directory named `img/` in the same directory where
+ the `.md` document that you're working on is located. Always prepend their
+ names with the name of the document that they will be included in. For
+ example, if there is a document called `twitter.md`, then a valid image name
+ could be `twitter_login_screen.png`.
+- Images should have a specific, non-generic name that will differentiate them.
+- Keep all file names in lower case.
+- Consider using PNG images instead of JPEG.
+
+Inside the document:
+
+- The Markdown way of using an image inside a document is:
+ `![Proper description what the image is about](img/document_image_title.png)`
+- Always use a proper description for what the image is about. That way, when a
+ browser fails to show the image, this text will be used as an alternative
+ description
+- If there are consecutive images with little text between them, always add
+ three dashes (`---`) between the image and the text to create a horizontal
+ line for better clarity
+- If a heading is placed right after an image, always add three dashes (`---`)
+ between the image and the heading
+
+## Notes
+
+- Notes should be in italics with the word `Note:` being bold. Use this form:
+ `_**Note:** This is something to note._`. If the note spans across multiple
+ lines it's OK to split the line.
+
+## New features
+
+- Every piece of documentation that comes with a new feature should declare the
+ GitLab version that feature got introduced. Right below the heading add a
+ note: `_**Note:** This feature was introduced in GitLab 8.3_`
+- If possible every feature should have a link to the MR that introduced it.
+ The above note would be then transformed to:
+ `_**Note:** This feature was [introduced][ce-1242] in GitLab 8.3_`, where
+ the [link identifier](#links) is named after the repository (CE) and the MR
+ number
+- If the feature is only in GitLab EE, don't forget to mention it, like:
+ `_**Note:** This feature was introduced in GitLab EE 8.3_`. Otherwise, leave
+ this mention out
+
+## API
+
+Here is a list of must-have items. Use them in the exact order that appears
+on this document. Further explanation is given below.
+
+- Every method must have the REST API request. For example:
+
+ ```
+ GET /projects/:id/repository/branches
+ ```
+
+- Every method must have a detailed
+ [description of the parameters](#method-description).
+- Every method must have a cURL example.
+- Every method must have a response body (in JSON format).
+
+### Method description
+
+Use the following table headers to describe the methods. Attributes should
+always be in code blocks using backticks (`).
+
+```
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+```
+
+Rendered example:
+
+| Attribute | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `user` | string | yes | The GitLab username |
+
+### cURL commands
+
+- Use `https://gitlab.example.com/api/v3/` as an endpoint.
+- Wherever needed use this private token: `9koXpg98eAheJpvBs5tK`.
+- Always put the request first. `GET` is the default so you don't have to
+ include it.
+- Use double quotes to the URL when it includes additional parameters.
+- Prefer to use examples using the private token and don't pass data of
+ username and password.
+
+| Methods | Description |
+| ------- | ----------- |
+| `-H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK"` | Use this method as is, whenever authentication needed |
+| `-X POST` | Use this method when creating new objects |
+| `-X PUT` | Use this method when updating existing objects |
+| `-X DELETE` | Use this method when removing existing objects |
+
+### cURL Examples
+
+Below is a set of [cURL][] examples that you can use in the API documentation.
+
+#### Simple cURL command
+
+Get the details of a group:
+
+```bash
+curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v3/groups/gitlab-org
+```
+
+#### cURL example with parameters passed in the URL
+
+Create a new project under the authenticated user's namespace:
+
+```bash
+curl -X POST -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects?name=foo"
+```
+
+#### Post data using cURL's --data
+
+Instead of using `-X POST` and appending the parameters to the URI, you can use
+cURL's `--data` option. The example below will create a new project `foo` under
+the authenticated user's namespace.
+
+```bash
+curl --data "name=foo" -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects"
+```
+
+#### Post data using JSON content
+
+_**Note:** In this example we create a new group. Watch carefully the single
+and double quotes._
+
+```bash
+curl -X POST -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" -H "Content-Type: application/json" --data '{"path": "my-group", "name": "My group"}' https://gitlab.example.com/api/v3/groups
+```
+
+#### Post data using form-data
+
+Instead of using JSON or urlencode you can use multipart/form-data which
+properly handles data encoding:
+
+```bash
+curl -X POST -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" -F "title=ssh-key" -F "key=ssh-rsa AAAAB3NzaC1yc2EA..." https://gitlab.example.com/api/v3/users/25/keys
+```
+
+The above example is run by and administrator and will add an SSH public key
+titled ssh-key to user's account which has an id of 25.
+
+#### Escape special characters
+
+Spaces or slashes (`/`) may sometimes result to errors, thus it is recommended
+to escape them when possible. In the example below we create a new issue which
+contains spaces in its title. Observe how spaces are escaped using the `%20`
+ASCII code.
+
+```bash
+curl -X POST -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/42/issues?title=Hello%20Dude"
+```
+
+Use `%2F` for slashes (`/`).
+
+#### Pass arrays to API calls
+
+The GitLab API sometimes accepts arrays of strings or integers. For example, to
+restrict the sign-up e-mail domains of a GitLab instance to `*.example.com` and
+`example.net`, you would do something like this:
+
+```bash
+curl -X PUT -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" -d "restricted_signup_domains[]=*.example.com" -d "restricted_signup_domains[]=example.net" https://gitlab.example.com/api/v3/application/settings
+```
+
+[cURL]: http://curl.haxx.se/ "cURL website"
+[single spaces]: http://www.slate.com/articles/technology/technology/2011/01/space_invaders.html
+[gfm]: http://doc.gitlab.com/ce/markdown/markdown.html#newlines "GitLab flavored markdown documentation"
diff --git a/doc/install/installation.md b/doc/install/installation.md
index dd59733cf4d..e645445df2a 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -231,9 +231,9 @@ sudo usermod -aG redis git
### Clone the Source
# Clone GitLab repository
- sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 8-3-stable gitlab
+ sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 8-4-stable gitlab
-**Note:** You can change `8-3-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
+**Note:** You can change `8-4-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
### Configure It
@@ -348,7 +348,7 @@ GitLab Shell is an SSH access and repository management software developed speci
cd /home/git
sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-workhorse.git
cd gitlab-workhorse
- sudo -u git -H git checkout 0.5.1
+ sudo -u git -H git checkout 0.5.4
sudo -u git -H make
### Initialize Database and Activate Advanced Features
diff --git a/doc/integration/ldap.md b/doc/integration/ldap.md
index 845f588f913..f256477196b 100644
--- a/doc/integration/ldap.md
+++ b/doc/integration/ldap.md
@@ -48,6 +48,11 @@ main: # 'main' is the GitLab 'provider ID' of this LDAP server
bind_dn: '_the_full_dn_of_the_user_you_will_bind_with'
password: '_the_password_of_the_bind_user'
+ # Set a timeout, in seconds, for LDAP queries. This helps avoid blocking
+ # a request if the LDAP server becomes unresponsive.
+ # A value of 0 means there is no timeout.
+ timeout: 10
+
# This setting specifies if LDAP server is Active Directory LDAP server.
# For non AD servers it skips the AD specific queries.
# If your LDAP server is not AD, set this to false.
diff --git a/doc/integration/shibboleth.md b/doc/integration/shibboleth.md
index 6258e5f1030..a0be3dd4e5c 100644
--- a/doc/integration/shibboleth.md
+++ b/doc/integration/shibboleth.md
@@ -1,8 +1,8 @@
# Shibboleth OmniAuth Provider
-This documentation is for enabling shibboleth with gitlab-omnibus package.
+This documentation is for enabling shibboleth with omnibus-gitlab package.
-In order to enable Shibboleth support in gitlab we need to use Apache instead of Nginx (It may be possible to use Nginx, however I did not found way to easily configure Nginx that is bundled in gitlab-omnibus package). Apache uses mod_shib2 module for shibboleth authentication and can pass attributes as headers to omniauth-shibboleth provider.
+In order to enable Shibboleth support in gitlab we need to use Apache instead of Nginx (It may be possible to use Nginx, however I did not found way to easily configure Nginx that is bundled in omnibus-gitlab package). Apache uses mod_shib2 module for shibboleth authentication and can pass attributes as headers to omniauth-shibboleth provider.
To enable the Shibboleth OmniAuth provider you must:
diff --git a/doc/release/patch.md b/doc/release/patch.md
index 3022e375aca..1c921439156 100644
--- a/doc/release/patch.md
+++ b/doc/release/patch.md
@@ -24,7 +24,7 @@ Use the following template:
- Picked into respective `stable` branches:
- [ ] Merge `x-y-stable` into `x-y-stable-ee`
- [ ] release-tools: `x.y.z`
-- gitlab-omnibus
+- omnibus-gitlab
- [ ] `x.y.z+ee.0`
- [ ] `x.y.z+ce.0`
- [ ] Deploy
diff --git a/doc/system_hooks/system_hooks.md b/doc/system_hooks/system_hooks.md
index 49f98ded046..612376e3a49 100644
--- a/doc/system_hooks/system_hooks.md
+++ b/doc/system_hooks/system_hooks.md
@@ -96,6 +96,7 @@ X-Gitlab-Event: System Hook
"project_path_with_namespace": "jsmith/storecloud",
"user_email": "johnsmith@gmail.com",
"user_name": "John Smith",
+ "user_username": "johnsmith",
"user_id": 41,
"project_visibility": "private",
}
@@ -115,6 +116,7 @@ X-Gitlab-Event: System Hook
"project_path_with_namespace": "jsmith/storecloud",
"user_email": "johnsmith@gmail.com",
"user_name": "John Smith",
+ "user_username": "johnsmith",
"user_id": 41,
"project_visibility": "private",
}
@@ -129,6 +131,7 @@ X-Gitlab-Event: System Hook
"email": "js@gitlabhq.com",
"event_name": "user_create",
"name": "John Smith",
+ "username": "js",
"user_id": 41
}
```
@@ -142,6 +145,7 @@ X-Gitlab-Event: System Hook
"email": "js@gitlabhq.com",
"event_name": "user_destroy",
"name": "John Smith",
+ "username": "js",
"user_id": 41
}
```
@@ -215,6 +219,7 @@ X-Gitlab-Event: System Hook
"group_path": "storecloud",
"user_email": "johnsmith@gmail.com",
"user_name": "John Smith",
+ "user_username": "johnsmith",
"user_id": 41
}
```
@@ -231,6 +236,7 @@ X-Gitlab-Event: System Hook
"group_path": "storecloud",
"user_email": "johnsmith@gmail.com",
"user_name": "John Smith",
+ "user_username": "johnsmith",
"user_id": 41
}
```
diff --git a/doc/update/8.2-to-8.3.md b/doc/update/8.2-to-8.3.md
index 3748941b781..2ca4e1f3770 100644
--- a/doc/update/8.2-to-8.3.md
+++ b/doc/update/8.2-to-8.3.md
@@ -78,7 +78,7 @@ which should already be on your system from GitLab 8.1.
```bash
cd /home/git/gitlab-workhorse
sudo -u git -H git fetch --all
-sudo -u git -H git checkout 0.5.1
+sudo -u git -H git checkout 0.5.4
sudo -u git -H make
```
diff --git a/doc/update/8.3-to-8.4.md b/doc/update/8.3-to-8.4.md
new file mode 100644
index 00000000000..1cbeab3eca3
--- /dev/null
+++ b/doc/update/8.3-to-8.4.md
@@ -0,0 +1,148 @@
+# From 8.3 to 8.4
+
+### 1. Stop server
+
+ sudo service gitlab stop
+
+### 2. Backup
+
+```bash
+cd /home/git/gitlab
+sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
+```
+
+### 3. Get latest code
+
+```bash
+sudo -u git -H git fetch --all
+sudo -u git -H git checkout -- db/schema.rb # local changes will be restored automatically
+```
+
+For GitLab Community Edition:
+
+```bash
+sudo -u git -H git checkout 8-4-stable
+```
+
+OR
+
+For GitLab Enterprise Edition:
+
+```bash
+sudo -u git -H git checkout 8-4-stable-ee
+```
+
+### 4. Update gitlab-shell
+
+```bash
+cd /home/git/gitlab-shell
+sudo -u git -H git fetch --all
+sudo -u git -H git checkout v2.6.9
+```
+
+### 5. Update gitlab-workhorse
+
+Install and compile gitlab-workhorse. This requires [Go 1.5](https://golang.org/dl)
+which should already be on your system from GitLab 8.1.
+
+```bash
+cd /home/git/gitlab-workhorse
+sudo -u git -H git fetch --all
+sudo -u git -H git checkout 0.5.4
+sudo -u git -H make
+```
+
+### 6. Install libs, migrations, etc.
+
+```bash
+cd /home/git/gitlab
+
+# MySQL installations (note: the line below states '--without postgres')
+sudo -u git -H bundle install --without postgres development test --deployment
+
+# PostgreSQL installations (note: the line below states '--without mysql')
+sudo -u git -H bundle install --without mysql development test --deployment
+
+# Run database migrations
+sudo -u git -H bundle exec rake db:migrate RAILS_ENV=production
+
+# Clean up assets and cache
+sudo -u git -H bundle exec rake assets:clean assets:precompile cache:clear RAILS_ENV=production
+
+```
+
+### 7. Update configuration files
+
+#### New configuration options for `gitlab.yml`
+
+There are new configuration options available for [`gitlab.yml`](config/gitlab.yml.example). View them with the command below and apply them manually to your current `gitlab.yml`:
+
+```sh
+git diff origin/8-3-stable:config/gitlab.yml.example origin/8-4-stable:config/gitlab.yml.example
+```
+
+#### Nginx configuration
+
+GitLab 8.3 introduced major changes in the NGINX configuration. Ensure you're
+still up-to-date with the latest changes:
+
+```sh
+# For HTTPS configurations
+git diff origin/8-3-stable:lib/support/nginx/gitlab-ssl origin/8-4-stable:lib/support/nginx/gitlab-ssl
+
+# For HTTP configurations
+git diff origin/8-3-stable:lib/support/nginx/gitlab origin/8-4-stable:lib/support/nginx/gitlab
+```
+
+If you are using Apache instead of NGINX please see the updated [Apache templates].
+Also note that because Apache does not support upstreams behind Unix sockets you
+will need to let gitlab-workhorse listen on a TCP port. You can do this
+via [/etc/default/gitlab].
+
+[Apache templates]: https://gitlab.com/gitlab-org/gitlab-recipes/tree/master/web-server/apache
+[/etc/default/gitlab]: https://gitlab.com/gitlab-org/gitlab-ce/blob/8-4-stable/lib/support/init.d/gitlab.default.example#L34
+
+#### Init script
+
+We updated the init script for GitLab in order to pass new
+configuration options to gitlab-workhorse. We let gitlab-workhorse
+connect to the Rails application via a Unix domain socket and we tell
+it where the 'public' directory of GitLab is.
+
+```
+cd /home/git/gitlab
+sudo cp lib/support/init.d/gitlab /etc/init.d/gitlab
+```
+
+### 8. Start application
+
+ sudo service gitlab start
+ sudo service nginx restart
+
+### 9. Check application status
+
+Check if GitLab and its environment are configured correctly:
+
+ sudo -u git -H bundle exec rake gitlab:env:info RAILS_ENV=production
+
+To make sure you didn't miss anything run a more thorough check:
+
+ sudo -u git -H bundle exec rake gitlab:check RAILS_ENV=production
+
+If all items are green, then congratulations, the upgrade is complete!
+
+## Things went south? Revert to previous version (8.3)
+
+### 1. Revert the code to the previous version
+
+Follow the [upgrade guide from 8.2 to 8.3](8.2-to-8.3.md), except for the
+database migration (the backup is already migrated to the previous version).
+
+### 2. Restore from the backup
+
+```bash
+cd /home/git/gitlab
+sudo -u git -H bundle exec rake gitlab:backup:restore RAILS_ENV=production
+```
+
+If you have more than one backup `*.tar` file(s) please add `BACKUP=timestamp_of_backup` to the command above.
diff --git a/doc/update/patch_versions.md b/doc/update/patch_versions.md
index c19ee49f9e0..a10e62877ba 100644
--- a/doc/update/patch_versions.md
+++ b/doc/update/patch_versions.md
@@ -48,6 +48,7 @@ sudo -u git -H git checkout v`cat /home/git/gitlab/GITLAB_SHELL_VERSION` -b v`ca
cd /home/git/gitlab-workhorse
sudo -u git -H git fetch
sudo -u git -H git checkout `cat /home/git/gitlab/GITLAB_WORKHORSE_VERSION` -b `cat /home/git/gitlab/GITLAB_WORKHORSE_VERSION`
+sudo -u git -H make
```
### 5. Install libs, migrations, etc.
diff --git a/doc_styleguide.md b/doc_styleguide.md
index cceb449a854..05ff46323ac 100644
--- a/doc_styleguide.md
+++ b/doc_styleguide.md
@@ -1,26 +1,3 @@
# Documentation styleguide
-This styleguide recommends best practices to improve documentation and to keep it organized and easy to find.
-
-## Text
-
-- Split up long lines, this makes it much easier to review and edit. Only
-double line breaks are shown as a full line break in markdown. 80 characters
-is a good line length.
-- For subtitles, make sure to start with the largest and go down, meaning:
-`#` for the title, `##` for subtitles and `###` for subtitles of the subtitles, etc.
-- Make sure that the documentation is added in the correct directory and that there's a link to it somewhere useful.
-- Add only one H1 or title in each document, by adding '#' at the begining of it (when using markdown).
-For subtitles, use '##', '###' and so on.
-- Do not duplicate information.
-- Be brief and clear.
-- Whenever it applies, add documents in alphabetical order.
-- Write in US English
-- Use [single spaces](http://www.slate.com/articles/technology/technology/2011/01/space_invaders.html) instead of double spaces.
-
-## Images
-
-- Create a directory to store the images with the specific name of the document where the images belong.
-It could be in the same directory where the .md document that you're working on is located.
-- Images should have a specific, non-generic name that will differentiate them.
-- Keep all file names in lower case. \ No newline at end of file
+Moved to [development/doc_styleguide](doc/development/doc_styleguide.md).
diff --git a/lib/api/entities.rb b/lib/api/entities.rb
index f0816a46529..b403d3c5032 100644
--- a/lib/api/entities.rb
+++ b/lib/api/entities.rb
@@ -71,6 +71,7 @@ module API
expose :avatar_url
expose :star_count, :forks_count
expose :open_issues_count, if: lambda { |project, options| project.issues_enabled? && project.default_issues_tracker? }
+ expose :runners_token, if: lambda { |_project, options| options[:user_can_admin_project] }
end
class ProjectMember < UserBasic
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 8b1390e3289..71bb342f844 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -69,7 +69,8 @@ module API
# Example Request:
# GET /projects/:id
get ":id" do
- present user_project, with: Entities::ProjectWithAccess, user: current_user
+ present user_project, with: Entities::ProjectWithAccess, user: current_user,
+ user_can_admin_project: can?(current_user, :admin_project, user_project)
end
# Get events for a single project
@@ -118,7 +119,8 @@ module API
attrs = map_public_to_visibility_level(attrs)
@project = ::Projects::CreateService.new(current_user, attrs).execute
if @project.saved?
- present @project, with: Entities::Project
+ present @project, with: Entities::Project,
+ user_can_admin_project: can?(current_user, :admin_project, @project)
else
if @project.errors[:limit_reached].present?
error!(@project.errors[:limit_reached], 403)
@@ -163,7 +165,8 @@ module API
attrs = map_public_to_visibility_level(attrs)
@project = ::Projects::CreateService.new(user, attrs).execute
if @project.saved?
- present @project, with: Entities::Project
+ present @project, with: Entities::Project,
+ user_can_admin_project: can?(current_user, :admin_project, @project)
else
render_validation_error!(@project)
end
@@ -182,8 +185,9 @@ module API
if @forked_project.errors.any?
conflict!(@forked_project.errors.messages)
else
- present @forked_project, with: Entities::Project
- end
+ present @forked_project, with: Entities::Project,
+ user_can_admin_project: can?(current_user, :admin_project, @forked_project)
+ end
end
# Update an existing project
@@ -229,7 +233,8 @@ module API
if user_project.errors.any?
render_validation_error!(user_project)
else
- present user_project, with: Entities::Project
+ present user_project, with: Entities::Project,
+ user_can_admin_project: can?(current_user, :admin_project, user_project)
end
end
diff --git a/lib/banzai/filter/reference_filter.rb b/lib/banzai/filter/reference_filter.rb
index 7198a8b03e2..5dd6d2fe3c7 100644
--- a/lib/banzai/filter/reference_filter.rb
+++ b/lib/banzai/filter/reference_filter.rb
@@ -133,7 +133,7 @@ module Banzai
next unless link && text
- link = URI.decode(link)
+ link = CGI.unescape(link)
# Ignore ending punctionation like periods or commas
next unless link == text && text =~ /\A#{pattern}/
@@ -170,7 +170,7 @@ module Banzai
text = node.text
next unless link && text
- link = URI.decode(link)
+ link = CGI.unescape(link)
next unless link && link =~ /\A#{pattern}\z/
html = yield link, text
diff --git a/lib/gitlab/gitlab_import/importer.rb b/lib/gitlab/gitlab_import/importer.rb
index e24b94d6159..59926084d07 100644
--- a/lib/gitlab/gitlab_import/importer.rb
+++ b/lib/gitlab/gitlab_import/importer.rb
@@ -12,7 +12,7 @@ module Gitlab
end
def execute
- project_identifier = URI.encode(project.import_source, '/')
+ project_identifier = CGI.escape(project.import_source, '/')
#Issues && Comments
issues = client.issues(project_identifier)
diff --git a/lib/gitlab/ldap/access.rb b/lib/gitlab/ldap/access.rb
index c438a3d167b..b2bdbc10d7f 100644
--- a/lib/gitlab/ldap/access.rb
+++ b/lib/gitlab/ldap/access.rb
@@ -5,7 +5,7 @@
module Gitlab
module LDAP
class Access
- attr_reader :adapter, :provider, :user
+ attr_reader :provider, :user
def self.open(user, &block)
Gitlab::LDAP::Adapter.open(user.ldap_identity.provider) do |adapter|
@@ -32,7 +32,7 @@ module Gitlab
end
def allowed?
- if Gitlab::LDAP::Person.find_by_dn(user.ldap_identity.extern_uid, adapter)
+ if ldap_user
return true unless ldap_config.active_directory
# Block user in GitLab if he/she was blocked in AD
@@ -59,6 +59,10 @@ module Gitlab
def ldap_config
Gitlab::LDAP::Config.new(provider)
end
+
+ def ldap_user
+ @ldap_user ||= Gitlab::LDAP::Person.find_by_dn(user.ldap_identity.extern_uid, adapter)
+ end
end
end
end
diff --git a/lib/gitlab/ldap/adapter.rb b/lib/gitlab/ldap/adapter.rb
index 577a890a7d9..df65179bfea 100644
--- a/lib/gitlab/ldap/adapter.rb
+++ b/lib/gitlab/ldap/adapter.rb
@@ -70,19 +70,25 @@ module Gitlab
end
def ldap_search(*args)
- results = ldap.search(*args)
+ # Net::LDAP's `time` argument doesn't work. Use Ruby `Timeout` instead.
+ Timeout.timeout(config.timeout) do
+ results = ldap.search(*args)
- if results.nil?
- response = ldap.get_operation_result
+ if results.nil?
+ response = ldap.get_operation_result
- unless response.code.zero?
- Rails.logger.warn("LDAP search error: #{response.message}")
- end
+ unless response.code.zero?
+ Rails.logger.warn("LDAP search error: #{response.message}")
+ end
- []
- else
- results
+ []
+ else
+ results
+ end
end
+ rescue Timeout::Error
+ Rails.logger.warn("LDAP search timed out after #{config.timeout} seconds")
+ []
end
end
end
diff --git a/lib/gitlab/ldap/config.rb b/lib/gitlab/ldap/config.rb
index 101a3285f4b..aff7ccb157f 100644
--- a/lib/gitlab/ldap/config.rb
+++ b/lib/gitlab/ldap/config.rb
@@ -88,6 +88,10 @@ module Gitlab
options['attributes']
end
+ def timeout
+ options['timeout'].to_i
+ end
+
protected
def base_config
Gitlab.config.ldap
diff --git a/lib/gitlab/metrics.rb b/lib/gitlab/metrics.rb
index 44356a0e42c..88a265c6af2 100644
--- a/lib/gitlab/metrics.rb
+++ b/lib/gitlab/metrics.rb
@@ -13,7 +13,8 @@ module Gitlab
timeout: current_application_settings[:metrics_timeout],
method_call_threshold: current_application_settings[:metrics_method_call_threshold],
host: current_application_settings[:metrics_host],
- port: current_application_settings[:metrics_port]
+ port: current_application_settings[:metrics_port],
+ sample_interval: current_application_settings[:metrics_sample_interval] || 15
}
end
@@ -36,20 +37,6 @@ module Gitlab
@pool
end
- # Returns a relative path and line number based on the last application call
- # frame.
- def self.last_relative_application_frame
- frame = caller_locations.find do |l|
- l.path.start_with?(RAILS_ROOT) && !l.path.start_with?(METRICS_ROOT)
- end
-
- if frame
- return frame.path.sub(PATH_REGEX, ''), frame.lineno
- else
- return nil, nil
- end
- end
-
def self.submit_metrics(metrics)
prepared = prepare_metrics(metrics)
diff --git a/lib/gitlab/metrics/rack_middleware.rb b/lib/gitlab/metrics/rack_middleware.rb
index e7a2f26d48b..6f179789d3e 100644
--- a/lib/gitlab/metrics/rack_middleware.rb
+++ b/lib/gitlab/metrics/rack_middleware.rb
@@ -39,10 +39,8 @@ module Gitlab
end
def tag_controller(trans, env)
- controller = env[CONTROLLER_KEY]
- label = "#{controller.class.name}##{controller.action_name}"
-
- trans.add_tag(:action, label)
+ controller = env[CONTROLLER_KEY]
+ trans.action = "#{controller.class.name}##{controller.action_name}"
end
end
end
diff --git a/lib/gitlab/metrics/sampler.rb b/lib/gitlab/metrics/sampler.rb
index 1ea425bc904..fc709222a9b 100644
--- a/lib/gitlab/metrics/sampler.rb
+++ b/lib/gitlab/metrics/sampler.rb
@@ -7,9 +7,14 @@ module Gitlab
# statistics, etc.
class Sampler
# interval - The sampling interval in seconds.
- def initialize(interval = 15)
- @interval = interval
- @metrics = []
+ def initialize(interval = Metrics.settings[:sample_interval])
+ interval_half = interval.to_f / 2
+
+ @interval = interval
+ @interval_steps = (-interval_half..interval_half).step(0.1).to_a
+ @last_step = nil
+
+ @metrics = []
@last_minor_gc = Delta.new(GC.stat[:minor_gc_count])
@last_major_gc = Delta.new(GC.stat[:major_gc_count])
@@ -26,7 +31,7 @@ module Gitlab
Thread.current.abort_on_exception = true
loop do
- sleep(@interval)
+ sleep(sleep_interval)
sample
end
@@ -102,6 +107,23 @@ module Gitlab
def sidekiq?
Sidekiq.server?
end
+
+ # Returns the sleep interval with a random adjustment.
+ #
+ # The random adjustment is put in place to ensure we:
+ #
+ # 1. Don't generate samples at the exact same interval every time (thus
+ # potentially missing anything that happens in between samples).
+ # 2. Don't sample data at the same interval two times in a row.
+ def sleep_interval
+ while step = @interval_steps.sample
+ if step != @last_step
+ @last_step = step
+
+ return @interval + @last_step
+ end
+ end
+ end
end
end
end
diff --git a/lib/gitlab/metrics/sidekiq_middleware.rb b/lib/gitlab/metrics/sidekiq_middleware.rb
index ad441decfa2..fd98aa3412e 100644
--- a/lib/gitlab/metrics/sidekiq_middleware.rb
+++ b/lib/gitlab/metrics/sidekiq_middleware.rb
@@ -5,19 +5,14 @@ module Gitlab
# This middleware is intended to be used as a server-side middleware.
class SidekiqMiddleware
def call(worker, message, queue)
- trans = Transaction.new
+ trans = Transaction.new("#{worker.class.name}#perform")
begin
trans.run { yield }
ensure
- tag_worker(trans, worker)
trans.finish
end
end
-
- def tag_worker(trans, worker)
- trans.add_tag(:action, "#{worker.class.name}#perform")
- end
end
end
end
diff --git a/lib/gitlab/metrics/subscribers/action_view.rb b/lib/gitlab/metrics/subscribers/action_view.rb
index 7c0105d543a..2e9dd4645e3 100644
--- a/lib/gitlab/metrics/subscribers/action_view.rb
+++ b/lib/gitlab/metrics/subscribers/action_view.rb
@@ -33,16 +33,8 @@ module Gitlab
def tags_for(event)
path = relative_path(event.payload[:identifier])
- tags = { view: path }
- file, line = Metrics.last_relative_application_frame
-
- if file and line
- tags[:file] = file
- tags[:line] = line
- end
-
- tags
+ { view: path }
end
def current_transaction
diff --git a/lib/gitlab/metrics/transaction.rb b/lib/gitlab/metrics/transaction.rb
index 73131cc6ef2..2578ddc49f4 100644
--- a/lib/gitlab/metrics/transaction.rb
+++ b/lib/gitlab/metrics/transaction.rb
@@ -6,11 +6,15 @@ module Gitlab
attr_reader :tags, :values
+ attr_accessor :action
+
def self.current
Thread.current[THREAD_KEY]
end
- def initialize
+ # action - A String describing the action performed, usually the class
+ # plus method name.
+ def initialize(action = nil)
@metrics = []
@started_at = nil
@@ -18,20 +22,30 @@ module Gitlab
@values = Hash.new(0)
@tags = {}
+ @action = action
+
+ @memory_before = 0
+ @memory_after = 0
end
def duration
@finished_at ? (@finished_at - @started_at) * 1000.0 : 0.0
end
+ def allocated_memory
+ @memory_after - @memory_before
+ end
+
def run
Thread.current[THREAD_KEY] = self
- @started_at = Time.now
+ @memory_before = System.memory_usage
+ @started_at = Time.now
yield
ensure
- @finished_at = Time.now
+ @memory_after = System.memory_usage
+ @finished_at = Time.now
Thread.current[THREAD_KEY] = nil
end
@@ -60,7 +74,7 @@ module Gitlab
end
def track_self
- values = { duration: duration }
+ values = { duration: duration, allocated_memory: allocated_memory }
@values.each do |name, value|
values[name] = value
@@ -70,7 +84,15 @@ module Gitlab
end
def submit
- Metrics.submit_metrics(@metrics.map(&:to_hash))
+ metrics = @metrics.map do |metric|
+ hash = metric.to_hash
+
+ hash[:tags][:action] ||= @action if @action
+
+ hash
+ end
+
+ Metrics.submit_metrics(metrics)
end
def sidekiq?
diff --git a/lib/tasks/gitlab/task_helpers.rake b/lib/tasks/gitlab/task_helpers.rake
index ebe516ec879..8c63877e51c 100644
--- a/lib/tasks/gitlab/task_helpers.rake
+++ b/lib/tasks/gitlab/task_helpers.rake
@@ -2,6 +2,8 @@ module Gitlab
class TaskAbortedByUserError < StandardError; end
end
+String.disable_colorization = true unless STDOUT.isatty
+
namespace :gitlab do
# Ask if the user wants to continue
diff --git a/spec/features/ci_lint_spec.rb b/spec/features/ci_lint_spec.rb
index e6e73e5e67c..30e29d9d552 100644
--- a/spec/features/ci_lint_spec.rb
+++ b/spec/features/ci_lint_spec.rb
@@ -35,5 +35,13 @@ describe 'CI Lint' do
expect(page).to have_content('Error: Please provide content of .gitlab-ci.yml')
end
end
+
+ describe 'YAML revalidate' do
+ let(:yaml_content) { 'my yaml content' }
+
+ it 'loads previous YAML content after validation' do
+ expect(page).to have_field('content', with: 'my yaml content', type: 'textarea')
+ end
+ end
end
end
diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb
index a2fb3e4c75d..e844e681ebf 100644
--- a/spec/features/issues_spec.rb
+++ b/spec/features/issues_spec.rb
@@ -127,15 +127,15 @@ describe 'Issues', feature: true do
it 'sorts by newest' do
visit namespace_project_issues_path(project.namespace, project, sort: sort_value_recently_created)
- expect(first_issue).to include('foo')
- expect(last_issue).to include('baz')
+ expect(first_issue).to include('baz')
+ expect(last_issue).to include('foo')
end
it 'sorts by oldest' do
visit namespace_project_issues_path(project.namespace, project, sort: sort_value_oldest_created)
- expect(first_issue).to include('baz')
- expect(last_issue).to include('foo')
+ expect(first_issue).to include('foo')
+ expect(last_issue).to include('baz')
end
it 'sorts by most recently updated' do
@@ -190,8 +190,8 @@ describe 'Issues', feature: true do
sort: sort_value_oldest_created,
assignee_id: user2.id)
- expect(first_issue).to include('bar')
- expect(last_issue).to include('foo')
+ expect(first_issue).to include('foo')
+ expect(last_issue).to include('bar')
expect(page).not_to have_content 'baz'
end
end
diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb
index efc850eb705..30e353148a8 100644
--- a/spec/helpers/application_helper_spec.rb
+++ b/spec/helpers/application_helper_spec.rb
@@ -285,6 +285,10 @@ describe ApplicationHelper do
it 'allows the script tag to be excluded' do
expect(element(skip_js: true)).not_to include 'script'
end
+
+ it 'converts to Time' do
+ expect { helper.time_ago_with_tooltip(Date.today) }.not_to raise_error
+ end
end
describe 'render_markup' do
diff --git a/spec/javascripts/issue_spec.js.coffee b/spec/javascripts/issue_spec.js.coffee
index b85fadcbe82..86ba9dd8e96 100644
--- a/spec/javascripts/issue_spec.js.coffee
+++ b/spec/javascripts/issue_spec.js.coffee
@@ -44,7 +44,7 @@ describe 'reopen/close issue', ->
expect($('div.status-box-closed')).toBeVisible()
expect($('div.status-box-open')).toBeHidden()
- it 'fails to closes an issue with success:false', ->
+ it 'fails to close an issue with success:false', ->
spyOn(jQuery, 'ajax').and.callFake (req) ->
expect(req.type).toBe('PUT')
diff --git a/spec/lib/gitlab/metrics/rack_middleware_spec.rb b/spec/lib/gitlab/metrics/rack_middleware_spec.rb
index 4e6dfc73df2..b99be4e1060 100644
--- a/spec/lib/gitlab/metrics/rack_middleware_spec.rb
+++ b/spec/lib/gitlab/metrics/rack_middleware_spec.rb
@@ -57,7 +57,7 @@ describe Gitlab::Metrics::RackMiddleware do
middleware.tag_controller(transaction, env)
- expect(transaction.tags[:action]).to eq('TestController#show')
+ expect(transaction.action).to eq('TestController#show')
end
end
end
diff --git a/spec/lib/gitlab/metrics/sampler_spec.rb b/spec/lib/gitlab/metrics/sampler_spec.rb
index 27211350fbe..38da77adc9f 100644
--- a/spec/lib/gitlab/metrics/sampler_spec.rb
+++ b/spec/lib/gitlab/metrics/sampler_spec.rb
@@ -9,7 +9,7 @@ describe Gitlab::Metrics::Sampler do
describe '#start' do
it 'gathers a sample at a given interval' do
- expect(sampler).to receive(:sleep).with(5)
+ expect(sampler).to receive(:sleep).with(a_kind_of(Numeric))
expect(sampler).to receive(:sample)
expect(sampler).to receive(:loop).and_yield
@@ -116,4 +116,24 @@ describe Gitlab::Metrics::Sampler do
sampler.add_metric('cats', value: 10)
end
end
+
+ describe '#sleep_interval' do
+ it 'returns a Numeric' do
+ expect(sampler.sleep_interval).to be_a_kind_of(Numeric)
+ end
+
+ # Testing random behaviour is very hard, so treat this test as a basic smoke
+ # test instead of a very accurate behaviour/unit test.
+ it 'does not return the same interval twice in a row' do
+ last = nil
+
+ 100.times do
+ interval = sampler.sleep_interval
+
+ expect(interval).to_not eq(last)
+
+ last = interval
+ end
+ end
+ end
end
diff --git a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
index 5882e7d81c7..e520a968999 100644
--- a/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
+++ b/spec/lib/gitlab/metrics/sidekiq_middleware_spec.rb
@@ -5,22 +5,15 @@ describe Gitlab::Metrics::SidekiqMiddleware do
describe '#call' do
it 'tracks the transaction' do
- worker = Class.new.new
+ worker = double(:worker, class: double(:class, name: 'TestWorker'))
+
+ expect(Gitlab::Metrics::Transaction).to receive(:new).
+ with('TestWorker#perform').
+ and_call_original
expect_any_instance_of(Gitlab::Metrics::Transaction).to receive(:finish)
middleware.call(worker, 'test', :test) { nil }
end
end
-
- describe '#tag_worker' do
- it 'adds the worker class and action to the transaction' do
- trans = Gitlab::Metrics::Transaction.new
- worker = double(:worker, class: double(:class, name: 'TestWorker'))
-
- expect(trans).to receive(:add_tag).with(:action, 'TestWorker#perform')
-
- middleware.tag_worker(trans, worker)
- end
- end
end
diff --git a/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb b/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb
index 05e4fbbeb51..0695c5ce096 100644
--- a/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb
+++ b/spec/lib/gitlab/metrics/subscribers/action_view_spec.rb
@@ -14,19 +14,12 @@ describe Gitlab::Metrics::Subscribers::ActionView do
before do
allow(subscriber).to receive(:current_transaction).and_return(transaction)
-
- allow(Gitlab::Metrics).to receive(:last_relative_application_frame).
- and_return(['app/views/x.html.haml', 4])
end
describe '#render_template' do
it 'tracks rendering of a template' do
values = { duration: 2.1 }
- tags = {
- view: 'app/views/x.html.haml',
- file: 'app/views/x.html.haml',
- line: 4
- }
+ tags = { view: 'app/views/x.html.haml' }
expect(transaction).to receive(:increment).
with(:view_duration, 2.1)
diff --git a/spec/lib/gitlab/metrics/transaction_spec.rb b/spec/lib/gitlab/metrics/transaction_spec.rb
index 3a27f897735..1d5a51a157e 100644
--- a/spec/lib/gitlab/metrics/transaction_spec.rb
+++ b/spec/lib/gitlab/metrics/transaction_spec.rb
@@ -11,6 +11,14 @@ describe Gitlab::Metrics::Transaction do
end
end
+ describe '#allocated_memory' do
+ it 'returns the allocated memory in bytes' do
+ transaction.run { 'a' * 32 }
+
+ expect(transaction.allocated_memory).to be_a_kind_of(Numeric)
+ end
+ end
+
describe '#run' do
it 'yields the supplied block' do
expect { |b| transaction.run(&b) }.to yield_control
@@ -43,8 +51,10 @@ describe Gitlab::Metrics::Transaction do
transaction.increment(:time, 1)
transaction.increment(:time, 2)
+ values = { duration: 0.0, time: 3, allocated_memory: a_kind_of(Numeric) }
+
expect(transaction).to receive(:add_metric).
- with('transactions', { duration: 0.0, time: 3 }, {})
+ with('transactions', values, {})
transaction.track_self
end
@@ -54,8 +64,14 @@ describe Gitlab::Metrics::Transaction do
it 'sets a value' do
transaction.set(:number, 10)
+ values = {
+ duration: 0.0,
+ number: 10,
+ allocated_memory: a_kind_of(Numeric)
+ }
+
expect(transaction).to receive(:add_metric).
- with('transactions', { duration: 0.0, number: 10 }, {})
+ with('transactions', values, {})
transaction.track_self
end
@@ -80,8 +96,13 @@ describe Gitlab::Metrics::Transaction do
describe '#track_self' do
it 'adds a metric for the transaction itself' do
+ values = {
+ duration: transaction.duration,
+ allocated_memory: a_kind_of(Numeric)
+ }
+
expect(transaction).to receive(:add_metric).
- with('transactions', { duration: transaction.duration }, {})
+ with('transactions', values, {})
transaction.track_self
end
@@ -96,5 +117,22 @@ describe Gitlab::Metrics::Transaction do
transaction.submit
end
+
+ it 'adds the action as a tag for every metric' do
+ transaction.action = 'Foo#bar'
+ transaction.track_self
+
+ hash = {
+ series: 'rails_transactions',
+ tags: { action: 'Foo#bar' },
+ values: { duration: 0.0, allocated_memory: a_kind_of(Numeric) },
+ timestamp: an_instance_of(Fixnum)
+ }
+
+ expect(Gitlab::Metrics).to receive(:submit_metrics).
+ with([hash])
+
+ transaction.submit
+ end
end
end
diff --git a/spec/lib/gitlab/metrics_spec.rb b/spec/lib/gitlab/metrics_spec.rb
index c2782f95c8e..0ec8a6dc5cb 100644
--- a/spec/lib/gitlab/metrics_spec.rb
+++ b/spec/lib/gitlab/metrics_spec.rb
@@ -13,15 +13,6 @@ describe Gitlab::Metrics do
end
end
- describe '.last_relative_application_frame' do
- it 'returns an Array containing a file path and line number' do
- file, line = described_class.last_relative_application_frame
-
- expect(line).to eq(__LINE__ - 2)
- expect(file).to eq('spec/lib/gitlab/metrics_spec.rb')
- end
- end
-
describe '#submit_metrics' do
it 'prepares and writes the metrics to InfluxDB' do
connection = double(:connection)
diff --git a/spec/models/abuse_report_spec.rb b/spec/models/abuse_report_spec.rb
index 46cab1644c7..f9be8fcbcfe 100644
--- a/spec/models/abuse_report_spec.rb
+++ b/spec/models/abuse_report_spec.rb
@@ -29,6 +29,22 @@ RSpec.describe AbuseReport, type: :model do
it { is_expected.to validate_uniqueness_of(:user_id) }
end
+ describe '#remove_user' do
+ it 'blocks the user' do
+ report = build(:abuse_report)
+
+ allow(report.user).to receive(:destroy)
+
+ expect { report.remove_user }.to change { report.user.blocked? }.to(true)
+ end
+
+ it 'removes the user' do
+ report = build(:abuse_report)
+
+ expect { report.remove_user }.to change { User.count }.by(-1)
+ end
+ end
+
describe '#notify' do
it 'delivers' do
expect(AbuseReportMailer).to receive(:notify).with(subject.id).
diff --git a/spec/services/system_hooks_service_spec.rb b/spec/services/system_hooks_service_spec.rb
index 4455ae7b321..fef211ded50 100644
--- a/spec/services/system_hooks_service_spec.rb
+++ b/spec/services/system_hooks_service_spec.rb
@@ -9,54 +9,54 @@ describe SystemHooksService, services: true do
let(:group_member) { create(:group_member) }
context 'event data' do
- it { expect(event_data(user, :create)).to include(:event_name, :name, :created_at, :updated_at, :email, :user_id) }
- it { expect(event_data(user, :destroy)).to include(:event_name, :name, :created_at, :updated_at, :email, :user_id) }
+ it { expect(event_data(user, :create)).to include(:event_name, :name, :created_at, :updated_at, :email, :user_id, :username) }
+ it { expect(event_data(user, :destroy)).to include(:event_name, :name, :created_at, :updated_at, :email, :user_id, :username) }
it { expect(event_data(project, :create)).to include(:event_name, :name, :created_at, :updated_at, :path, :project_id, :owner_name, :owner_email, :project_visibility) }
it { expect(event_data(project, :destroy)).to include(:event_name, :name, :created_at, :updated_at, :path, :project_id, :owner_name, :owner_email, :project_visibility) }
- it { expect(event_data(project_member, :create)).to include(:event_name, :created_at, :updated_at, :project_name, :project_path, :project_path_with_namespace, :project_id, :user_name, :user_email, :access_level, :project_visibility) }
- it { expect(event_data(project_member, :destroy)).to include(:event_name, :created_at, :updated_at, :project_name, :project_path, :project_path_with_namespace, :project_id, :user_name, :user_email, :access_level, :project_visibility) }
+ it { expect(event_data(project_member, :create)).to include(:event_name, :created_at, :updated_at, :project_name, :project_path, :project_path_with_namespace, :project_id, :user_name, :user_username, :user_email, :user_id, :access_level, :project_visibility) }
+ it { expect(event_data(project_member, :destroy)).to include(:event_name, :created_at, :updated_at, :project_name, :project_path, :project_path_with_namespace, :project_id, :user_name, :user_username, :user_email, :user_id, :access_level, :project_visibility) }
it { expect(event_data(key, :create)).to include(:username, :key, :id) }
it { expect(event_data(key, :destroy)).to include(:username, :key, :id) }
it do
project.old_path_with_namespace = 'renamed_from_path'
expect(event_data(project, :rename)).to include(
- :event_name, :name, :created_at, :updated_at, :path, :project_id,
- :owner_name, :owner_email, :project_visibility,
+ :event_name, :name, :created_at, :updated_at, :path, :project_id,
+ :owner_name, :owner_email, :project_visibility,
:old_path_with_namespace
- )
+ )
end
it do
project.old_path_with_namespace = 'transfered_from_path'
expect(event_data(project, :transfer)).to include(
- :event_name, :name, :created_at, :updated_at, :path, :project_id,
- :owner_name, :owner_email, :project_visibility,
+ :event_name, :name, :created_at, :updated_at, :path, :project_id,
+ :owner_name, :owner_email, :project_visibility,
:old_path_with_namespace
- )
+ )
end
it do
expect(event_data(group, :create)).to include(
- :event_name, :name, :created_at, :updated_at, :path, :group_id,
+ :event_name, :name, :created_at, :updated_at, :path, :group_id,
:owner_name, :owner_email
)
end
it do
expect(event_data(group, :destroy)).to include(
- :event_name, :name, :created_at, :updated_at, :path, :group_id,
+ :event_name, :name, :created_at, :updated_at, :path, :group_id,
:owner_name, :owner_email
)
end
it do
expect(event_data(group_member, :create)).to include(
- :event_name, :created_at, :updated_at, :group_name, :group_path,
- :group_id, :user_id, :user_name, :user_email, :group_access
+ :event_name, :created_at, :updated_at, :group_name, :group_path,
+ :group_id, :user_id, :user_username, :user_name, :user_email, :group_access
)
end
it do
expect(event_data(group_member, :destroy)).to include(
- :event_name, :created_at, :updated_at, :group_name, :group_path,
- :group_id, :user_id, :user_name, :user_email, :group_access
+ :event_name, :created_at, :updated_at, :group_name, :group_path,
+ :group_id, :user_id, :user_username, :user_name, :user_email, :group_access
)
end
end