summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitlab/ci/review.gitlab-ci.yml5
-rw-r--r--GITLAB_SHELL_VERSION2
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock4
-rw-r--r--app/assets/javascripts/diffs/components/tree_list.vue9
-rw-r--r--app/controllers/registrations_controller.rb25
-rw-r--r--app/models/clusters/concerns/application_data.rb74
-rw-r--r--app/models/repository.rb23
-rw-r--r--app/uploaders/file_uploader.rb12
-rw-r--r--app/uploaders/personal_file_uploader.rb68
-rw-r--r--app/views/admin/groups/_form.html.haml2
-rw-r--r--app/views/admin/users/_access_levels.html.haml2
-rw-r--r--app/views/projects/mirrors/_mirror_repos.html.haml2
-rw-r--r--app/views/projects/protected_branches/_protected_branch.html.haml2
-rw-r--r--changelogs/unreleased/61914-fix-emojis-urls.yml5
-rw-r--r--changelogs/unreleased/add-branch-to-project-search-api.yml5
-rw-r--r--changelogs/unreleased/jc-omit-count-diverging-commits-max.yml5
-rw-r--r--changelogs/unreleased/sh-fix-personal-snippet-uploads-object-storage.yml5
-rw-r--r--db/migrate/20190515125613_add_application_settings_elasticsearch_shards.rb10
-rw-r--r--db/schema.rb4
-rw-r--r--doc/api/search.md5
-rw-r--r--doc/ci/examples/README.md48
-rw-r--r--doc/development/architecture.md10
-rw-r--r--doc/development/ee_features.md14
-rw-r--r--doc/development/testing_guide/review_apps.md22
-rw-r--r--doc/install/ldap.md4
-rw-r--r--doc/integration/elasticsearch.md2
-rw-r--r--doc/license/README.md2
-rw-r--r--doc/topics/authentication/index.md10
-rw-r--r--doc/user/admin_area/settings/continuous_integration.md10
-rw-r--r--doc/user/application_security/container_scanning/index.md6
-rw-r--r--doc/user/group/saml_sso/index.md12
-rw-r--r--doc/user/markdown.md10
-rw-r--r--doc/user/project/merge_requests/img/container_scanning.pngbin32549 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/create-issue-with-list-hover.pngbin106954 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/dast_all.pngbin25844 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/dast_single.pngbin69353 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/dependency_scanning.pngbin16167 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/interactive_reports.pngbin23190 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/license_management.pngbin5184 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/license_management_decision.pngbin5981 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/license_management_pipeline_tab.pngbin12115 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/license_management_settings.pngbin13300 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/revert_changes_commit.pngbin95647 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/revert_changes_mr.pngbin104954 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/sast.pngbin24876 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/security_report.pngbin38475 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/img/vulnerability_solution.pngbin3421 -> 0 bytes
-rw-r--r--doc/user/project/merge_requests/merge_request_approvals.md12
-rw-r--r--lib/api/search.rb3
-rw-r--r--lib/gitlab/danger/helper.rb2
-rw-r--r--lib/gitlab/git/repository.rb2
-rw-r--r--locale/gitlab.pot5
-rwxr-xr-xscripts/clean-old-cached-assets4
-rw-r--r--spec/controllers/registrations_controller_spec.rb19
-rw-r--r--spec/frontend/helpers/timeout.js27
-rw-r--r--spec/models/repository_spec.rb37
-rw-r--r--spec/requests/api/search_spec.rb7
-rw-r--r--spec/uploaders/personal_file_uploader_spec.rb60
59 files changed, 430 insertions, 169 deletions
diff --git a/.gitlab/ci/review.gitlab-ci.yml b/.gitlab/ci/review.gitlab-ci.yml
index 3a024c44fe2..80356fa1dc2 100644
--- a/.gitlab/ci/review.gitlab-ci.yml
+++ b/.gitlab/ci/review.gitlab-ci.yml
@@ -78,7 +78,6 @@ schedule:review-build-cng:
<<: *review-base
stage: review
retry: 2
- allow_failure: true
variables:
HOST_SUFFIX: "${CI_ENVIRONMENT_SLUG}"
DOMAIN: "-${CI_ENVIRONMENT_SLUG}.${REVIEW_APPS_DOMAIN}"
@@ -130,7 +129,6 @@ review-stop:
.review-qa-base: &review-qa-base
<<: *review-docker
stage: qa
- allow_failure: true
variables:
<<: *review-docker-variables
QA_ARTIFACTS_DIR: "${CI_PROJECT_DIR}/qa"
@@ -165,13 +163,14 @@ review-qa-smoke:
review-qa-all:
<<: *review-qa-base
+ allow_failure: true
when: manual
script:
- gitlab-qa Test::Instance::Any "${QA_IMAGE}" "${CI_ENVIRONMENT_URL}"
.review-performance-base: &review-performance-base
<<: *review-qa-base
- stage: qa
+ allow_failure: true
before_script:
- export CI_ENVIRONMENT_URL="$(cat review_app_url.txt)"
- echo "${CI_ENVIRONMENT_URL}"
diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION
index 47da986f86f..deeb3d66ef0 100644
--- a/GITLAB_SHELL_VERSION
+++ b/GITLAB_SHELL_VERSION
@@ -1 +1 @@
-9.1.0
+9.2.0
diff --git a/Gemfile b/Gemfile
index 6b37ecbfba9..0d3b1d5e774 100644
--- a/Gemfile
+++ b/Gemfile
@@ -360,7 +360,7 @@ group :development, :test do
gem 'rubocop-rspec', '~> 1.22.1'
gem 'scss_lint', '~> 0.56.0', require: false
- gem 'haml_lint', '~> 0.30.0', require: false
+ gem 'haml_lint', '~> 0.31.0', require: false
gem 'simplecov', '~> 0.14.0', require: false
gem 'bundler-audit', '~> 0.5.0', require: false
diff --git a/Gemfile.lock b/Gemfile.lock
index 8238ed4763e..94961354a2e 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -360,7 +360,7 @@ GEM
haml (5.0.4)
temple (>= 0.8.0)
tilt
- haml_lint (0.30.0)
+ haml_lint (0.31.0)
haml (>= 4.0, < 5.1)
rainbow
rake (>= 10, < 13)
@@ -1089,7 +1089,7 @@ DEPENDENCIES
graphiql-rails (~> 1.4.10)
graphql (~> 1.8.0)
grpc (~> 1.19.0)
- haml_lint (~> 0.30.0)
+ haml_lint (~> 0.31.0)
hamlit (~> 2.8.8)
hangouts-chat (~> 0.0.5)
hashie-forbidden_attributes
diff --git a/app/assets/javascripts/diffs/components/tree_list.vue b/app/assets/javascripts/diffs/components/tree_list.vue
index 384f33e0983..30be2e68e76 100644
--- a/app/assets/javascripts/diffs/components/tree_list.vue
+++ b/app/assets/javascripts/diffs/components/tree_list.vue
@@ -1,6 +1,7 @@
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
import { GlTooltipDirective } from '@gitlab/ui';
+import { s__, sprintf } from '~/locale';
import Icon from '~/vue_shared/components/icon.vue';
import FileRow from '~/vue_shared/components/file_row.vue';
import FileRowStats from './file_row_stats.vue';
@@ -57,6 +58,9 @@ export default {
this.search = '';
},
},
+ searchPlaceholder: sprintf(s__('MergeRequest|Filter files or search with %{modifier_key}+p'), {
+ modifier_key: /Mac/i.test(navigator.userAgent) ? 'cmd' : 'ctrl',
+ }),
};
</script>
@@ -65,10 +69,13 @@ export default {
<div class="append-bottom-8 position-relative tree-list-search d-flex">
<div class="flex-fill d-flex">
<icon name="search" class="position-absolute tree-list-icon" />
+ <label for="diff-tree-search" class="sr-only">{{ $options.searchPlaceholder }}</label>
<input
+ id="diff-tree-search"
v-model="search"
- :placeholder="s__('MergeRequest|Filter files')"
+ :placeholder="$options.searchPlaceholder"
type="search"
+ name="diff-tree-search"
class="form-control"
/>
<button
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index 0fa4677ced1..07b38371ab9 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -4,6 +4,7 @@ class RegistrationsController < Devise::RegistrationsController
include Recaptcha::Verify
include AcceptsPendingInvitations
+ prepend_before_action :check_captcha, only: :create
before_action :whitelist_query_limiting, only: [:destroy]
before_action :ensure_terms_accepted,
if: -> { Gitlab::CurrentSettings.current_application_settings.enforce_terms? },
@@ -21,15 +22,10 @@ class RegistrationsController < Devise::RegistrationsController
params[resource_name] = params.delete(:"new_#{resource_name}")
end
- if !Gitlab::Recaptcha.load_configurations! || verify_recaptcha
- accept_pending_invitations
- super do |new_user|
- persist_accepted_terms_if_required(new_user)
- end
- else
- flash[:alert] = s_('Profiles|There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.')
- flash.delete :recaptcha_error
- render action: 'new'
+ accept_pending_invitations
+
+ super do |new_user|
+ persist_accepted_terms_if_required(new_user)
end
rescue Gitlab::Access::AccessDeniedError
redirect_to(new_user_session_path)
@@ -89,6 +85,17 @@ class RegistrationsController < Devise::RegistrationsController
private
+ def check_captcha
+ return unless Feature.enabled?(:registrations_recaptcha, default_enabled: true)
+ return unless Gitlab::Recaptcha.load_configurations!
+
+ return if verify_recaptcha
+
+ flash[:alert] = _('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.')
+ flash.delete :recaptcha_error
+ render action: 'new'
+ end
+
def sign_up_params
params.require(:user).permit(:username, :email, :email_confirmation, :name, :password)
end
diff --git a/app/models/clusters/concerns/application_data.rb b/app/models/clusters/concerns/application_data.rb
index a48ee340fac..3479fea415e 100644
--- a/app/models/clusters/concerns/application_data.rb
+++ b/app/models/clusters/concerns/application_data.rb
@@ -3,56 +3,52 @@
module Clusters
module Concerns
module ApplicationData
- extend ActiveSupport::Concern
-
- included do
- def uninstall_command
- Gitlab::Kubernetes::Helm::DeleteCommand.new(
- name: name,
- rbac: cluster.platform_kubernetes_rbac?,
- files: files
- )
- end
+ def uninstall_command
+ Gitlab::Kubernetes::Helm::DeleteCommand.new(
+ name: name,
+ rbac: cluster.platform_kubernetes_rbac?,
+ files: files
+ )
+ end
- def repository
- nil
- end
+ def repository
+ nil
+ end
- def values
- File.read(chart_values_file)
- end
+ def values
+ File.read(chart_values_file)
+ end
- def files
- @files ||= begin
- files = { 'values.yaml': values }
+ def files
+ @files ||= begin
+ files = { 'values.yaml': values }
- files.merge!(certificate_files) if cluster.application_helm.has_ssl?
+ files.merge!(certificate_files) if cluster.application_helm.has_ssl?
- files
- end
+ files
end
+ end
- private
+ private
- def certificate_files
- {
- 'ca.pem': ca_cert,
- 'cert.pem': helm_cert.cert_string,
- 'key.pem': helm_cert.key_string
- }
- end
+ def certificate_files
+ {
+ 'ca.pem': ca_cert,
+ 'cert.pem': helm_cert.cert_string,
+ 'key.pem': helm_cert.key_string
+ }
+ end
- def ca_cert
- cluster.application_helm.ca_cert
- end
+ def ca_cert
+ cluster.application_helm.ca_cert
+ end
- def helm_cert
- @helm_cert ||= cluster.application_helm.issue_client_cert
- end
+ def helm_cert
+ @helm_cert ||= cluster.application_helm.issue_client_cert
+ end
- def chart_values_file
- "#{Rails.root}/vendor/#{name}/values.yaml"
- end
+ def chart_values_file
+ "#{Rails.root}/vendor/#{name}/values.yaml"
end
end
end
diff --git a/app/models/repository.rb b/app/models/repository.rb
index f540b00a849..e05d3dd58ac 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -283,14 +283,19 @@ class Repository
end
def diverging_commit_counts(branch)
+ return diverging_commit_counts_without_max(branch) if Feature.enabled?('gitaly_count_diverging_commits_no_max')
+
+ ## TODO: deprecate the below code after 12.0
@root_ref_hash ||= raw_repository.commit(root_ref).id
cache.fetch(:"diverging_commit_counts_#{branch.name}") do
# Rugged seems to throw a `ReferenceError` when given branch_names rather
# than SHA-1 hashes
+ branch_sha = branch.dereferenced_target.sha
+
number_commits_behind, number_commits_ahead =
raw_repository.diverging_commit_count(
@root_ref_hash,
- branch.dereferenced_target.sha,
+ branch_sha,
max_count: MAX_DIVERGING_COUNT)
if number_commits_behind + number_commits_ahead >= MAX_DIVERGING_COUNT
@@ -301,6 +306,22 @@ class Repository
end
end
+ def diverging_commit_counts_without_max(branch)
+ @root_ref_hash ||= raw_repository.commit(root_ref).id
+ cache.fetch(:"diverging_commit_counts_without_max_#{branch.name}") do
+ # Rugged seems to throw a `ReferenceError` when given branch_names rather
+ # than SHA-1 hashes
+ branch_sha = branch.dereferenced_target.sha
+
+ number_commits_behind, number_commits_ahead =
+ raw_repository.diverging_commit_count(
+ @root_ref_hash,
+ branch_sha)
+
+ { behind: number_commits_behind, ahead: number_commits_ahead }
+ end
+ end
+
def archive_metadata(ref, storage_path, format = "tar.gz", append_sha:, path: nil)
raw_repository.archive_metadata(
ref,
diff --git a/app/uploaders/file_uploader.rb b/app/uploaders/file_uploader.rb
index 6dfe2bed0ba..1c7582533ad 100644
--- a/app/uploaders/file_uploader.rb
+++ b/app/uploaders/file_uploader.rb
@@ -109,12 +109,20 @@ class FileUploader < GitlabUploader
def upload_path
if file_storage?
# Legacy path relative to project.full_path
- File.join(dynamic_segment, identifier)
+ local_storage_path(identifier)
else
- File.join(store_dir, identifier)
+ remote_storage_path(identifier)
end
end
+ def local_storage_path(file_identifier)
+ File.join(dynamic_segment, file_identifier)
+ end
+
+ def remote_storage_path(file_identifier)
+ File.join(store_dir, file_identifier)
+ end
+
def store_dirs
{
Store::LOCAL => File.join(base_dir, dynamic_segment),
diff --git a/app/uploaders/personal_file_uploader.rb b/app/uploaders/personal_file_uploader.rb
index f4697d898af..b43162f0935 100644
--- a/app/uploaders/personal_file_uploader.rb
+++ b/app/uploaders/personal_file_uploader.rb
@@ -6,15 +6,12 @@ class PersonalFileUploader < FileUploader
options.storage_path
end
- def self.base_dir(model, store = nil)
- base_dirs(model)[store || Store::LOCAL]
- end
-
- def self.base_dirs(model)
- {
- Store::LOCAL => File.join(options.base_dir, model_path_segment(model)),
- Store::REMOTE => model_path_segment(model)
- }
+ def self.base_dir(model, _store = nil)
+ # base_dir is the path seen by the user when rendering Markdown, so
+ # it should be the same for both local and object storage. It is
+ # typically prefaced with uploads/-/system, but that prefix
+ # is omitted in the path stored on disk.
+ File.join(options.base_dir, model_path_segment(model))
end
def self.model_path_segment(model)
@@ -40,8 +37,61 @@ class PersonalFileUploader < FileUploader
store_dirs[object_store]
end
+ # A personal snippet path is stored using FileUploader#upload_path.
+ #
+ # The format for the path:
+ #
+ # Local storage: :random_hex/:filename.
+ # Object storage: personal_snippet/:id/:random_hex/:filename.
+ #
+ # upload_paths represent the possible paths for a given identifier,
+ # which will vary depending on whether the file is stored in local or
+ # object storage. upload_path should match an element in upload_paths.
+ #
+ # base_dir represents the path seen by the user in Markdown, and it
+ # should always be prefixed with uploads/-/system.
+ #
+ # store_dirs represent the paths that are actually used on disk. For
+ # object storage, this should omit the prefix /uploads/-/system.
+ #
+ # For example, consider the requested path /uploads/-/system/personal_snippet/172/ff4ad5c2e40b39ae57cda51577317d20/file.png.
+ #
+ # For local storage:
+ #
+ # File on disk: /opt/gitlab/embedded/service/gitlab-rails/public/uploads/-/system/personal_snippet/172/ff4ad5c2e40b39ae57cda51577317d20/file.png.
+ #
+ # base_dir: uploads/-/system/personal_snippet/172
+ # upload_path: ff4ad5c2e40b39ae57cda51577317d20/file.png
+ # upload_paths: ["ff4ad5c2e40b39ae57cda51577317d20/file.png", "personal_snippet/172/ff4ad5c2e40b39ae57cda51577317d20/file.png"].
+ # store_dirs:
+ # => {1=>"uploads/-/system/personal_snippet/172/ff4ad5c2e40b39ae57cda51577317d20", 2=>"personal_snippet/172/ff4ad5c2e40b39ae57cda51577317d20"}
+ #
+ # For object storage:
+ #
+ # upload_path: personal_snippet/172/ff4ad5c2e40b39ae57cda51577317d20/file.png
+ def upload_paths(identifier)
+ [
+ local_storage_path(identifier),
+ File.join(remote_storage_base_path, identifier)
+ ]
+ end
+
+ def store_dirs
+ {
+ Store::LOCAL => File.join(base_dir, dynamic_segment),
+ Store::REMOTE => remote_storage_base_path
+ }
+ end
+
private
+ # To avoid prefacing the remote storage path with `/uploads/-/system`,
+ # we just drop that part so that the destination path will be
+ # personal_snippet/:id/:random_hex/:filename.
+ def remote_storage_base_path
+ File.join(self.class.model_path_segment(model), dynamic_segment)
+ end
+
def secure_url
File.join('/', base_dir, secret, file.filename)
end
diff --git a/app/views/admin/groups/_form.html.haml b/app/views/admin/groups/_form.html.haml
index 8fb38f6a690..62d1d01cc83 100644
--- a/app/views/admin/groups/_form.html.haml
+++ b/app/views/admin/groups/_form.html.haml
@@ -2,7 +2,7 @@
= form_errors(@group)
= render 'shared/group_form', f: f
- = render_if_exists 'shared/repository_size_limit_setting', form: f, type: :group
+ = render_if_exists 'shared/old_repository_size_limit_setting', form: f, type: :group
= render_if_exists 'admin/namespace_plan', f: f
.form-group.row.group-description-holder
diff --git a/app/views/admin/users/_access_levels.html.haml b/app/views/admin/users/_access_levels.html.haml
index 12e24ddef02..98b6bc7bc46 100644
--- a/app/views/admin/users/_access_levels.html.haml
+++ b/app/views/admin/users/_access_levels.html.haml
@@ -22,6 +22,8 @@
%p.light
Regular users have access to their groups and projects
+ = render_if_exists 'admin/users/auditor_access_level_radio', f: f, disabled: editing_current_user
+
= f.radio_button :access_level, :admin, disabled: editing_current_user
= label_tag :admin, class: 'font-weight-bold' do
Admin
diff --git a/app/views/projects/mirrors/_mirror_repos.html.haml b/app/views/projects/mirrors/_mirror_repos.html.haml
index 73e2a4ffb8b..e68fa5d08c7 100644
--- a/app/views/projects/mirrors/_mirror_repos.html.haml
+++ b/app/views/projects/mirrors/_mirror_repos.html.haml
@@ -29,7 +29,7 @@
.form-check.append-bottom-10
= check_box_tag :only_protected_branches, '1', false, class: 'js-mirror-protected form-check-input'
= label_tag :only_protected_branches, _('Only mirror protected branches'), class: 'form-check-label'
- = link_to icon('question-circle'), help_page_path('user/project/protected_branches')
+ = link_to icon('question-circle'), help_page_path('user/project/protected_branches'), target: '_blank'
.panel-footer
= f.submit _('Mirror repository'), class: 'btn btn-success js-mirror-submit qa-mirror-repository-button', name: :update_remote_mirror
diff --git a/app/views/projects/protected_branches/_protected_branch.html.haml b/app/views/projects/protected_branches/_protected_branch.html.haml
index b12ae995ece..366d7a7a2eb 100644
--- a/app/views/projects/protected_branches/_protected_branch.html.haml
+++ b/app/views/projects/protected_branches/_protected_branch.html.haml
@@ -1,2 +1,2 @@
= render layout: 'projects/protected_branches/shared/protected_branch', locals: { protected_branch: protected_branch } do
- = render partial: 'projects/protected_branches/update_protected_branch', locals: { protected_branch: protected_branch }
+ = render_if_exists 'projects/protected_branches/update_protected_branch', protected_branch: protected_branch
diff --git a/changelogs/unreleased/61914-fix-emojis-urls.yml b/changelogs/unreleased/61914-fix-emojis-urls.yml
new file mode 100644
index 00000000000..578edf4a063
--- /dev/null
+++ b/changelogs/unreleased/61914-fix-emojis-urls.yml
@@ -0,0 +1,5 @@
+---
+title: Fix emojis URLs
+merge_request: 28371
+author:
+type: fixed
diff --git a/changelogs/unreleased/add-branch-to-project-search-api.yml b/changelogs/unreleased/add-branch-to-project-search-api.yml
new file mode 100644
index 00000000000..74cff94ab76
--- /dev/null
+++ b/changelogs/unreleased/add-branch-to-project-search-api.yml
@@ -0,0 +1,5 @@
+---
+title: Added ref querystring parameter to project search API to allow searching on branches/tags other than the default
+merge_request: 28069
+author: Lee Tickett
+type: added
diff --git a/changelogs/unreleased/jc-omit-count-diverging-commits-max.yml b/changelogs/unreleased/jc-omit-count-diverging-commits-max.yml
new file mode 100644
index 00000000000..23235060a98
--- /dev/null
+++ b/changelogs/unreleased/jc-omit-count-diverging-commits-max.yml
@@ -0,0 +1,5 @@
+---
+title: Omit max-count for diverging_commit_counts behind feature flag
+merge_request: 28157
+author:
+type: other
diff --git a/changelogs/unreleased/sh-fix-personal-snippet-uploads-object-storage.yml b/changelogs/unreleased/sh-fix-personal-snippet-uploads-object-storage.yml
new file mode 100644
index 00000000000..603afa8573f
--- /dev/null
+++ b/changelogs/unreleased/sh-fix-personal-snippet-uploads-object-storage.yml
@@ -0,0 +1,5 @@
+---
+title: Fix incorrect prefix used in new uploads for personal snippets
+merge_request: 28337
+author:
+type: fixed
diff --git a/db/migrate/20190515125613_add_application_settings_elasticsearch_shards.rb b/db/migrate/20190515125613_add_application_settings_elasticsearch_shards.rb
new file mode 100644
index 00000000000..9cebc0f8db4
--- /dev/null
+++ b/db/migrate/20190515125613_add_application_settings_elasticsearch_shards.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+class AddApplicationSettingsElasticsearchShards < ActiveRecord::Migration[5.1]
+ DOWNTIME = false
+
+ def change
+ add_column :application_settings, :elasticsearch_shards, :integer, null: false, default: 5
+ add_column :application_settings, :elasticsearch_replicas, :integer, null: false, default: 1
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 159e7e03cf4..9d367938cec 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20190506135400) do
+ActiveRecord::Schema.define(version: 20190515125613) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -189,6 +189,8 @@ ActiveRecord::Schema.define(version: 20190506135400) do
t.string "encrypted_external_auth_client_key_pass_iv"
t.string "lets_encrypt_notification_email"
t.boolean "lets_encrypt_terms_of_service_accepted", default: false, null: false
+ t.integer "elasticsearch_shards", default: 5, null: false
+ t.integer "elasticsearch_replicas", default: 1, null: false
t.index ["usage_stats_set_by_user_id"], name: "index_application_settings_on_usage_stats_set_by_user_id", using: :btree
end
diff --git a/doc/api/search.md b/doc/api/search.md
index 6ee3d32d8bc..c2dd72479c1 100644
--- a/doc/api/search.md
+++ b/doc/api/search.md
@@ -556,6 +556,7 @@ GET /projects/:id/search
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
| `scope` | string | yes | The scope to search in |
| `search` | string | yes | The search query |
+| `ref` | string | no | The name of a repository branch or tag to search on. The project's default branch is used by default. This is only applicable for scopes: commits, blobs, and wiki_blobs. |
Search the expression within the specified scope. Currently these scopes are supported: issues, merge_requests, milestones, notes, wiki_blobs, commits, blobs, users.
@@ -850,7 +851,7 @@ Blobs searches are performed on both filenames and contents. Search results:
times in the content.
```bash
-curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/6/search?scope=blobs&search=installation
+curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/6/search?scope=blobs&search=installation&ref=feature
```
Example response:
@@ -863,7 +864,7 @@ Example response:
"data": "```\n\n## Installation\n\nQuick start using the [pre-built",
"filename": "README.md",
"id": null,
- "ref": "master",
+ "ref": "feature",
"startline": 46,
"project_id": 6
}
diff --git a/doc/ci/examples/README.md b/doc/ci/examples/README.md
index 6b9f8181d1d..340a41c196b 100644
--- a/doc/ci/examples/README.md
+++ b/doc/ci/examples/README.md
@@ -18,30 +18,30 @@ Examples are available in several forms. As a collection of:
The following table lists examples for different use cases:
-| Use case | Resource |
-|:-----------------------------------------------|:---------------------------------------------------------------------------------------------------------------------|
-| Browser performance testing | [Browser Performance Testing with the Sitespeed.io container](browser_performance.md). |
-| Clojure | [Test a Clojure application with GitLab CI/CD](test-clojure-application.md). |
-| Code quality analysis | [Analyze your project's Code Quality](code_quality.md). **[STARTER]** |
-| Container scanning | [Container Scanning with GitLab CI/CD](container_scanning.md). |
-| Dependency scanning | [Dependency Scanning with GitLab CI/CD](dependency_scanning.md). **[ULTIMATE]** |
-| Deployment with `dpl` | [Using `dpl` as deployment tool](deployment/README.md). |
-| Dynamic application<br>security testing (DAST) | [Dynamic Application Security Testing with GitLab CI/CD](dast.md) **[ULTIMATE]** |
-| Elixir | [Testing a Phoenix application with GitLab CI/CD](test_phoenix_app_with_gitlab_ci_cd/index.md). |
-| Game development | [DevOps and Game Dev with GitLab CI/CD](devops_and_game_dev_with_gitlab_ci_cd/index.md). |
-| GitLab Pages | See the [GitLab Pages](../../user/project/pages/index.md) documentation for a complete example. |
-| Java | [Deploy a Spring Boot application to Cloud Foundry with GitLab CI/CD](deploy_spring_boot_to_cloud_foundry/index.md). |
-| JUnit | [JUnit test reports](../junit_test_reports.md). |
-| License management | [Dependencies license management with GitLab CI/CD](license_management.md) **[ULTIMATE]** |
-| Maven | [How to deploy Maven projects to Artifactory with GitLab CI/CD](artifactory_and_gitlab/index.md). |
-| PHP | [Testing PHP projects](php.md). |
-| PHP | [Running Composer and NPM scripts with deployment via SCP in GitLab CI/CD](deployment/composer-npm-deploy.md). |
-| PHP | [Test and deploy Laravel applications with GitLab CI/CD and Envoy](laravel_with_gitlab_and_envoy/index.md). |
-| Python | [Test and deploy a Python application with GitLab CI/CD](test-and-deploy-python-application-to-heroku.md). |
-| Ruby | [Test and deploy a Ruby application with GitLab CI/CD](test-and-deploy-ruby-application-to-heroku.md). |
-| Scala | [Test and deploy a Scala application to Heroku](test-scala-application.md). |
-| Static application<br>security testing (SAST) | [Static Application Security Testing with GitLab CI/CD](sast.md) **[ULTIMATE]** |
-| Testing | [End-to-end testing with GitLab CI/CD and WebdriverIO](end_to_end_testing_webdriverio/index.md). |
+| Use case | Resource |
+|:-----------------------------------------------|:------------------------------------------------------------------------------------------------------------------------|
+| Browser performance testing | [Browser Performance Testing with the Sitespeed.io container](browser_performance.md). |
+| Clojure | [Test a Clojure application with GitLab CI/CD](test-clojure-application.md). |
+| Code quality analysis | [Analyze your project's Code Quality](code_quality.md). **[STARTER]** |
+| Container scanning | [Container Scanning with GitLab CI/CD](../../user/application_security/container_scanning/index.md). **[ULTIMATE]** |
+| Dependency scanning | [Dependency Scanning with GitLab CI/CD](../../user/application_security/dependency_scanning/index.md). **[ULTIMATE]** |
+| Deployment with `dpl` | [Using `dpl` as deployment tool](deployment/README.md). |
+| Dynamic application<br>security testing (DAST) | [Dynamic Application Security Testing with GitLab CI/CD](../../user/application_security/dast/index.md). **[ULTIMATE]** |
+| Elixir | [Testing a Phoenix application with GitLab CI/CD](test_phoenix_app_with_gitlab_ci_cd/index.md). |
+| Game development | [DevOps and Game Dev with GitLab CI/CD](devops_and_game_dev_with_gitlab_ci_cd/index.md). |
+| GitLab Pages | See the [GitLab Pages](../../user/project/pages/index.md) documentation for a complete example. |
+| Java | [Deploy a Spring Boot application to Cloud Foundry with GitLab CI/CD](deploy_spring_boot_to_cloud_foundry/index.md). |
+| JUnit | [JUnit test reports](../junit_test_reports.md). |
+| License management | [Dependencies license management with GitLab CI/CD](../../user/application_security/license_management/index.md). **[ULTIMATE]** |
+| Maven | [How to deploy Maven projects to Artifactory with GitLab CI/CD](artifactory_and_gitlab/index.md). |
+| PHP | [Testing PHP projects](php.md). |
+| PHP | [Running Composer and NPM scripts with deployment via SCP in GitLab CI/CD](deployment/composer-npm-deploy.md). |
+| PHP | [Test and deploy Laravel applications with GitLab CI/CD and Envoy](laravel_with_gitlab_and_envoy/index.md). |
+| Python | [Test and deploy a Python application with GitLab CI/CD](test-and-deploy-python-application-to-heroku.md). |
+| Ruby | [Test and deploy a Ruby application with GitLab CI/CD](test-and-deploy-ruby-application-to-heroku.md). |
+| Scala | [Test and deploy a Scala application to Heroku](test-scala-application.md). |
+| Static application<br>security testing (SAST) | [Static Application Security Testing with GitLab CI/CD](../../user/application_security/sast/index.md). **[ULTIMATE]** |
+| Testing | [End-to-end testing with GitLab CI/CD and WebdriverIO](end_to_end_testing_webdriverio/index.md). |
### Contributing examples
diff --git a/doc/development/architecture.md b/doc/development/architecture.md
index 13de1f55f23..56c5056fd6d 100644
--- a/doc/development/architecture.md
+++ b/doc/development/architecture.md
@@ -212,6 +212,8 @@ To serve repositories over SSH there's an add-on application called gitlab-shell
### Components
+#### Component Diagram
+
```mermaid
graph TB
@@ -280,15 +282,15 @@ graph TB
```
----
-
-**Legend**:
+#### Component Legend
* ✅ - Automatically configured
* ⚙ - Requires additional configuration
* ⤓ - Additional software/service required
* ❌ - Not available
+#### Component Table
+
| Component | Description | [Omnibus GitLab](https://docs.gitlab.com/omnibus/README.html) | [GitLab chart](https://docs.gitlab.com/charts/) | [Minikube Minimal](https://docs.gitlab.com/charts/development/minikube/#deploying-gitlab-with-minimal-settings) | [GitLab.com](https://gitlab.com) | CE/EE |
| --------- | ----------- |:--------------------:|:------------------:|:-----:|:--------:|:--------:|
| NGINX | Routes requests to appropriate components, terminates SSL | [✅](https://docs.gitlab.com/omnibus/settings/nginx.html) | [✅](https://docs.gitlab.com/charts/charts/nginx/index.html) | [⚙](https://docs.gitlab.com/charts/charts/nginx/index.html) | [✅](https://about.gitlab.com/handbook/engineering/infrastructure/production-architecture/#service-architecture) | CE & EE |
@@ -326,6 +328,8 @@ graph TB
| Jaeger: deployed apps | Distributed tracing for deployed apps | [⤓](https://docs.gitlab.com/ee/user/project/operations/tracing.html) | [⤓](https://docs.gitlab.com/ee/user/project/operations/tracing.html) | [⤓](https://docs.gitlab.com/ee/user/project/operations/tracing.html) | [⤓](https://docs.gitlab.com/ee/user/project/operations/tracing.html) | EE Only |
| Kubernetes cluster apps | Deploy [Helm](https://docs.helm.sh/), [Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/), [Cert-Manager](https://docs.cert-manager.io/en/latest/), [Prometheus](https://prometheus.io/docs/introduction/overview/), a [Runner](https://docs.gitlab.com/runner/), [JupyterHub](http://jupyter.org/), [Knative](https://cloud.google.com/knative) to a cluster | [✅](https://docs.gitlab.com/ee/user/project/clusters/#installing-applications) | [✅](https://docs.gitlab.com/ee/user/project/clusters/#installing-applications) | [✅](https://docs.gitlab.com/ee/user/project/clusters/#installing-applications) | [✅](https://docs.gitlab.com/ee/user/project/clusters/#installing-applications) | CE & EE |
+#### Component Overview
+
A typical install of GitLab will be on GNU/Linux. It uses Nginx or Apache as a web front end to proxypass the Unicorn web server. By default, communication between Unicorn and the front end is via a Unix domain socket but forwarding requests via TCP is also supported. The web front end accesses `/home/git/gitlab/public` bypassing the Unicorn server to serve static pages, uploads (e.g. avatar images or attachments), and precompiled assets. GitLab serves web pages and a [GitLab API](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/api) using the Unicorn web server. It uses Sidekiq as a job queue which, in turn, uses redis as a non-persistent database backend for job information, meta data, and incoming jobs.
We also support deploying GitLab on Kubernetes using our [gitlab Helm chart](https://docs.gitlab.com/charts/).
diff --git a/doc/development/ee_features.md b/doc/development/ee_features.md
index 8706fe537fa..9db28bcddf8 100644
--- a/doc/development/ee_features.md
+++ b/doc/development/ee_features.md
@@ -446,16 +446,28 @@ The disadvantage of this:
port `render_if_exists` to CE.
- If we have typos in the partial name, it would be silently ignored.
+
+##### Caveats
+
The `render_if_exists` view path argument must be relative to `app/views/` and `ee/app/views`.
Resolving an EE template path that is relative to the CE view path will not work.
```haml
- # app/views/projects/index.html.haml
-= render_if_exists 'button' # Will not render `ee/app/views/projects/_button` and quietly fail
+= render_if_exists 'button' # Will not render `ee/app/views/projects/_button` and will quietly fail
= render_if_exists 'projects/button' # Will render `ee/app/views/projects/_button`
```
+You should not explicitly set render options like `partial` or provide a `locals` hash.
+The first argument should be a path string and the second can be a hash replacing `locals`.
+
+```ruby
+render partial: 'projects/button', locals: { project: project }
+# becomes
+render_if_exists 'projects/button', project: project
+```
+
#### Using `render_ce`
For `render` and `render_if_exists`, they search for the EE partial first,
diff --git a/doc/development/testing_guide/review_apps.md b/doc/development/testing_guide/review_apps.md
index 7ad33f05f77..f34793c11f4 100644
--- a/doc/development/testing_guide/review_apps.md
+++ b/doc/development/testing_guide/review_apps.md
@@ -78,17 +78,27 @@ subgraph CNG-mirror pipeline
**Additional notes:**
-- The Kubernetes cluster is connected to the `gitlab-{ce,ee}` projects using
- [GitLab's Kubernetes integration][gitlab-k8s-integration]. This basically
- allows to have a link to the Review App directly from the merge request
- widget.
-- If the Review App deployment fails, you can simply retry it (there's no need
- to run the [`review-stop`][gitlab-ci-yml] job first).
+- If the `review-deploy` job keep failing (note that we already retry it twice),
+ please post a message in the `#quality` channel and/or create a ~Quality ~bug
+ issue with a link to your merge request. Note that the deployment failure can
+ reveal an actual problem introduced in your merge request (i.e. this isn't
+ necessarily a transient failure)!
+- If the `review-qa-smoke` job keep failing (note that we already retry it twice),
+ please check the job's logs: you could discover an actual problem introduced in
+ your merge request. You can also download the artifacts to see screenshots of
+ the page at the time the failures occurred. If you don't find the cause of the
+ failure or if it seems unrelated to your change, please post a message in the
+ `#quality` channel and/or create a ~Quality ~bug issue with a link to your
+ merge request.
- The manual [`review-stop`][gitlab-ci-yml] in the `test` stage can be used to
stop a Review App manually, and is also started by GitLab once a merge
request's branch is deleted after being merged.
- Review Apps are cleaned up regularly via a pipeline schedule that runs
the [`schedule:review-cleanup`][gitlab-ci-yml] job.
+- The Kubernetes cluster is connected to the `gitlab-{ce,ee}` projects using
+ [GitLab's Kubernetes integration][gitlab-k8s-integration]. This basically
+ allows to have a link to the Review App directly from the merge request
+ widget.
## QA runs
diff --git a/doc/install/ldap.md b/doc/install/ldap.md
index a19f0342b65..d8d54864586 100644
--- a/doc/install/ldap.md
+++ b/doc/install/ldap.md
@@ -2,6 +2,4 @@
redirect_to: '../administration/auth/ldap.md'
---
-# GitLab LDAP integration
-
-This document was moved under [`administration/auth/ldap`](../administration/auth/ldap.md).
+This document was moved to [another location](../administration/auth/ldap.md).
diff --git a/doc/integration/elasticsearch.md b/doc/integration/elasticsearch.md
index b03bb6d98e8..d1d12dfd064 100644
--- a/doc/integration/elasticsearch.md
+++ b/doc/integration/elasticsearch.md
@@ -131,6 +131,8 @@ The following Elasticsearch settings are available:
| `Use the new repository indexer (beta)` | Perform repository indexing using [GitLab Elasticsearch Indexer](https://gitlab.com/gitlab-org/gitlab-elasticsearch-indexer). |
| `Search with Elasticsearch enabled` | Enables/disables using Elasticsearch in search. |
| `URL` | The URL to use for connecting to Elasticsearch. Use a comma-separated list to support clustering (e.g., "http://host1, https://host2:9200"). If your Elasticsearch instance is password protected, pass the `username:password` in the URL (e.g., `http://<username>:<password>@<elastic_host>:9200/`). |
+| `Number of Elasticsearch shards` | Elasticsearch indexes are split into multiple shards for performance reasons. In general, larger indexes need to have more shards. Changes to this value do not take effect until the index is recreated. You can read more about tradeoffs in the [Elasticsearch documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-create-index.html#create-index-settings) |
+| `Number of Elasticsearch replicas` | Each Elasticsearch shard can have a number of replicas. These are a complete copy of the shard, and can provide increased query performance or resilience against hardware failure. Increasing this value will greatly increase total disk space required by the index. |
| `Limit namespaces and projects that can be indexed` | Enabling this will allow you to select namespaces and projects to index. All other namespaces and projects will use database search instead. Please note that if you enable this option but do not select any namespaces or projects, none will be indexed. [Read more below](#limiting-namespaces-and-projects).
| `Using AWS hosted Elasticsearch with IAM credentials` | Sign your Elasticsearch requests using [AWS IAM authorization](http://docs.aws.amazon.com/IAM/latest/UserGuide/id_credentials_access-keys.html) or [AWS EC2 Instance Profile Credentials](http://docs.aws.amazon.com/codedeploy/latest/userguide/getting-started-create-iam-instance-profile.html#getting-started-create-iam-instance-profile-cli). The policies must be configured to allow `es:*` actions. |
| `AWS Region` | The AWS region your Elasticsearch service is located in. |
diff --git a/doc/license/README.md b/doc/license/README.md
index 4cc387ba95f..b9281fd5299 100644
--- a/doc/license/README.md
+++ b/doc/license/README.md
@@ -2,4 +2,4 @@
redirect_to: 'https://docs.gitlab.com/ee/user/admin_area/license.html'
---
-This document was moved to [user/admin_area/license](https://docs.gitlab.com/ee/user/admin_area/license.html).
+This document was moved to [another location](https://docs.gitlab.com/ee/user/admin_area/license.html).
diff --git a/doc/topics/authentication/index.md b/doc/topics/authentication/index.md
index 0531627b7b3..00b6c1dfdc2 100644
--- a/doc/topics/authentication/index.md
+++ b/doc/topics/authentication/index.md
@@ -17,11 +17,11 @@ This page gathers all the resources for the topic **Authentication** within GitL
## GitLab administrators
- [LDAP (Community Edition)](../../administration/auth/ldap.md)
-- [LDAP (Enterprise Edition)](https://docs.gitlab.com/ee/administration/auth/ldap-ee.html)
+- [LDAP (Enterprise Edition)](https://docs.gitlab.com/ee/administration/auth/ldap-ee.html) **[STARTER]**
- [Enforce Two-factor Authentication (2FA)](../../security/two_factor_authentication.md#enforce-two-factor-authentication-2fa)
- **Articles:**
- [How to Configure LDAP with GitLab CE](../../administration/auth/how_to_configure_ldap_gitlab_ce/index.md)
- - [How to Configure LDAP with GitLab EE](https://docs.gitlab.com/ee/administration/auth/how_to_configure_ldap_gitlab_ee/index.html)
+ - [How to Configure LDAP with GitLab EE](https://docs.gitlab.com/ee/administration/auth/how_to_configure_ldap_gitlab_ee/index.html) **[STARTER]**
- [Feature Highlight: LDAP Integration](https://about.gitlab.com/2014/07/10/feature-highlight-ldap-sync/)
- [Debugging LDAP](https://about.gitlab.com/handbook/support/workflows/support-engineering/ldap/debugging_ldap.html)
- **Integrations:**
@@ -30,10 +30,10 @@ This page gathers all the resources for the topic **Authentication** within GitL
- [Atlassian Crowd OmniAuth Provider](../../administration/auth/crowd.md)
- [CAS OmniAuth Provider](../../integration/cas.md)
- [SAML OmniAuth Provider](../../integration/saml.md)
- - [SAML for GitLab.com Groups](https://docs.gitlab.com/ee/user/group/saml_sso/index.html)
- - [SCIM user provisioning for GitLab.com Groups](https://docs.gitlab.com/ee/user/group/saml_sso/scim_setup.html)
+ - [SAML for GitLab.com Groups](https://docs.gitlab.com/ee/user/group/saml_sso/index.html) **[SILVER ONLY]**
+ - [SCIM user provisioning for GitLab.com Groups](https://docs.gitlab.com/ee/user/group/saml_sso/scim_setup.html) **[SILVER ONLY]**
- [Okta SSO provider](../../administration/auth/okta.md)
- - [Kerberos integration (GitLab EE)](https://docs.gitlab.com/ee/integration/kerberos.html)
+ - [Kerberos integration (GitLab EE)](https://docs.gitlab.com/ee/integration/kerberos.html) **[STARTER]**
## API
diff --git a/doc/user/admin_area/settings/continuous_integration.md b/doc/user/admin_area/settings/continuous_integration.md
index 42fc4efa4ce..9dd476656ed 100644
--- a/doc/user/admin_area/settings/continuous_integration.md
+++ b/doc/user/admin_area/settings/continuous_integration.md
@@ -118,7 +118,15 @@ will be synced to your Group and you can visualize it from the
![Additional minutes](img/additional_minutes.png)
-NOTE: **Important note**: If you have some minutes used over your default quota, these minutes will
+Be aware that:
+
+1. If you have purchased extra CI minutes before the purchase of a paid plan,
+we will calculate a pro-rated charge for your paid plan. That means you may
+be charged for less than one year since your subscription was previously
+created with the extra CI minutes.
+1. Once the extra CI minutes has been assigned to a Group they cannot be transferred
+to a different Group.
+1. If you have some minutes used over your default quota, these minutes will
be deducted from your Additional Minutes quota immediately after your purchase of additional
minutes.
diff --git a/doc/user/application_security/container_scanning/index.md b/doc/user/application_security/container_scanning/index.md
index ce86ade3c1a..5c635b09503 100644
--- a/doc/user/application_security/container_scanning/index.md
+++ b/doc/user/application_security/container_scanning/index.md
@@ -122,12 +122,13 @@ container_scanning:
## https://docs.gitlab.com/ee/ci/variables/#predefined-environment-variables
CI_APPLICATION_REPOSITORY: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG
CI_APPLICATION_TAG: $CI_COMMIT_SHA
+ CLAIR_LOCAL_SCAN_VERSION: v2.0.8_fe9b059d930314b54c78f75afe265955faf4fdc1
allow_failure: true
services:
- docker:stable-dind
script:
- docker run -d --name db arminc/clair-db:latest
- - docker run -p 6060:6060 --link db:postgres -d --name clair --restart on-failure arminc/clair-local-scan:v2.0.6
+ - docker run -p 6060:6060 --link db:postgres -d --name clair --restart on-failure arminc/clair-local-scan:${CLAIR_LOCAL_SCAN_VERSION}
- apk add -U wget ca-certificates
- docker pull ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG}
- wget https://github.com/arminc/clair-scanner/releases/download/v8/clair-scanner_linux_amd64
@@ -164,12 +165,13 @@ container_scanning:
## https://docs.gitlab.com/ee/ci/variables/#predefined-environment-variables
CI_APPLICATION_REPOSITORY: $CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG
CI_APPLICATION_TAG: $CI_COMMIT_SHA
+ CLAIR_LOCAL_SCAN_VERSION: v2.0.8_fe9b059d930314b54c78f75afe265955faf4fdc1
allow_failure: true
services:
- docker:stable-dind
script:
- docker run -d --name db arminc/clair-db:latest
- - docker run -p 6060:6060 --link db:postgres -d --name clair --restart on-failure arminc/clair-local-scan:v2.0.6
+ - docker run -p 6060:6060 --link db:postgres -d --name clair --restart on-failure arminc/clair-local-scan:${CLAIR_LOCAL_SCAN_VERSION}
- apk add -U wget ca-certificates
- docker pull ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG}
- wget https://github.com/arminc/clair-scanner/releases/download/v8/clair-scanner_linux_amd64
diff --git a/doc/user/group/saml_sso/index.md b/doc/user/group/saml_sso/index.md
index ee3137d032e..53116606201 100644
--- a/doc/user/group/saml_sso/index.md
+++ b/doc/user/group/saml_sso/index.md
@@ -22,8 +22,16 @@ SAML SSO for groups is used only as a convenient way to add users and does not s
![Issuer and callback for configuring SAML identity provider with GitLab.com](img/group_saml_configuration_information.png)
-NOTE: **Note:**
-Partial SSO enforcement was introduced in [11.8](https://gitlab.com/gitlab-org/gitlab-ee/issues/5291). With this option enabled, users must use your group's GitLab single sign on URL to be added to the group or be added via SCIM. Users can no longer be added manually. After a user has been added to the group, GitLab does not continue to enforce the use of SSO, but we'll [add a persistent check](https://gitlab.com/gitlab-org/gitlab-ee/issues/9255) in a later version.
+### SSO enforcement
+
+SSO enforcement was:
+
+- [Introduced in GitLab 11.8](https://gitlab.com/gitlab-org/gitlab-ee/issues/5291).
+- [Improved upon in GitLab 11.11 with ongoing enforcement in the GitLab UI](https://gitlab.com/gitlab-org/gitlab-ee/issues/9255).
+
+With this option enabled, users must use your group's GitLab single sign on URL to be added to the group or be added via SCIM. Users cannot be added manually, and may only access project/group resources via the UI by signing in through the SSO URL.
+
+We intend to add a similar SSO requirement for [Git and API activity](https://gitlab.com/gitlab-org/gitlab-ee/issues/9152) in the future.
### NameID
diff --git a/doc/user/markdown.md b/doc/user/markdown.md
index c4f9fe45211..5dad9621802 100644
--- a/doc/user/markdown.md
+++ b/doc/user/markdown.md
@@ -286,15 +286,15 @@ On Linux, you can download [Noto Color Emoji](https://www.google.com/get/noto/he
Ubuntu 18.04 (like many modern Linux distros) has this font installed by default.
```
-Sometimes you want to <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/public/-/emojis/1/monkey.png" width="20px" height="20px" style="display:inline;margin:0"> around a bit and add some <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/public/-/emojis/1/star2.png" width="20px" height="20px" style="display:inline;margin:0"> to your <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/public/-/emojis/1/speech_balloon.png" width="20px" height="20px" style="display:inline;margin:0">. Well we have a gift for you:
+Sometimes you want to <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/app/assets/images/emoji/monkey.png" width="20px" height="20px" style="display:inline;margin:0"> around a bit and add some <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/app/assets/images/emoji/star2.png" width="20px" height="20px" style="display:inline;margin:0"> to your <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/app/assets/images/emoji/speech_balloon.png" width="20px" height="20px" style="display:inline;margin:0">. Well we have a gift for you:
-<img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/public/-/emojis/1/zap.png" width="20px" height="20px" style="display:inline;margin:0">You can use emoji anywhere GFM is supported. <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/public/-/emojis/1/v.png" width="20px" height="20px" style="display:inline;margin:0">
+<img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/app/assets/images/emoji/zap.png" width="20px" height="20px" style="display:inline;margin:0">You can use emoji anywhere GFM is supported. <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/app/assets/images/emoji/v.png" width="20px" height="20px" style="display:inline;margin:0">
-You can use it to point out a <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/public/-/emojis/1/bug.png" width="20px" height="20px" style="display:inline;margin:0"> or warn about <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/public/-/emojis/1/speak_no_evil.png" width="20px" height="20px" style="display:inline;margin:0"> patches. And if someone improves your really <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/public/-/emojis/1/snail.png" width="20px" height="20px" style="display:inline;margin:0"> code, send them some <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/public/-/emojis/1/birthday.png" width="20px" height="20px" style="display:inline;margin:0">. People will <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/public/-/emojis/1/heart.png" width="20px" height="20px" style="display:inline;margin:0"> you for that.
+You can use it to point out a <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/app/assets/images/emoji/bug.png" width="20px" height="20px" style="display:inline;margin:0"> or warn about <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/app/assets/images/emoji/speak_no_evil.png" width="20px" height="20px" style="display:inline;margin:0"> patches. And if someone improves your really <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/app/assets/images/emoji/snail.png" width="20px" height="20px" style="display:inline;margin:0"> code, send them some <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/app/assets/images/emoji/birthday.png" width="20px" height="20px" style="display:inline;margin:0">. People will <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/app/assets/images/emoji/heart.png" width="20px" height="20px" style="display:inline;margin:0"> you for that.
-If you are new to this, don't be <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/public/-/emojis/1/fearful.png" width="20px" height="20px" style="display:inline;margin:0">. You can easily join the emoji <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/public/-/emojis/1/family.png" width="20px" height="20px" style="display:inline;margin:0">. All you need to do is to look up one of the supported codes.
+If you are new to this, don't be <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/app/assets/images/emoji/fearful.png" width="20px" height="20px" style="display:inline;margin:0">. You can easily join the emoji <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/app/assets/images/emoji/family.png" width="20px" height="20px" style="display:inline;margin:0">. All you need to do is to look up one of the supported codes.
-Consult the [Emoji Cheat Sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) for a list of all supported emoji codes. <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/public/-/emojis/1/thumbsup.png" width="20px" height="20px" style="display:inline;margin:0">
+Consult the [Emoji Cheat Sheet](https://www.webfx.com/tools/emoji-cheat-sheet/) for a list of all supported emoji codes. <img src="https://gitlab.com/gitlab-org/gitlab-ce/raw/master/app/assets/images/emoji/thumbsup.png" width="20px" height="20px" style="display:inline;margin:0">
Most emoji are natively supported on macOS, Windows, iOS, Android and will fallback to image-based emoji where there is lack of support.
diff --git a/doc/user/project/merge_requests/img/container_scanning.png b/doc/user/project/merge_requests/img/container_scanning.png
deleted file mode 100644
index e47f62acd9d..00000000000
--- a/doc/user/project/merge_requests/img/container_scanning.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/create-issue-with-list-hover.png b/doc/user/project/merge_requests/img/create-issue-with-list-hover.png
deleted file mode 100644
index 7d70e8299f5..00000000000
--- a/doc/user/project/merge_requests/img/create-issue-with-list-hover.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/dast_all.png b/doc/user/project/merge_requests/img/dast_all.png
deleted file mode 100644
index b6edc928dc3..00000000000
--- a/doc/user/project/merge_requests/img/dast_all.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/dast_single.png b/doc/user/project/merge_requests/img/dast_single.png
deleted file mode 100644
index 26ca4bde786..00000000000
--- a/doc/user/project/merge_requests/img/dast_single.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/dependency_scanning.png b/doc/user/project/merge_requests/img/dependency_scanning.png
deleted file mode 100644
index 18df356f846..00000000000
--- a/doc/user/project/merge_requests/img/dependency_scanning.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/interactive_reports.png b/doc/user/project/merge_requests/img/interactive_reports.png
deleted file mode 100644
index 9f9812dc69d..00000000000
--- a/doc/user/project/merge_requests/img/interactive_reports.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/license_management.png b/doc/user/project/merge_requests/img/license_management.png
deleted file mode 100644
index cdce6b5fe38..00000000000
--- a/doc/user/project/merge_requests/img/license_management.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/license_management_decision.png b/doc/user/project/merge_requests/img/license_management_decision.png
deleted file mode 100644
index 0763130c375..00000000000
--- a/doc/user/project/merge_requests/img/license_management_decision.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/license_management_pipeline_tab.png b/doc/user/project/merge_requests/img/license_management_pipeline_tab.png
deleted file mode 100644
index 80ffca815b9..00000000000
--- a/doc/user/project/merge_requests/img/license_management_pipeline_tab.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/license_management_settings.png b/doc/user/project/merge_requests/img/license_management_settings.png
deleted file mode 100644
index b5490e59074..00000000000
--- a/doc/user/project/merge_requests/img/license_management_settings.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/revert_changes_commit.png b/doc/user/project/merge_requests/img/revert_changes_commit.png
deleted file mode 100644
index c9dd0019024..00000000000
--- a/doc/user/project/merge_requests/img/revert_changes_commit.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/revert_changes_mr.png b/doc/user/project/merge_requests/img/revert_changes_mr.png
deleted file mode 100644
index 06b841b3002..00000000000
--- a/doc/user/project/merge_requests/img/revert_changes_mr.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/sast.png b/doc/user/project/merge_requests/img/sast.png
deleted file mode 100644
index 2c75592c32a..00000000000
--- a/doc/user/project/merge_requests/img/sast.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/security_report.png b/doc/user/project/merge_requests/img/security_report.png
deleted file mode 100644
index ba41b707238..00000000000
--- a/doc/user/project/merge_requests/img/security_report.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/img/vulnerability_solution.png b/doc/user/project/merge_requests/img/vulnerability_solution.png
deleted file mode 100644
index 7443b9b6eea..00000000000
--- a/doc/user/project/merge_requests/img/vulnerability_solution.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/project/merge_requests/merge_request_approvals.md b/doc/user/project/merge_requests/merge_request_approvals.md
index 265871a7b4b..ea86633d9e2 100644
--- a/doc/user/project/merge_requests/merge_request_approvals.md
+++ b/doc/user/project/merge_requests/merge_request_approvals.md
@@ -294,6 +294,18 @@ enabling [**Prevent approval of merge requests by their committers**](#prevent-a
1. Tick the checkbox **Prevent approval of merge requests by their committers**.
1. Click **Save changes**.
+## Require authentication when approving a merge request **[STARTER]**
+
+> [Introduced](https://gitlab.com/gitlab-org/gitlab-ee/issues/5981) in [GitLab Starter](https://about.gitlab.com/pricing/) 12.0.
+
+You can force the approver to enter a password in order to authenticate who is approving the merge request by
+enabling **Require user password to approve**. This enables an Electronic Signature
+for approvals such as the one defined by [CFR Part 11](https://www.accessdata.fda.gov/scripts/cdrh/cfdocs/cfcfr/CFRSearch.cfm?CFRPart=11&showFR=1&subpartNode=21:1.0.1.1.8.3)):
+
+1. Navigate to your project's **Settings > General** and expand **Merge request approvals**.
+1. Tick the checkbox **Require user password to approve**.
+1. Click **Save changes**.
+
## Merge requests with different source branch and target branch projects
If the merge request source branch and target branch belong to different
diff --git a/lib/api/search.rb b/lib/api/search.rb
index 60095300ea1..1cab1a97186 100644
--- a/lib/api/search.rb
+++ b/lib/api/search.rb
@@ -112,12 +112,13 @@ module API
type: String,
desc: 'The scope of the search',
values: Helpers::SearchHelpers.project_search_scopes
+ optional :ref, type: String, desc: 'The name of a repository branch or tag. If not given, the default branch is used'
use :pagination
end
get ':id/(-/)search' do
check_users_search_allowed!
- present search(project_id: user_project.id), with: entity
+ present search({ project_id: user_project.id, repository_ref: params[:ref] }), with: entity
end
end
end
diff --git a/lib/gitlab/danger/helper.rb b/lib/gitlab/danger/helper.rb
index 3ef19d801b7..f0ca397609d 100644
--- a/lib/gitlab/danger/helper.rb
+++ b/lib/gitlab/danger/helper.rb
@@ -121,6 +121,8 @@ module Gitlab
\.prettierrc |
\.scss-lint.yml |
\.stylelintrc |
+ \.haml-lint.yml |
+ \.haml-lint_todo.yml |
babel\.config\.js |
jest\.config\.js |
karma\.config\.js |
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index fc9bcbdcca2..455588f3c66 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -500,7 +500,7 @@ module Gitlab
end
# Return total diverging commits count
- def diverging_commit_count(from, to, max_count:)
+ def diverging_commit_count(from, to, max_count: 0)
wrapped_gitaly_errors do
gitaly_commit_client.diverging_commit_count(from, to, max_count: max_count)
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 9883622669c..5800aa9604b 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -5935,7 +5935,7 @@ msgstr ""
msgid "MergeRequest|Error loading full diff. Please try again."
msgstr ""
-msgid "MergeRequest|Filter files"
+msgid "MergeRequest|Filter files or search with %{modifier_key}+p"
msgstr ""
msgid "MergeRequest|No files found"
@@ -7280,9 +7280,6 @@ msgstr ""
msgid "Profiles|The maximum file size allowed is 200KB."
msgstr ""
-msgid "Profiles|There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
-msgstr ""
-
msgid "Profiles|This doesn't look like a public SSH key, are you sure you want to add it?"
msgstr ""
diff --git a/scripts/clean-old-cached-assets b/scripts/clean-old-cached-assets
index 7a3a62a477a..8bdd3a9cdb6 100755
--- a/scripts/clean-old-cached-assets
+++ b/scripts/clean-old-cached-assets
@@ -1,6 +1,6 @@
#!/bin/bash
-# Clean up cached files that are older than 1 week
-find tmp/cache/assets/sprockets/ -type f -mtime +7 -execdir rm -- "{}" \;
+# Clean up cached files that are older than 4 days
+find tmp/cache/assets/sprockets/ -type f -mtime +4 -execdir rm -- "{}" \;
du -d 0 -h tmp/cache/assets/sprockets | cut -f1 | xargs -I % echo "tmp/cache/assets/sprockets/ is currently %"
diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb
index 088c515c3a6..9a598790ff2 100644
--- a/spec/controllers/registrations_controller_spec.rb
+++ b/spec/controllers/registrations_controller_spec.rb
@@ -46,13 +46,17 @@ describe RegistrationsController do
end
context 'when reCAPTCHA is enabled' do
+ def fail_recaptcha
+ # Without this, `verify_recaptcha` arbitrarily returns true in test env
+ Recaptcha.configuration.skip_verify_env.delete('test')
+ end
+
before do
stub_application_setting(recaptcha_enabled: true)
end
it 'displays an error when the reCAPTCHA is not solved' do
- # Without this, `verify_recaptcha` arbitrarily returns true in test env
- Recaptcha.configuration.skip_verify_env.delete('test')
+ fail_recaptcha
post(:create, params: user_params)
@@ -70,6 +74,17 @@ describe RegistrationsController do
expect(flash[:notice]).to include 'Welcome! You have signed up successfully.'
end
+
+ it 'does not require reCAPTCHA if disabled by feature flag' do
+ stub_feature_flags(registrations_recaptcha: false)
+ fail_recaptcha
+
+ post(:create, params: user_params)
+
+ expect(controller).not_to receive(:verify_recaptcha)
+ expect(flash[:alert]).to be_nil
+ expect(flash[:notice]).to include 'Welcome! You have signed up successfully.'
+ end
end
context 'when terms are enforced' do
diff --git a/spec/frontend/helpers/timeout.js b/spec/frontend/helpers/timeout.js
index 318593a48a4..b30b7f1ce1e 100644
--- a/spec/frontend/helpers/timeout.js
+++ b/spec/frontend/helpers/timeout.js
@@ -1,24 +1,31 @@
-let testTimeoutInMs;
+const NS_PER_SEC = 1e9;
+const NS_PER_MS = 1e6;
-export const setTestTimeout = newTimeoutInMs => {
- testTimeoutInMs = newTimeoutInMs;
- jest.setTimeout(newTimeoutInMs);
+let testTimeoutNS;
+
+export const setTestTimeout = newTimeoutMS => {
+ testTimeoutNS = newTimeoutMS * NS_PER_MS;
+ jest.setTimeout(newTimeoutMS);
};
-export const initializeTestTimeout = defaultTimeoutInMs => {
- setTestTimeout(defaultTimeoutInMs);
+export const initializeTestTimeout = defaultTimeoutMS => {
+ setTestTimeout(defaultTimeoutMS);
let testStartTime;
// https://github.com/facebook/jest/issues/6947
beforeEach(() => {
- testStartTime = Date.now();
+ testStartTime = process.hrtime();
});
afterEach(() => {
- const elapsedTimeInMs = Date.now() - testStartTime;
- if (elapsedTimeInMs > testTimeoutInMs) {
- throw new Error(`Test took too long (${elapsedTimeInMs}ms > ${testTimeoutInMs}ms)!`);
+ const [seconds, remainingNs] = process.hrtime(testStartTime);
+ const elapsedNS = seconds * NS_PER_SEC + remainingNs;
+
+ if (elapsedNS > testTimeoutNS) {
+ throw new Error(
+ `Test took too long (${elapsedNS / NS_PER_MS}ms > ${testTimeoutNS / NS_PER_MS}ms)!`,
+ );
}
});
};
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 9ff0f355fd4..c5ab7e57272 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -2286,12 +2286,45 @@ describe Repository do
end
describe '#diverging_commit_counts' do
+ let(:diverged_branch) { repository.find_branch('fix') }
+ let(:root_ref_sha) { repository.raw_repository.commit(repository.root_ref).id }
+ let(:diverged_branch_sha) { diverged_branch.dereferenced_target.sha }
+
it 'returns the commit counts behind and ahead of default branch' do
- result = repository.diverging_commit_counts(
- repository.find_branch('fix'))
+ result = repository.diverging_commit_counts(diverged_branch)
expect(result).to eq(behind: 29, ahead: 2)
end
+
+ context 'when gitaly_count_diverging_commits_no_max is enabled' do
+ before do
+ stub_feature_flags(gitaly_count_diverging_commits_no_max: true)
+ end
+
+ it 'calls diverging_commit_count without max count' do
+ expect(repository.raw_repository)
+ .to receive(:diverging_commit_count)
+ .with(root_ref_sha, diverged_branch_sha)
+ .and_return([29, 2])
+
+ repository.diverging_commit_counts(diverged_branch)
+ end
+ end
+
+ context 'when gitaly_count_diverging_commits_no_max is disabled' do
+ before do
+ stub_feature_flags(gitaly_count_diverging_commits_no_max: false)
+ end
+
+ it 'calls diverging_commit_count with max count' do
+ expect(repository.raw_repository)
+ .to receive(:diverging_commit_count)
+ .with(root_ref_sha, diverged_branch_sha, max_count: Repository::MAX_DIVERGING_COUNT)
+ .and_return([29, 2])
+
+ repository.diverging_commit_counts(diverged_branch)
+ end
+ end
end
describe '#refresh_method_caches' do
diff --git a/spec/requests/api/search_spec.rb b/spec/requests/api/search_spec.rb
index 49672591b3b..7d61ec9c4d8 100644
--- a/spec/requests/api/search_spec.rb
+++ b/spec/requests/api/search_spec.rb
@@ -414,6 +414,13 @@ describe API::Search do
expect(response).to have_gitlab_http_status(200)
expect(json_response.size).to eq(11)
end
+
+ it 'by ref' do
+ get api("/projects/#{repo_project.id}/search", user), params: { scope: 'blobs', search: 'This file is used in tests for ci_environments_status', ref: 'pages-deploy' }
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(json_response.size).to eq(1)
+ end
end
end
end
diff --git a/spec/uploaders/personal_file_uploader_spec.rb b/spec/uploaders/personal_file_uploader_spec.rb
index 97758f0243e..d9f0e2f3cb7 100644
--- a/spec/uploaders/personal_file_uploader_spec.rb
+++ b/spec/uploaders/personal_file_uploader_spec.rb
@@ -7,33 +7,19 @@ describe PersonalFileUploader do
subject { uploader }
- it_behaves_like 'builds correct paths',
- store_dir: %r[uploads/-/system/personal_snippet/\d+],
- upload_path: %r[\h+/\S+],
- absolute_path: %r[#{CarrierWave.root}/uploads/-/system/personal_snippet\/\d+\/\h+\/\S+$]
-
- context "object_store is REMOTE" do
+ shared_examples '#base_dir' do
before do
- stub_uploads_object_storage
+ subject.instance_variable_set(:@secret, 'secret')
end
- include_context 'with storage', described_class::Store::REMOTE
-
- it_behaves_like 'builds correct paths',
- store_dir: %r[\d+/\h+],
- upload_path: %r[^personal_snippet\/\d+\/\h+\/<filename>]
- end
-
- describe '#upload_paths' do
- it 'builds correct paths for both local and remote storage' do
- paths = uploader.upload_paths('test.jpg')
+ it 'is prefixed with uploads/-/system' do
+ allow(uploader).to receive(:file).and_return(double(extension: 'txt', filename: 'file_name'))
- expect(paths.first).to match(%r[\h+\/test.jpg])
- expect(paths.second).to match(%r[^personal_snippet\/\d+\/\h+\/test.jpg])
+ expect(described_class.base_dir(model)).to eq("uploads/-/system/personal_snippet/#{model.id}")
end
end
- describe '#to_h' do
+ shared_examples '#to_h' do
before do
subject.instance_variable_set(:@secret, 'secret')
end
@@ -50,6 +36,40 @@ describe PersonalFileUploader do
end
end
+ describe '#upload_paths' do
+ it 'builds correct paths for both local and remote storage' do
+ paths = uploader.upload_paths('test.jpg')
+
+ expect(paths.first).to match(%r[\h+\/test.jpg])
+ expect(paths.second).to match(%r[^personal_snippet\/\d+\/\h+\/test.jpg])
+ end
+ end
+
+ context 'object_store is LOCAL' do
+ it_behaves_like 'builds correct paths',
+ store_dir: %r[uploads/-/system/personal_snippet/\d+/\h+],
+ upload_path: %r[\h+/\S+],
+ absolute_path: %r[#{CarrierWave.root}/uploads/-/system/personal_snippet\/\d+\/\h+\/\S+$]
+
+ it_behaves_like '#base_dir'
+ it_behaves_like '#to_h'
+ end
+
+ context "object_store is REMOTE" do
+ before do
+ stub_uploads_object_storage
+ end
+
+ include_context 'with storage', described_class::Store::REMOTE
+
+ it_behaves_like 'builds correct paths',
+ store_dir: %r[\d+/\h+],
+ upload_path: %r[^personal_snippet\/\d+\/\h+\/<filename>]
+
+ it_behaves_like '#base_dir'
+ it_behaves_like '#to_h'
+ end
+
describe "#migrate!" do
before do
uploader.store!(fixture_file_upload('spec/fixtures/doc_sample.txt'))