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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-09-15 12:09:47 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-09-15 12:09:47 +0300
commit33f96e8df089c2291010598c50ec6868ab8cb1ef (patch)
tree1c9276a56a62e464fc68fa58780647c93f0045cf
parent034e7d969a591605267c0e5ddbe6f2228bf8e43d (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--GITLAB_KAS_VERSION2
-rw-r--r--Gemfile2
-rw-r--r--Gemfile.lock4
-rw-r--r--app/assets/javascripts/design_management/components/design_sidebar.vue2
-rw-r--r--app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue54
-rw-r--r--app/controllers/projects/service_desk_controller.rb33
-rw-r--r--app/models/environment.rb36
-rw-r--r--app/models/release.rb1
-rw-r--r--app/models/repository.rb6
-rw-r--r--app/models/service_desk_setting.rb12
-rw-r--r--app/views/admin/application_settings/_ip_limits.html.haml70
-rw-r--r--config/feature_flags/development/environment_last_visible_pipeline_disable_joins.yml8
-rw-r--r--config/feature_flags/development/find_tag_via_gitaly.yml (renamed from config/feature_flags/development/get_tag_signatures.yml)10
-rw-r--r--db/migrate/20210902171808_set_default_job_token_scope_false.rb17
-rw-r--r--db/post_migrate/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks.rb20
-rw-r--r--db/post_migrate/20210908132335_disable_job_token_scope_when_unused.rb52
-rw-r--r--db/schema_migrations/202109021718081
-rw-r--r--db/schema_migrations/202109061003161
-rw-r--r--db/schema_migrations/202109081323351
-rw-r--r--db/structure.sql14
-rw-r--r--doc/api/settings.md12
-rw-r--r--doc/update/package/convert_to_ee.md118
-rw-r--r--doc/update/package/downgrade.md83
-rw-r--r--doc/update/package/index.md278
-rw-r--r--doc/user/admin_area/settings/img/user_and_ip_rate_limits.pngbin36909 -> 0 bytes
-rw-r--r--doc/user/admin_area/settings/img/user_and_ip_rate_limits_v14_3.pngbin0 -> 29534 bytes
-rw-r--r--doc/user/admin_area/settings/user_and_ip_rate_limits.md9
-rw-r--r--lib/api/entities/blob.rb2
-rw-r--r--lib/gitlab/git/repository.rb11
-rw-r--r--lib/gitlab/gitaly_client/ref_service.rb15
-rw-r--r--lib/gitlab/signed_tag.rb24
-rw-r--r--locale/gitlab.pot30
-rw-r--r--qa/qa/page/admin/settings/component/ip_limits.rb10
-rw-r--r--spec/features/admin/admin_settings_spec.rb44
-rw-r--r--spec/features/projects/settings/service_desk_setting_spec.rb1
-rw-r--r--spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js23
-rw-r--r--spec/helpers/issuables_description_templates_helper_spec.rb21
-rw-r--r--spec/lib/gitlab/email/handler/service_desk_handler_spec.rb9
-rw-r--r--spec/lib/gitlab/git/tag_spec.rb14
-rw-r--r--spec/lib/gitlab/gitaly_client/ref_service_spec.rb30
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml2
-rw-r--r--spec/lib/gitlab/x509/tag_spec.rb18
-rw-r--r--spec/migrations/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks_spec.rb21
-rw-r--r--spec/migrations/disable_job_token_scope_when_unused_spec.rb44
-rw-r--r--spec/models/clusters/cluster_spec.rb4
-rw-r--r--spec/models/environment_spec.rb182
-rw-r--r--spec/models/project_ci_cd_setting_spec.rb6
-rw-r--r--spec/models/repository_spec.rb36
-rw-r--r--spec/support/shared_contexts/email_shared_context.rb9
49 files changed, 1210 insertions, 192 deletions
diff --git a/GITLAB_KAS_VERSION b/GITLAB_KAS_VERSION
index e4eccd4e6cd..6dfe8b1298c 100644
--- a/GITLAB_KAS_VERSION
+++ b/GITLAB_KAS_VERSION
@@ -1 +1 @@
-14.2.2
+14.3.1
diff --git a/Gemfile b/Gemfile
index 03e55fefd73..c71ac209ecf 100644
--- a/Gemfile
+++ b/Gemfile
@@ -120,7 +120,7 @@ gem 'carrierwave', '~> 1.3'
gem 'mini_magick', '~> 4.10.1'
# for backups
-gem 'fog-aws', '~> 3.9'
+gem 'fog-aws', '~> 3.12'
# Locked until fog-google resolves https://github.com/fog/fog-google/issues/421.
# Also see config/initializers/fog_core_patch.rb.
gem 'fog-core', '= 2.1.0'
diff --git a/Gemfile.lock b/Gemfile.lock
index dcc34698053..87f78455ee0 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -395,7 +395,7 @@ GEM
fog-json
ipaddress (~> 0.8)
xml-simple (~> 1.1)
- fog-aws (3.9.0)
+ fog-aws (3.12.0)
fog-core (~> 2.1)
fog-json (~> 1.1)
fog-xml (~> 0.1)
@@ -1452,7 +1452,7 @@ DEPENDENCIES
flipper-active_support_cache_store (~> 0.21.0)
flowdock (~> 0.7)
fog-aliyun (~> 0.3)
- fog-aws (~> 3.9)
+ fog-aws (~> 3.12)
fog-core (= 2.1.0)
fog-google (~> 1.15)
fog-local (~> 0.6)
diff --git a/app/assets/javascripts/design_management/components/design_sidebar.vue b/app/assets/javascripts/design_management/components/design_sidebar.vue
index efa1ef2107a..ced76eb4843 100644
--- a/app/assets/javascripts/design_management/components/design_sidebar.vue
+++ b/app/assets/javascripts/design_management/components/design_sidebar.vue
@@ -202,7 +202,7 @@ export default {
data-testid="resolved-discussion"
@error="$emit('onDesignDiscussionError', $event)"
@updateNoteError="$emit('updateNoteError', $event)"
- @openForm="updateDiscussionWithOpenForm"
+ @open-form="updateDiscussionWithOpenForm"
@click.native.stop="updateActiveDiscussion(discussion.notes[0].id)"
/>
</gl-collapse>
diff --git a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue
index 34d53e2de0c..5f70a9b9664 100644
--- a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue
+++ b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue
@@ -1,5 +1,13 @@
<script>
-import { GlButton, GlFormSelect, GlToggle, GlLoadingIcon, GlSprintf } from '@gitlab/ui';
+import {
+ GlButton,
+ GlFormSelect,
+ GlToggle,
+ GlLoadingIcon,
+ GlSprintf,
+ GlFormInput,
+ GlLink,
+} from '@gitlab/ui';
import { __ } from '~/locale';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
@@ -14,6 +22,8 @@ export default {
GlToggle,
GlLoadingIcon,
GlSprintf,
+ GlFormInput,
+ GlLink,
},
props: {
isEnabled: {
@@ -148,17 +158,37 @@ export default {
<span class="sr-only">{{ __('Fetching incoming email') }}</span>
</template>
- <template v-if="hasProjectKeySupport">
- <label for="service-desk-project-suffix" class="mt-3">
- {{ __('Project name suffix') }}
- </label>
- <input id="service-desk-project-suffix" v-model.trim="projectKey" class="form-control" />
- <span class="form-text text-muted">
- {{
- __('A string appended to the project path to form the Service Desk email address.')
- }}
- </span>
- </template>
+ <label for="service-desk-project-suffix" class="mt-3">
+ {{ __('Project name suffix') }}
+ </label>
+ <gl-form-input
+ v-if="hasProjectKeySupport"
+ id="service-desk-project-suffix"
+ v-model.trim="projectKey"
+ data-testid="project-suffix"
+ class="form-control"
+ />
+ <span v-if="hasProjectKeySupport" class="form-text text-muted">
+ {{ __('A string appended to the project path to form the Service Desk email address.') }}
+ </span>
+ <span v-else class="form-text text-muted">
+ <gl-sprintf
+ :message="
+ __(
+ 'Please set up a Service Desk email address in order to add a custom suffix. %{linkStart}Learn more%{linkEnd}.',
+ )
+ "
+ >
+ <template #link="{ content }">
+ <gl-link
+ href="https://docs.gitlab.com/ee/user/project/service_desk.html#using-a-custom-email-address"
+ target="_blank"
+ class="gl-text-blue-600 font-size-inherit"
+ >{{ content }}
+ </gl-link>
+ </template>
+ </gl-sprintf>
+ </span>
<label for="service-desk-template-select" class="mt-3">
{{ __('Template to append to all Service Desk issues') }}
diff --git a/app/controllers/projects/service_desk_controller.rb b/app/controllers/projects/service_desk_controller.rb
index f7c0a54fb9e..1fb07c3a903 100644
--- a/app/controllers/projects/service_desk_controller.rb
+++ b/app/controllers/projects/service_desk_controller.rb
@@ -24,24 +24,31 @@ class Projects::ServiceDeskController < Projects::ApplicationController
private
def setting_params
- params.permit(:issue_template_key, :outgoing_name, :project_key)
+ params.permit(*allowed_update_attributes)
+ end
+
+ def allowed_update_attributes
+ %i(issue_template_key outgoing_name project_key)
+ end
+
+ def service_desk_attributes
+ service_desk_settings = project.service_desk_setting
+
+ {
+ service_desk_address: project.service_desk_address,
+ service_desk_enabled: project.service_desk_enabled,
+ issue_template_key: service_desk_settings&.issue_template_key,
+ template_file_missing: service_desk_settings&.issue_template_missing?,
+ outgoing_name: service_desk_settings&.outgoing_name,
+ project_key: service_desk_settings&.project_key
+ }
end
def json_response
respond_to do |format|
- service_desk_settings = project.service_desk_setting
-
- service_desk_attributes =
- {
- service_desk_address: project.service_desk_address,
- service_desk_enabled: project.service_desk_enabled,
- issue_template_key: service_desk_settings&.issue_template_key,
- template_file_missing: service_desk_settings&.issue_template_missing?,
- outgoing_name: service_desk_settings&.outgoing_name,
- project_key: service_desk_settings&.project_key
- }
-
format.json { render json: service_desk_attributes }
end
end
end
+
+Projects::ServiceDeskController.prepend_mod
diff --git a/app/models/environment.rb b/app/models/environment.rb
index a4084565579..48522a23068 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -27,11 +27,10 @@ class Environment < ApplicationRecord
has_many :alert_management_alerts, class_name: 'AlertManagement::Alert', inverse_of: :environment
has_one :last_deployment, -> { success.distinct_on_environment }, class_name: 'Deployment', inverse_of: :environment
- has_one :last_deployable, through: :last_deployment, source: 'deployable', source_type: 'CommitStatus'
- has_one :last_pipeline, through: :last_deployable, source: 'pipeline'
has_one :last_visible_deployment, -> { visible.distinct_on_environment }, inverse_of: :environment, class_name: 'Deployment'
- has_one :last_visible_deployable, through: :last_visible_deployment, source: 'deployable', source_type: 'CommitStatus'
- has_one :last_visible_pipeline, through: :last_visible_deployable, source: 'pipeline'
+ has_one :last_visible_deployable, through: :last_visible_deployment, source: 'deployable', source_type: 'CommitStatus', disable_joins: -> { ::Feature.enabled?(:environment_last_visible_pipeline_disable_joins, default_enabled: :yaml) }
+ has_one :last_visible_pipeline, through: :last_visible_deployable, source: 'pipeline', disable_joins: -> { ::Feature.enabled?(:environment_last_visible_pipeline_disable_joins, default_enabled: :yaml) }
+
has_one :upcoming_deployment, -> { running.distinct_on_environment }, class_name: 'Deployment', inverse_of: :environment
has_one :latest_opened_most_severe_alert, -> { order_severity_with_open_prometheus_alert }, class_name: 'AlertManagement::Alert', inverse_of: :environment
@@ -182,6 +181,35 @@ class Environment < ApplicationRecord
end
end
+ def last_deployable
+ last_deployment&.deployable
+ end
+
+ # NOTE: Below assocation overrides is a workaround for issue https://gitlab.com/gitlab-org/gitlab/-/issues/339908
+ # It helps to avoid cross joins with the CI database.
+ # Caveat: It also overrides and losses the default AR caching mechanism.
+ # Read - https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68870#note_677227727
+
+ # NOTE: Association Preloads does not use the overriden definitions below.
+ # Association Preloads when preloading uses the original definitions from the relationships above.
+ # https://github.com/rails/rails/blob/75ac626c4e21129d8296d4206a1960563cc3d4aa/activerecord/lib/active_record/associations/preloader.rb#L158
+ # But after preloading, when they are called it is using the overriden methods below.
+ # So we are checking for `association_cached?(:association_name)` in the overridden methods and calling `super` which inturn fetches the preloaded values.
+
+ # Overriding association
+ def last_visible_deployable
+ return super if association_cached?(:last_visible_deployable) || ::Feature.disabled?(:environment_last_visible_pipeline_disable_joins, default_enabled: :yaml)
+
+ last_visible_deployment&.deployable
+ end
+
+ # Overriding association
+ def last_visible_pipeline
+ return super if association_cached?(:last_visible_pipeline) || ::Feature.disabled?(:environment_last_visible_pipeline_disable_joins, default_enabled: :yaml)
+
+ last_visible_deployable&.pipeline
+ end
+
def clear_prometheus_reactive_cache!(query_name)
cluster_prometheus_adapter&.clear_prometheus_reactive_cache!(query_name, self)
end
diff --git a/app/models/release.rb b/app/models/release.rb
index aad1cbeabdb..0dd71c6ebfb 100644
--- a/app/models/release.rb
+++ b/app/models/release.rb
@@ -33,7 +33,6 @@ class Release < ApplicationRecord
includes(:author, :evidences, :milestones, :links, :sorted_links,
project: [:project_feature, :route, { namespace: :route }])
}
- scope :with_project_and_namespace, -> { includes(project: :namespace) }
scope :recent, -> { sorted.limit(MAX_NUMBER_TO_DISPLAY) }
scope :without_evidence, -> { left_joins(:evidences).where(::Releases::Evidence.arel_table[:id].eq(nil)) }
scope :released_within_2hrs, -> { where(released_at: Time.zone.now - 1.hour..Time.zone.now + 1.hour) }
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 33225e51abc..f20b306c806 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -191,7 +191,11 @@ class Repository
end
def find_tag(name)
- tags.find { |tag| tag.name == name }
+ if @tags.blank? && Feature.enabled?(:find_tag_via_gitaly, project, default_enabled: :yaml)
+ raw_repository.find_tag(name)
+ else
+ tags.find { |tag| tag.name == name }
+ end
end
def ambiguous_ref?(ref)
diff --git a/app/models/service_desk_setting.rb b/app/models/service_desk_setting.rb
index 1c854cc9941..6dd7415d928 100644
--- a/app/models/service_desk_setting.rb
+++ b/app/models/service_desk_setting.rb
@@ -19,7 +19,11 @@ class ServiceDeskSetting < ApplicationRecord
strong_memoize(:issue_template_content) do
next unless issue_template_key.present?
- Gitlab::Template::IssueTemplate.find(issue_template_key, project).content
+ TemplateFinder.new(
+ :issues, project,
+ name: issue_template_key,
+ source_template_project: source_template_project
+ ).execute.content
rescue ::Gitlab::Template::Finders::RepoTemplateFinder::FileNotFoundError
end
end
@@ -42,6 +46,10 @@ class ServiceDeskSetting < ApplicationRecord
private
+ def source_template_project
+ nil
+ end
+
def projects_with_same_slug_and_key_exists?
return false unless project_key
@@ -53,3 +61,5 @@ class ServiceDeskSetting < ApplicationRecord
end
end
end
+
+ServiceDeskSetting.prepend_mod
diff --git a/app/views/admin/application_settings/_ip_limits.html.haml b/app/views/admin/application_settings/_ip_limits.html.haml
index e584aaf9880..511d628cb79 100644
--- a/app/views/admin/application_settings/_ip_limits.html.haml
+++ b/app/views/admin/application_settings/_ip_limits.html.haml
@@ -1,56 +1,68 @@
-= form_for @application_setting, url: network_admin_application_settings_path(anchor: 'js-ip-limits-settings'), html: { class: 'fieldset-form' } do |f|
+= gitlab_ui_form_for @application_setting, url: network_admin_application_settings_path(anchor: 'js-ip-limits-settings'), html: { class: 'fieldset-form' } do |f|
= form_errors(@application_setting)
%fieldset
- %h5
- = _('Unauthenticated request rate limit')
+ %legend.h5.gl-border-none
+ = _('Unauthenticated API request rate limit')
.form-group
- .form-check
- = f.check_box :throttle_unauthenticated_enabled, class: 'form-check-input', data: { qa_selector: 'throttle_unauthenticated_checkbox' }
- = f.label :throttle_unauthenticated_enabled, class: 'form-check-label label-bold' do
- = _("Enable unauthenticated request rate limit")
- %span.form-text.text-muted
- = _("Helps reduce request volume (e.g. from crawlers or abusive bots)")
+ = f.gitlab_ui_checkbox_component :throttle_unauthenticated_api_enabled,
+ _("Enable unauthenticated API request rate limit"),
+ help_text: _("Helps reduce request volume (e.g. from crawlers or abusive bots)"),
+ checkbox_options: { data: { qa_selector: 'throttle_unauthenticated_api_checkbox' } }
.form-group
- = f.label :throttle_unauthenticated_requests_per_period, _('Max unauthenticated requests per period per IP'), class: 'label-bold'
+ = f.label :throttle_unauthenticated_api_requests_per_period, _('Max unauthenticated API requests per period per IP'), class: 'label-bold'
+ = f.number_field :throttle_unauthenticated_api_requests_per_period, class: 'form-control gl-form-input'
+ .form-group
+ = f.label :throttle_unauthenticated_api_period_in_seconds, _('Unauthenticated API rate limit period in seconds'), class: 'label-bold'
+ = f.number_field :throttle_unauthenticated_api_period_in_seconds, class: 'form-control gl-form-input'
+
+ %fieldset
+ %legend.h5.gl-border-none
+ = _('Unauthenticated web request rate limit')
+ .form-group
+ = f.gitlab_ui_checkbox_component :throttle_unauthenticated_enabled,
+ _("Enable unauthenticated web request rate limit"),
+ help_text: _("Helps reduce request volume (e.g. from crawlers or abusive bots)"),
+ checkbox_options: { data: { qa_selector: 'throttle_unauthenticated_web_checkbox' } }
+ .form-group
+ = f.label :throttle_unauthenticated_requests_per_period, _('Max unauthenticated web requests per period per IP'), class: 'label-bold'
= f.number_field :throttle_unauthenticated_requests_per_period, class: 'form-control gl-form-input'
.form-group
- = f.label :throttle_unauthenticated_period_in_seconds, _('Unauthenticated rate limit period in seconds'), class: 'label-bold'
+ = f.label :throttle_unauthenticated_period_in_seconds, _('Unauthenticated web rate limit period in seconds'), class: 'label-bold'
= f.number_field :throttle_unauthenticated_period_in_seconds, class: 'form-control gl-form-input'
- %hr
- %h5
+
+ %fieldset
+ %legend.h5.gl-border-none
= _('Authenticated API request rate limit')
.form-group
- .form-check
- = f.check_box :throttle_authenticated_api_enabled, class: 'form-check-input', data: { qa_selector: 'throttle_authenticated_api_checkbox' }
- = f.label :throttle_authenticated_api_enabled, class: 'form-check-label label-bold' do
- = _("Enable authenticated API request rate limit")
- %span.form-text.text-muted
- = _("Helps reduce request volume (e.g. from crawlers or abusive bots)")
+ = f.gitlab_ui_checkbox_component :throttle_authenticated_api_enabled,
+ _("Enable authenticated API request rate limit"),
+ help_text: _("Helps reduce request volume (e.g. from crawlers or abusive bots)"),
+ checkbox_options: { data: { qa_selector: 'throttle_authenticated_api_checkbox' }}
.form-group
= f.label :throttle_authenticated_api_requests_per_period, _('Max authenticated API requests per period per user'), class: 'label-bold'
= f.number_field :throttle_authenticated_api_requests_per_period, class: 'form-control gl-form-input'
.form-group
= f.label :throttle_authenticated_api_period_in_seconds, _('Authenticated API rate limit period in seconds'), class: 'label-bold'
= f.number_field :throttle_authenticated_api_period_in_seconds, class: 'form-control gl-form-input'
- %hr
- %h5
+
+ %fieldset
+ %legend.h5.gl-border-none
= _('Authenticated web request rate limit')
.form-group
- .form-check
- = f.check_box :throttle_authenticated_web_enabled, class: 'form-check-input', data: { qa_selector: 'throttle_authenticated_web_checkbox' }
- = f.label :throttle_authenticated_web_enabled, class: 'form-check-label label-bold' do
- Enable authenticated web request rate limit
- %span.form-text.text-muted
- Helps reduce request volume (e.g. from crawlers or abusive bots)
+ = f.gitlab_ui_checkbox_component :throttle_authenticated_web_enabled,
+ _("Enable authenticated web request rate limit"),
+ help_text: _("Helps reduce request volume (e.g. from crawlers or abusive bots)"),
+ checkbox_options: { data: { qa_selector: 'throttle_authenticated_web_checkbox' } }
.form-group
= f.label :throttle_authenticated_web_requests_per_period, _('Max authenticated web requests per period per user'), class: 'label-bold'
= f.number_field :throttle_authenticated_web_requests_per_period, class: 'form-control gl-form-input'
.form-group
= f.label :throttle_authenticated_web_period_in_seconds, _('Authenticated web rate limit period in seconds'), class: 'label-bold'
= f.number_field :throttle_authenticated_web_period_in_seconds, class: 'form-control gl-form-input'
- %hr
- %h5
+
+ %fieldset
+ %legend.h5.gl-border-none
= _('Response text')
.form-group
= f.label :rate_limiting_response_text, class: 'label-bold' do
diff --git a/config/feature_flags/development/environment_last_visible_pipeline_disable_joins.yml b/config/feature_flags/development/environment_last_visible_pipeline_disable_joins.yml
new file mode 100644
index 00000000000..7667542506a
--- /dev/null
+++ b/config/feature_flags/development/environment_last_visible_pipeline_disable_joins.yml
@@ -0,0 +1,8 @@
+---
+name: environment_last_visible_pipeline_disable_joins
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/68870
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340283
+milestone: '14.3'
+type: development
+group: group::release
+default_enabled: true
diff --git a/config/feature_flags/development/get_tag_signatures.yml b/config/feature_flags/development/find_tag_via_gitaly.yml
index e0d7d5d6dcf..217eac464ad 100644
--- a/config/feature_flags/development/get_tag_signatures.yml
+++ b/config/feature_flags/development/find_tag_via_gitaly.yml
@@ -1,8 +1,8 @@
---
-name: get_tag_signatures
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/67000
-rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/337842
-milestone: '14.2'
+name: find_tag_via_gitaly
+introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70181
+rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/340899
+milestone: '14.3'
type: development
-group: group::gitaly
+group: group::source code
default_enabled: false
diff --git a/db/migrate/20210902171808_set_default_job_token_scope_false.rb b/db/migrate/20210902171808_set_default_job_token_scope_false.rb
new file mode 100644
index 00000000000..0680382094f
--- /dev/null
+++ b/db/migrate/20210902171808_set_default_job_token_scope_false.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+class SetDefaultJobTokenScopeFalse < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ def up
+ with_lock_retries do
+ change_column_default :project_ci_cd_settings, :job_token_scope_enabled, from: true, to: false
+ end
+ end
+
+ def down
+ with_lock_retries do
+ change_column_default :project_ci_cd_settings, :job_token_scope_enabled, from: false, to: true
+ end
+ end
+end
diff --git a/db/post_migrate/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks.rb b/db/post_migrate/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks.rb
new file mode 100644
index 00000000000..44bec402cae
--- /dev/null
+++ b/db/post_migrate/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks.rb
@@ -0,0 +1,20 @@
+# frozen_string_literal: true
+
+class DropTemporaryColumnsAndTriggersForCiBuildTraceChunks < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ TABLE = 'ci_build_trace_chunks'
+ COLUMN = 'build_id'
+
+ # rubocop:disable Migration/WithLockRetriesDisallowedMethod
+ def up
+ with_lock_retries do
+ cleanup_conversion_of_integer_to_bigint(TABLE, COLUMN)
+ end
+ end
+ # rubocop:enable Migration/WithLockRetriesDisallowedMethod
+
+ def down
+ restore_conversion_of_integer_to_bigint(TABLE, COLUMN)
+ end
+end
diff --git a/db/post_migrate/20210908132335_disable_job_token_scope_when_unused.rb b/db/post_migrate/20210908132335_disable_job_token_scope_when_unused.rb
new file mode 100644
index 00000000000..2e6ad12f928
--- /dev/null
+++ b/db/post_migrate/20210908132335_disable_job_token_scope_when_unused.rb
@@ -0,0 +1,52 @@
+# frozen_string_literal: true
+
+class DisableJobTokenScopeWhenUnused < Gitlab::Database::Migration[1.0]
+ disable_ddl_transaction!
+
+ class ProjectCiCdSetting < ApplicationRecord
+ include EachBatch
+
+ self.table_name = 'project_ci_cd_settings'
+ end
+
+ module Ci
+ module JobToken
+ class ProjectScopeLink < ApplicationRecord
+ self.table_name = 'ci_job_token_project_scope_links'
+ end
+ end
+ end
+
+ def up
+ # Disabling job token scope after db/migrate/20210902171808_set_default_job_token_scope_false.rb
+ # if users haven't configured it.
+ ProjectCiCdSetting.each_batch(of: 10_000) do |settings|
+ with_enabled_but_unused_scope(settings).each_batch(of: 500) do |settings_to_update|
+ settings_to_update.update_all(job_token_scope_enabled: false)
+ end
+ end
+ end
+
+ def down
+ # irreversible data migration
+
+ # The migration relies on the state of `job_token_scope_enabled` and
+ # updates it based on whether the feature is used or not.
+ #
+ # The inverse migration would be to set `job_token_scope_enabled: true`
+ # for those projects that have the feature disabled and unused. But there
+ # could be also existing cases where the feature is disabled and unused.
+ # For example, old projects.
+ end
+
+ private
+
+ # The presence of ProjectScopeLinks means that the job token scope
+ # is configured and we need to leave it enabled. Unused job token scope
+ # can be disabled since they weren't configured.
+ def with_enabled_but_unused_scope(settings)
+ settings
+ .where(job_token_scope_enabled: true)
+ .where.not(project_id: Ci::JobToken::ProjectScopeLink.select(:source_project_id))
+ end
+end
diff --git a/db/schema_migrations/20210902171808 b/db/schema_migrations/20210902171808
new file mode 100644
index 00000000000..1398c2db4b6
--- /dev/null
+++ b/db/schema_migrations/20210902171808
@@ -0,0 +1 @@
+09b482e4716a2b0808ad83770222baed8e863a8f94f85f77ed2d557eaa348df4 \ No newline at end of file
diff --git a/db/schema_migrations/20210906100316 b/db/schema_migrations/20210906100316
new file mode 100644
index 00000000000..4ce17059b07
--- /dev/null
+++ b/db/schema_migrations/20210906100316
@@ -0,0 +1 @@
+b7329d4ff7ee651b56cb86c7091e0d933c4f43a77125323fb6c283eedcb737c2 \ No newline at end of file
diff --git a/db/schema_migrations/20210908132335 b/db/schema_migrations/20210908132335
new file mode 100644
index 00000000000..864d6ccc942
--- /dev/null
+++ b/db/schema_migrations/20210908132335
@@ -0,0 +1 @@
+399e35197111c257786a2bdf5dac990a26f48d2cc8493de642dcfa47ddececd2 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index 34b7d38383f..44800192952 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -108,15 +108,6 @@ BEGIN
END;
$$;
-CREATE FUNCTION trigger_cf2f9e35f002() RETURNS trigger
- LANGUAGE plpgsql
- AS $$
-BEGIN
- NEW."build_id_convert_to_bigint" := NEW."build_id";
- RETURN NEW;
-END;
-$$;
-
CREATE TABLE audit_events (
id bigint NOT NULL,
author_id integer NOT NULL,
@@ -11277,7 +11268,6 @@ ALTER SEQUENCE ci_build_report_results_build_id_seq OWNED BY ci_build_report_res
CREATE TABLE ci_build_trace_chunks (
id bigint NOT NULL,
- build_id_convert_to_bigint integer DEFAULT 0 NOT NULL,
chunk_index integer NOT NULL,
data_store integer NOT NULL,
raw_data bytea,
@@ -17729,7 +17719,7 @@ CREATE TABLE project_ci_cd_settings (
auto_rollback_enabled boolean DEFAULT false NOT NULL,
keep_latest_artifact boolean DEFAULT true NOT NULL,
restrict_user_defined_variables boolean DEFAULT false NOT NULL,
- job_token_scope_enabled boolean DEFAULT true NOT NULL
+ job_token_scope_enabled boolean DEFAULT false NOT NULL
);
CREATE SEQUENCE project_ci_cd_settings_id_seq
@@ -27329,8 +27319,6 @@ CREATE TRIGGER trigger_91dc388a5fe6 BEFORE INSERT OR UPDATE ON dep_ci_build_trac
CREATE TRIGGER trigger_aebe8b822ad3 BEFORE INSERT OR UPDATE ON taggings FOR EACH ROW EXECUTE FUNCTION trigger_aebe8b822ad3();
-CREATE TRIGGER trigger_cf2f9e35f002 BEFORE INSERT OR UPDATE ON ci_build_trace_chunks FOR EACH ROW EXECUTE FUNCTION trigger_cf2f9e35f002();
-
CREATE TRIGGER trigger_has_external_issue_tracker_on_delete AFTER DELETE ON integrations FOR EACH ROW WHEN ((((old.category)::text = 'issue_tracker'::text) AND (old.active = true) AND (old.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_issue_tracker();
CREATE TRIGGER trigger_has_external_issue_tracker_on_insert AFTER INSERT ON integrations FOR EACH ROW WHEN ((((new.category)::text = 'issue_tracker'::text) AND (new.active = true) AND (new.project_id IS NOT NULL))) EXECUTE FUNCTION set_has_external_issue_tracker();
diff --git a/doc/api/settings.md b/doc/api/settings.md
index 6b549ecc71c..6b1faa0402f 100644
--- a/doc/api/settings.md
+++ b/doc/api/settings.md
@@ -415,9 +415,15 @@ listed in the descriptions of the relevant settings.
| `throttle_authenticated_web_enabled` | boolean | no | (**If enabled, requires:** `throttle_authenticated_web_period_in_seconds` and `throttle_authenticated_web_requests_per_period`) Enable authenticated web request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). |
| `throttle_authenticated_web_period_in_seconds` | integer | required by:<br>`throttle_authenticated_web_enabled` | Rate limit period in seconds. |
| `throttle_authenticated_web_requests_per_period` | integer | required by:<br>`throttle_authenticated_web_enabled` | Max requests per period per user. |
-| `throttle_unauthenticated_enabled` | boolean | no | (**If enabled, requires:** `throttle_unauthenticated_period_in_seconds` and `throttle_unauthenticated_requests_per_period`) Enable unauthenticated request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). |
-| `throttle_unauthenticated_period_in_seconds` | integer | required by:<br>`throttle_unauthenticated_enabled` | Rate limit period in seconds. |
-| `throttle_unauthenticated_requests_per_period` | integer | required by:<br>`throttle_unauthenticated_enabled` | Max requests per period per IP. |
+| `throttle_unauthenticated_enabled` | boolean | no | ([Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/335300) in GitLab 14.3. Use `throttle_unauthenticated_web_enabled` or `throttle_unauthenticated_api_enabled` instead.) (**If enabled, requires:** `throttle_unauthenticated_period_in_seconds` and `throttle_unauthenticated_requests_per_period`) Enable unauthenticated web request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). |
+| `throttle_unauthenticated_period_in_seconds` | integer | required by:<br>`throttle_unauthenticated_enabled` | ([Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/335300) in GitLab 14.3. Use `throttle_unauthenticated_web_period_in_seconds` or `throttle_unauthenticated_api_period_in_seconds` instead.) Rate limit period in seconds. |
+| `throttle_unauthenticated_requests_per_period` | integer | required by:<br>`throttle_unauthenticated_enabled` | ([Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/335300) in GitLab 14.3. Use `throttle_unauthenticated_web_requests_per_period` or `throttle_unauthenticated_api_requests_per_period` instead.) Max requests per period per IP. |
+| `throttle_unauthenticated_api_enabled` | boolean | no | (**If enabled, requires:** `throttle_unauthenticated_api_period_in_seconds` and `throttle_unauthenticated_api_requests_per_period`) Enable unauthenticated API request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). |
+| `throttle_unauthenticated_api_period_in_seconds` | integer | required by:<br>`throttle_unauthenticated_api_enabled` | Rate limit period in seconds. |
+| `throttle_unauthenticated_api_requests_per_period` | integer | required by:<br>`throttle_unauthenticated_api_enabled` | Max requests per period per IP. |
+| `throttle_unauthenticated_web_enabled` | boolean | no | (**If enabled, requires:** `throttle_unauthenticated_web_period_in_seconds` and `throttle_unauthenticated_web_requests_per_period`) Enable unauthenticated web request rate limit. Helps reduce request volume (for example, from crawlers or abusive bots). |
+| `throttle_unauthenticated_web_period_in_seconds` | integer | required by:<br>`throttle_unauthenticated_web_enabled` | Rate limit period in seconds. |
+| `throttle_unauthenticated_web_requests_per_period` | integer | required by:<br>`throttle_unauthenticated_web_enabled` | Max requests per period per IP. |
| `time_tracking_limit_to_hours` | boolean | no | Limit display of time tracking units to hours. Default is `false`. |
| `two_factor_grace_period` | integer | required by: `require_two_factor_authentication` | Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication. |
| `unique_ips_limit_enabled` | boolean | no | (**If enabled, requires:** `unique_ips_limit_per_user` and `unique_ips_limit_time_window`) Limit sign in from multiple IPs. |
diff --git a/doc/update/package/convert_to_ee.md b/doc/update/package/convert_to_ee.md
new file mode 100644
index 00000000000..2cc54e2c8cf
--- /dev/null
+++ b/doc/update/package/convert_to_ee.md
@@ -0,0 +1,118 @@
+---
+stage: Enablement
+group: Distribution
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
+# Convert Community Edition to Enterprise Edition **(FREE SELF)**
+
+To convert an existing GitLab Community Edition (CE) server installed using the Omnibus GitLab
+packages to GitLab [Enterprise Edition](https://about.gitlab.com/pricing/) (EE), you install the EE
+package on top of CE.
+
+Converting from the same version of CE to EE is not explicitly necessary, and any standard upgrade
+(for example, CE 12.0 to EE 12.1) should work. However, in the following steps we assume that
+you are upgrading the same version (for example, CE 12.1 to EE 12.1), which is **recommended**.
+
+WARNING:
+When updating to EE from CE, avoid reverting back to CE if you plan on going to EE again in the
+future. Reverting back to CE can cause
+[database issues](index.md#500-error-when-accessing-project--settings--repository)
+that may require Support intervention.
+
+The steps can be summed up to:
+
+1. Find the currently installed GitLab version:
+
+ **For Debian/Ubuntu**
+
+ ```shell
+ sudo apt-cache policy gitlab-ce | grep Installed
+ ```
+
+ The output should be similar to: `Installed: 13.0.4-ce.0`. In that case,
+ the equivalent Enterprise Edition version will be: `13.0.4-ee.0`. Write this
+ value down.
+
+ **For CentOS/RHEL**
+
+ ```shell
+ sudo rpm -q gitlab-ce
+ ```
+
+ The output should be similar to: `gitlab-ce-13.0.4-ce.0.el8.x86_64`. In that
+ case, the equivalent Enterprise Edition version will be:
+ `gitlab-ee-13.0.4-ee.0.el8.x86_64`. Write this value down.
+
+1. Add the `gitlab-ee` [Apt or Yum repository](https://packages.gitlab.com/gitlab/gitlab-ee/install):
+
+ **For Debian/Ubuntu**
+
+ ```shell
+ curl --silent "https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.deb.sh" | sudo bash
+ ```
+
+ **For CentOS/RHEL**
+
+ ```shell
+ curl --silent "https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.rpm.sh" | sudo bash
+ ```
+
+ The above command will find your OS version and automatically set up the
+ repository. If you are not comfortable installing the repository through a
+ piped script, you can first
+ [check its contents](https://packages.gitlab.com/gitlab/gitlab-ee/install).
+
+1. Next, install the `gitlab-ee` package. Note that this will automatically
+ uninstall the `gitlab-ce` package on your GitLab server. `reconfigure`
+ Omnibus right after the `gitlab-ee` package is installed. **Make sure that you
+ install the exact same GitLab version**:
+
+ **For Debian/Ubuntu**
+
+ ```shell
+ ## Make sure the repositories are up-to-date
+ sudo apt-get update
+
+ ## Install the package using the version you wrote down from step 1
+ sudo apt-get install gitlab-ee=13.0.4-ee.0
+
+ ## Reconfigure GitLab
+ sudo gitlab-ctl reconfigure
+ ```
+
+ **For CentOS/RHEL**
+
+ ```shell
+ ## Install the package using the version you wrote down from step 1
+ sudo yum install gitlab-ee-13.0.4-ee.0.el8.x86_64
+
+ ## Reconfigure GitLab
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. Now go to the GitLab admin panel of your server (`/admin/license/new`) and
+ upload your license file.
+
+1. After you confirm that GitLab is working as expected, you may remove the old
+ Community Edition repository:
+
+ **For Debian/Ubuntu**
+
+ ```shell
+ sudo rm /etc/apt/sources.list.d/gitlab_gitlab-ce.list
+ ```
+
+ **For CentOS/RHEL**
+
+ ```shell
+ sudo rm /etc/yum.repos.d/gitlab_gitlab-ce.repo
+ ```
+
+That's it! You can now use GitLab Enterprise Edition! To update to a newer
+version, follow [Update using the official repositories](index.md#upgrade-using-the-official-repositories).
+
+NOTE:
+If you want to use `dpkg`/`rpm` instead of `apt-get`/`yum`, go through the first
+step to find the current GitLab version and then follow
+[Update using a manually-downloaded package](index.md#upgrade-using-a-manually-downloaded-package).
diff --git a/doc/update/package/downgrade.md b/doc/update/package/downgrade.md
new file mode 100644
index 00000000000..9a528f5ee44
--- /dev/null
+++ b/doc/update/package/downgrade.md
@@ -0,0 +1,83 @@
+---
+stage: Enablement
+group: Distribution
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
+# Downgrade **(FREE SELF)**
+
+This section contains general information on how to revert to an earlier version
+of a package.
+
+WARNING:
+You must at least have a database backup created under the version you are
+downgrading to. Ideally, you should have a
+[full backup archive](../../raketasks/backup_restore.md#back-up-gitlab)
+on hand.
+
+The example below demonstrates the downgrade procedure when downgrading between minor
+and patch versions (for example, from 13.0.6 to 13.0.5).
+
+When downgrading between major versions, take into account the
+[specific version changes](index.md#version-specific-changes) that occurred when you upgraded
+to the major version you are downgrading from.
+
+These steps consist of:
+
+- Stopping GitLab
+- Removing the current package
+- Installing the old package
+- Reconfiguring GitLab
+- Restoring the backup
+- Starting GitLab
+
+Steps:
+
+1. Stop GitLab and remove the current package:
+
+ ```shell
+ # If running Puma
+ sudo gitlab-ctl stop puma
+
+ # Stop sidekiq
+ sudo gitlab-ctl stop sidekiq
+
+ # If on Ubuntu: remove the current package
+ sudo dpkg -r gitlab-ee
+
+ # If on Centos: remove the current package
+ sudo yum remove gitlab-ee
+ ```
+
+1. Identify the GitLab version you want to downgrade to:
+
+ ```shell
+ # (Replace with gitlab-ce if you have GitLab FOSS installed)
+
+ # Ubuntu
+ sudo apt-cache madison gitlab-ee
+
+ # CentOS:
+ sudo yum --showduplicates list gitlab-ee
+ ```
+
+1. Downgrade GitLab to the desired version (for example, to GitLab 13.0.5):
+
+ ```shell
+ # (Replace with gitlab-ce if you have GitLab FOSS installed)
+
+ # Ubuntu
+ sudo apt install gitlab-ee=13.0.5-ee.0
+
+ # CentOS:
+ sudo yum install gitlab-ee-13.0.5-ee.0.el8
+ ```
+
+1. Reconfigure GitLab:
+
+ ```shell
+ sudo gitlab-ctl reconfigure
+ ```
+
+1. [Restore GitLab](../../raketasks/backup_restore.md#restore-for-omnibus-gitlab-installations)
+ to complete the downgrade.
diff --git a/doc/update/package/index.md b/doc/update/package/index.md
new file mode 100644
index 00000000000..d0b1e46597c
--- /dev/null
+++ b/doc/update/package/index.md
@@ -0,0 +1,278 @@
+---
+stage: Enablement
+group: Distribution
+info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
+---
+
+# Upgrade GitLab using the GitLab Package **(FREE SELF)**
+
+This section describes how to upgrade GitLab to a new version using the
+GitLab package.
+
+We recommend performing upgrades between major and minor releases no more than once per
+week, to allow time for background migrations to finish. Decrease the time required to
+complete these migrations by increasing the number of
+[Sidekiq workers](../../administration/operations/extra_sidekiq_processes.md)
+that can process jobs in the `background_migration` queue.
+
+If you don't follow the steps in [zero downtime upgrades](../zero_downtime.md),
+your GitLab application will not be available to users while an upgrade is in progress.
+They either see a "Deploy in progress" message or a "502" error in their web browser.
+
+Prerequisites:
+
+- [Supported upgrade paths](../index.md#upgrade-paths)
+ has suggestions on when to upgrade. Upgrade paths are enforced for version upgrades by
+ default. This restricts performing direct upgrades that skip major versions (for
+ example 10.3 to 12.7 in one jump) that **can break GitLab
+ installations** due to multiple reasons like deprecated or removed configuration
+ settings, upgrade of internal tools and libraries, and so on.
+- If you are upgrading from a non-Package installation to a GitLab Package installation, see
+ [Upgrading from a non-Package installation to a GitLab Package installation](https://docs.gitlab.com/omnibus/convert_to_omnibus.html).
+- It's important to ensure that any
+ [background migrations](../index.md#checking-for-background-migrations-before-upgrading)
+ have been fully completed before upgrading to a new major version. Upgrading
+ before background migrations have finished may lead to data corruption.
+- Gitaly servers must be upgraded to the newer version prior to upgrading the application server.
+ This prevents the gRPC client on the application server from sending RPCs that the old Gitaly version
+ does not support.
+
+You can upgrade the GitLab Package using one of the following methods:
+
+- [Using the official repositories](#upgrade-using-the-official-repositories).
+- [Using a manually-downloaded package](#upgrade-using-a-manually-downloaded-package).
+
+Both automatically back up the GitLab database before installing a newer
+GitLab version. You may skip this automatic database backup by creating an empty file
+at `/etc/gitlab/skip-auto-backup`:
+
+```shell
+sudo touch /etc/gitlab/skip-auto-backup
+```
+
+For safety reasons, you should maintain an up-to-date backup on your own if you plan to use this flag.
+
+## Version-specific changes
+
+Updating to major versions might need some manual intervention. For more information,
+check the version your are upgrading to:
+
+- [GitLab 14](https://docs.gitlab.com/omnibus/gitlab_14_changes.html)
+- [GitLab 13](https://docs.gitlab.com/omnibus/gitlab_13_changes.html)
+- [GitLab 12](https://docs.gitlab.com/omnibus/gitlab_12_changes.html)
+- [GitLab 11](https://docs.gitlab.com/omnibus/gitlab_11_changes.html)
+
+## Upgrade using the official repositories
+
+All GitLab packages are posted to the GitLab [package server](https://packages.gitlab.com/gitlab/).
+Five repositories are maintained:
+
+- [GitLab EE](https://packages.gitlab.com/gitlab/gitlab-ee): for official
+ [Enterprise Edition](https://about.gitlab.com/pricing/) releases.
+- [GitLab CE](https://packages.gitlab.com/gitlab/gitlab-ce): for official Community Edition releases.
+- [Unstable](https://packages.gitlab.com/gitlab/unstable): for release candidates and other unstable versions.
+- [Nighty Builds](https://packages.gitlab.com/gitlab/nightly-builds): for nightly builds.
+- [Raspberry Pi](https://packages.gitlab.com/gitlab/raspberry-pi2): for official Community Edition releases built for [Raspberry Pi](https://www.raspberrypi.org) packages.
+
+If you have installed Omnibus GitLab [Community Edition](https://about.gitlab.com/install/?version=ce)
+or [Enterprise Edition](https://about.gitlab.com/install/), then the
+official GitLab repository should have already been set up for you.
+
+To upgrade to the newest GitLab version, run:
+
+- For GitLab [Enterprise Edition](https://about.gitlab.com/pricing/):
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update
+ sudo apt-get install gitlab-ee
+
+ # Centos/RHEL
+ sudo yum install gitlab-ee
+ ```
+
+- For GitLab Community Edition:
+
+ ```shell
+ # Debian/Ubuntu
+ sudo apt-get update
+ sudo apt-get install gitlab-ce
+
+ # Centos/RHEL
+ sudo yum install gitlab-ce
+ ```
+
+### Upgrade to a specific version using the official repositories
+
+Linux package managers default to installing the latest available version of a
+package for installation and upgrades. Upgrading directly to the latest major
+version can be problematic for older GitLab versions that require a multi-stage
+[upgrade path](../index.md#upgrade-paths). An upgrade path can span multiple
+versions, so you must specify the specific GitLab package with each upgrade.
+
+To specify the intended GitLab version number in your package manager's install
+or upgrade command:
+
+1. First, identify the GitLab version number in your package manager:
+
+ ```shell
+ # Ubuntu/Debian
+ sudo apt-cache madison gitlab-ee
+ # RHEL/CentOS 6 and 7
+ yum --showduplicates list gitlab-ee
+ # RHEL/CentOS 8
+ dnf search gitlab-ee*
+ ```
+
+1. Then install the specific GitLab package:
+
+ ```shell
+ # Ubuntu/Debian
+ sudo apt install gitlab-ee=12.0.12-ee.0
+ # RHEL/CentOS 6 and 7
+ yum install gitlab-ee-12.0.12-ee.0.el7
+ # RHEL/CentOS 8
+ dnf install gitlab-ee-12.0.12-ee.0.el8
+ # SUSE
+ zypper install gitlab-ee=12.0.12-ee.0
+ ```
+
+## Upgrade using a manually-downloaded package
+
+NOTE:
+The [package repository](#upgrade-using-the-official-repositories) is recommended over
+a manual installation.
+
+If for some reason you don't use the official repositories, you can
+download the package and install it manually. This method can be used to either
+install GitLab for the first time or update it.
+
+To download and install GitLab:
+
+1. Visit the [official repository](#upgrade-using-the-official-repositories) of your package.
+1. Browse to the repository for the type of package you would like to see the
+ list of packages that are available. Multiple packages exist for a
+ single version, one for each supported distribution type. Next to the filename
+ is a label indicating the distribution, as the file names may be the same.
+1. Find the package version you wish to install and click on it.
+1. Click the **Download** button in the upper right corner to download the package.
+1. After the GitLab package is downloaded, install it using the following commands:
+
+ - For GitLab [Enterprise Edition](https://about.gitlab.com/pricing/):
+
+ ```shell
+ # Debian/Ubuntu
+ dpkg -i gitlab-ee-<version>.deb
+
+ # CentOS/RHEL
+ rpm -Uvh gitlab-ee-<version>.rpm
+ ```
+
+ - For GitLab Community Edition:
+
+ ```shell
+ # GitLab Community Edition
+ # Debian/Ubuntu
+ dpkg -i gitlab-ce-<version>.deb
+
+ # CentOS/RHEL
+ rpm -Uvh gitlab-ce-<version>.rpm
+ ```
+
+## Troubleshooting
+
+### GitLab 13.7 and later unavailable on Amazon Linux 2
+
+Amazon Linux 2 is not an [officially supported operating system](https://docs.gitlab.com/omnibus/package-information/deprecated_os.html#supported-operating-systems).
+However, in past the [official package installation script](https://packages.gitlab.com/gitlab/gitlab-ee/install)
+installed the `el/6` package repository if run on Amazon Linux. From GitLab 13.7, we no longer
+provide `el/6` packages so administrators must run the [installation script](https://packages.gitlab.com/gitlab/gitlab-ee/install)
+again to update the repository to `el/7`:
+
+```shell
+curl --silent "https://packages.gitlab.com/install/repositories/gitlab/gitlab-ee/script.rpm.sh" | sudo bash
+```
+
+See the [epic on support for GitLab on Amazon Linux 2](https://gitlab.com/groups/gitlab-org/-/epics/2195) for the latest details on official Amazon Linux 2 support.
+
+### Get the status of a GitLab installation
+
+```shell
+sudo gitlab-ctl status
+sudo gitlab-rake gitlab:check SANITIZE=true
+```
+
+- Information on using `gitlab-ctl` to perform [maintenance tasks](https://docs.gitlab.com/omnibus/maintenance/index.html).
+- Information on using `gitlab-rake` to [check the configuration](../../administration/raketasks/maintenance.md#check-gitlab-configuration).
+
+### RPM 'package is already installed' error
+
+If you are using RPM and you are upgrading from GitLab Community Edition to GitLab Enterprise Edition you may get an error like this:
+
+```shell
+package gitlab-7.5.2_omnibus.5.2.1.ci-1.el7.x86_64 (which is newer than gitlab-7.5.2_ee.omnibus.5.2.1.ci-1.el7.x86_64) is already installed
+```
+
+You can override this version check with the `--oldpackage` option:
+
+```shell
+sudo rpm -Uvh --oldpackage gitlab-7.5.2_ee.omnibus.5.2.1.ci-1.el7.x86_64.rpm
+```
+
+### Package obsoleted by installed package
+
+CE and EE packages are marked as obsoleting and replacing each other so that both aren't installed and running at the same time.
+
+If you are using local RPM files to switch from CE to EE or vice versa, use `rpm` for installing the package rather than `yum`. If you try to use yum, then you may get an error like this:
+
+```plaintext
+Cannot install package gitlab-ee-11.8.3-ee.0.el6.x86_64. It is obsoleted by installed package gitlab-ce-11.8.3-ce.0.el6.x86_64
+```
+
+To avoid this issue, either:
+
+- Use the same instructions provided in the
+ [Upgrade using a manually-downloaded package](#upgrade-using-a-manually-downloaded-package) section.
+- Temporarily disable this checking in yum by adding `--setopt=obsoletes=0` to the options given to the command.
+
+### 500 error when accessing Project > Settings > Repository
+
+When GitLab is migrated from CE > EE > CE, and then back to EE, you
+might get the following error when viewing a project's repository settings:
+
+```shell
+Processing by Projects::Settings::RepositoryController#show as HTML
+ Parameters: {"namespace_id"=>"<namespace_id>", "project_id"=>"<project_id>"}
+Completed 500 Internal Server Error in 62ms (ActiveRecord: 4.7ms | Elasticsearch: 0.0ms | Allocations: 14583)
+
+NoMethodError (undefined method `commit_message_negative_regex' for #<PushRule:0x00007fbddf4229b8>
+Did you mean? commit_message_regex_change):
+```
+
+This error is caused by an EE feature being added to a CE instance on the initial move to EE.
+After the instance is moved back to CE and then is upgraded to EE again, the
+`push_rules` table already exists in the database. Therefore, a migration is
+unable to add the `commit_message_regex_change` column.
+
+This results in the [backport migration of EE tables](https://gitlab.com/gitlab-org/gitlab/-/blob/cf00e431024018ddd82158f8a9210f113d0f4dbc/db/migrate/20190402150158_backport_enterprise_schema.rb#L1619) not working correctly.
+The backport migration assumes that certain tables in the database do not exist when running CE.
+
+To fix this issue, manually add the missing `commit_message_negative_regex` column and restart GitLab:
+
+```shell
+# Access psql
+sudo gitlab-rails dbconsole
+
+# Add the missing column
+ALTER TABLE push_rules ADD COLUMN commit_message_negative_regex VARCHAR;
+
+# Exit psql
+\q
+
+# Restart GitLab
+sudo gitlab-ctl restart
+```
+
+### Error `Failed to connect to the internal GitLab API` on a separate GitLab Pages server
+
+Please see [GitLab Pages troubleshooting](../../administration/pages/index.md#failed-to-connect-to-the-internal-gitlab-api).
diff --git a/doc/user/admin_area/settings/img/user_and_ip_rate_limits.png b/doc/user/admin_area/settings/img/user_and_ip_rate_limits.png
deleted file mode 100644
index 5056e8354a9..00000000000
--- a/doc/user/admin_area/settings/img/user_and_ip_rate_limits.png
+++ /dev/null
Binary files differ
diff --git a/doc/user/admin_area/settings/img/user_and_ip_rate_limits_v14_3.png b/doc/user/admin_area/settings/img/user_and_ip_rate_limits_v14_3.png
new file mode 100644
index 00000000000..36f27c4025a
--- /dev/null
+++ b/doc/user/admin_area/settings/img/user_and_ip_rate_limits_v14_3.png
Binary files differ
diff --git a/doc/user/admin_area/settings/user_and_ip_rate_limits.md b/doc/user/admin_area/settings/user_and_ip_rate_limits.md
index 28c78fd8837..0cf6a0a1b82 100644
--- a/doc/user/admin_area/settings/user_and_ip_rate_limits.md
+++ b/doc/user/admin_area/settings/user_and_ip_rate_limits.md
@@ -13,7 +13,8 @@ of a web application. For more details, see
The following limits are disabled by default:
-- Unauthenticated requests
+- Unauthenticated API requests
+- Unauthenticated web requests
- Authenticated API requests
- Authenticated web requests
@@ -21,7 +22,7 @@ To enforce any or all of them:
1. On the top bar, select **Menu > Admin**.
1. On the left sidebar, select **Settings > Network**, and expand **User and IP rate limits**:
- ![user-and-ip-rate-limits](img/user_and_ip_rate_limits.png)
+ ![user-and-ip-rate-limits](img/user_and_ip_rate_limits_v14_3.png)
NOTE:
By default, all Git operations are first tried unauthenticated. Because of this, HTTP Git operations
@@ -129,6 +130,10 @@ a comma-separated list of throttle names.
The possible names are:
- `throttle_unauthenticated`
+ - [Deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/335300) in GitLab 14.3. Use `throttle_unauthenticated_api` or `throttle_unauthenticated_web` instead.
+ `throttle_unauthenticated` is still supported and selects both of them.
+- `throttle_unauthenticated_api`
+- `throttle_unauthenticated_web`
- `throttle_authenticated_api`
- `throttle_authenticated_web`
- `throttle_unauthenticated_protected_paths`
diff --git a/lib/api/entities/blob.rb b/lib/api/entities/blob.rb
index b14ef127b68..12700d99865 100644
--- a/lib/api/entities/blob.rb
+++ b/lib/api/entities/blob.rb
@@ -10,7 +10,7 @@ module API
# in the future we can only return the filename here without the leading
# directory path.
# https://gitlab.com/gitlab-org/gitlab/issues/34521
- expose :filename, &:path
+ expose :path, as: :filename
expose :id
expose :ref
expose :startline
diff --git a/lib/gitlab/git/repository.rb b/lib/gitlab/git/repository.rb
index 4e588ee9db8..bc15bd367d8 100644
--- a/lib/gitlab/git/repository.rb
+++ b/lib/gitlab/git/repository.rb
@@ -127,6 +127,13 @@ module Gitlab
end
end
+ def find_tag(name)
+ wrapped_gitaly_errors do
+ gitaly_ref_client.find_tag(name)
+ end
+ rescue CommandError
+ end
+
def local_branches(sort_by: nil, pagination_params: nil)
wrapped_gitaly_errors do
gitaly_ref_client.local_branches(sort_by: sort_by, pagination_params: pagination_params)
@@ -604,10 +611,6 @@ module Gitlab
end
end
- def find_tag(name)
- tags.find { |tag| tag.name == name }
- end
-
def merge_to_ref(user, **kwargs)
wrapped_gitaly_errors do
gitaly_operation_client.user_merge_to_ref(user, **kwargs)
diff --git a/lib/gitlab/gitaly_client/ref_service.rb b/lib/gitlab/gitaly_client/ref_service.rb
index 6ba68a92dcd..2dafe0e12ba 100644
--- a/lib/gitlab/gitaly_client/ref_service.rb
+++ b/lib/gitlab/gitaly_client/ref_service.rb
@@ -129,6 +129,21 @@ module Gitlab
Gitlab::Git::Branch.new(@repository, encode!(branch.name.dup), branch.target_commit.id, target_commit)
end
+ def find_tag(tag_name)
+ return if tag_name.blank?
+
+ request = Gitaly::FindTagRequest.new(
+ repository: @gitaly_repo,
+ tag_name: encode_binary(tag_name)
+ )
+
+ response = GitalyClient.call(@repository.storage, :ref_service, :find_tag, request, timeout: GitalyClient.medium_timeout)
+ tag = response.tag
+ return unless tag
+
+ Gitlab::Git::Tag.new(@repository, tag)
+ end
+
def delete_refs(refs: [], except_with_prefixes: [])
request = Gitaly::DeleteRefsRequest.new(
repository: @gitaly_repo,
diff --git a/lib/gitlab/signed_tag.rb b/lib/gitlab/signed_tag.rb
index 3b22cb7622d..49194300a39 100644
--- a/lib/gitlab/signed_tag.rb
+++ b/lib/gitlab/signed_tag.rb
@@ -7,12 +7,7 @@ module Gitlab
def initialize(repository, tag)
@repository = repository
@tag = tag
-
- if Feature.enabled?(:get_tag_signatures)
- @signature_data = Gitlab::Git::Tag.extract_signature_lazily(repository, tag.id) if repository
- else
- @signature_data = [signature_text_of_message.b, signed_text_of_message.b]
- end
+ @signature_data = Gitlab::Git::Tag.extract_signature_lazily(repository, tag.id) if repository
end
def signature
@@ -26,22 +21,5 @@ module Gitlab
def signed_text
@signature_data&.fetch(1)
end
-
- private
-
- def signature_text_of_message
- @tag.message.slice(@tag.message.index("-----BEGIN SIGNED MESSAGE-----")..-1)
- rescue StandardError
- nil
- end
-
- def signed_text_of_message
- %{object #{@tag.target_commit.id}
-type commit
-tag #{@tag.name}
-tagger #{@tag.tagger.name} <#{@tag.tagger.email}> #{@tag.tagger.date.seconds} #{@tag.tagger.timezone}
-
-#{@tag.message.gsub(/-----BEGIN SIGNED MESSAGE-----(.*)-----END SIGNED MESSAGE-----/m, "")}}
- end
end
end
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index b99b4c66722..b58dd6bed68 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -12493,6 +12493,9 @@ msgstr ""
msgid "Enable authenticated Git LFS request rate limit"
msgstr ""
+msgid "Enable authenticated web request rate limit"
+msgstr ""
+
msgid "Enable authentication"
msgstr ""
@@ -12598,7 +12601,7 @@ msgstr ""
msgid "Enable unauthenticated API request rate limit"
msgstr ""
-msgid "Enable unauthenticated request rate limit"
+msgid "Enable unauthenticated web request rate limit"
msgstr ""
msgid "Enable user deactivation emails"
@@ -18937,7 +18940,7 @@ msgstr ""
msgid "Iterations|Create cadence"
msgstr ""
-msgid "Iterations|Create your first iteration"
+msgid "Iterations|Create iteration"
msgstr ""
msgid "Iterations|Delete cadence"
@@ -18982,12 +18985,18 @@ msgstr ""
msgid "Iterations|New iteration cadence"
msgstr ""
+msgid "Iterations|No closed iterations."
+msgstr ""
+
msgid "Iterations|No iteration cadences to show."
msgstr ""
msgid "Iterations|No iterations in cadence."
msgstr ""
+msgid "Iterations|No open iterations."
+msgstr ""
+
msgid "Iterations|Number of future iterations you would like to have scheduled"
msgstr ""
@@ -20726,7 +20735,10 @@ msgstr ""
msgid "Max session time"
msgstr ""
-msgid "Max unauthenticated requests per period per IP"
+msgid "Max unauthenticated API requests per period per IP"
+msgstr ""
+
+msgid "Max unauthenticated web requests per period per IP"
msgstr ""
msgid "MaxBuilds"
@@ -25291,6 +25303,9 @@ msgstr ""
msgid "Please set a new password before proceeding."
msgstr ""
+msgid "Please set up a Service Desk email address in order to add a custom suffix. %{linkStart}Learn more%{linkEnd}."
+msgstr ""
+
msgid "Please share your feedback about %{featureName} %{linkStart}in this issue%{linkEnd} to help us improve the experience."
msgstr ""
@@ -35927,16 +35942,19 @@ msgstr ""
msgid "Unassigned"
msgstr ""
+msgid "Unauthenticated API rate limit period in seconds"
+msgstr ""
+
msgid "Unauthenticated API request rate limit"
msgstr ""
-msgid "Unauthenticated rate limit period in seconds"
+msgid "Unauthenticated requests"
msgstr ""
-msgid "Unauthenticated request rate limit"
+msgid "Unauthenticated web rate limit period in seconds"
msgstr ""
-msgid "Unauthenticated requests"
+msgid "Unauthenticated web request rate limit"
msgstr ""
msgid "Undo"
diff --git a/qa/qa/page/admin/settings/component/ip_limits.rb b/qa/qa/page/admin/settings/component/ip_limits.rb
index 1f9bd113cab..a85b96014b3 100644
--- a/qa/qa/page/admin/settings/component/ip_limits.rb
+++ b/qa/qa/page/admin/settings/component/ip_limits.rb
@@ -7,16 +7,18 @@ module QA
module Component
class IpLimits < Page::Base
view 'app/views/admin/application_settings/_ip_limits.html.haml' do
- element :throttle_unauthenticated_checkbox
+ element :throttle_unauthenticated_api_checkbox
+ element :throttle_unauthenticated_web_checkbox
element :throttle_authenticated_api_checkbox
element :throttle_authenticated_web_checkbox
element :save_changes_button
end
def enable_throttles
- check_element(:throttle_unauthenticated_checkbox)
- check_element(:throttle_authenticated_api_checkbox)
- check_element(:throttle_authenticated_web_checkbox)
+ check_element(:throttle_unauthenticated_api_checkbox, true)
+ check_element(:throttle_unauthenticated_web_checkbox, true)
+ check_element(:throttle_authenticated_api_checkbox, true)
+ check_element(:throttle_authenticated_web_checkbox, true)
end
def save_settings
diff --git a/spec/features/admin/admin_settings_spec.rb b/spec/features/admin/admin_settings_spec.rb
index df4e71c06de..f40905415e0 100644
--- a/spec/features/admin/admin_settings_spec.rb
+++ b/spec/features/admin/admin_settings_spec.rb
@@ -546,6 +546,50 @@ RSpec.describe 'Admin updates settings' do
expect(current_settings.dns_rebinding_protection_enabled).to be false
end
+ it 'changes User and IP Rate Limits settings' do
+ visit network_admin_application_settings_path
+
+ page.within('.as-ip-limits') do
+ check 'Enable unauthenticated API request rate limit'
+ fill_in 'Max unauthenticated API requests per period per IP', with: 100
+ fill_in 'Unauthenticated API rate limit period in seconds', with: 200
+
+ check 'Enable unauthenticated web request rate limit'
+ fill_in 'Max unauthenticated web requests per period per IP', with: 300
+ fill_in 'Unauthenticated web rate limit period in seconds', with: 400
+
+ check 'Enable authenticated API request rate limit'
+ fill_in 'Max authenticated API requests per period per user', with: 500
+ fill_in 'Authenticated API rate limit period in seconds', with: 600
+
+ check 'Enable authenticated web request rate limit'
+ fill_in 'Max authenticated web requests per period per user', with: 700
+ fill_in 'Authenticated web rate limit period in seconds', with: 800
+
+ fill_in 'A plain-text response to show to clients that hit the rate limit.', with: 'Custom message'
+
+ click_button 'Save changes'
+ end
+
+ expect(page).to have_content "Application settings saved successfully"
+
+ expect(current_settings).to have_attributes(
+ throttle_unauthenticated_api_enabled: true,
+ throttle_unauthenticated_api_requests_per_period: 100,
+ throttle_unauthenticated_api_period_in_seconds: 200,
+ throttle_unauthenticated_enabled: true,
+ throttle_unauthenticated_requests_per_period: 300,
+ throttle_unauthenticated_period_in_seconds: 400,
+ throttle_authenticated_api_enabled: true,
+ throttle_authenticated_api_requests_per_period: 500,
+ throttle_authenticated_api_period_in_seconds: 600,
+ throttle_authenticated_web_enabled: true,
+ throttle_authenticated_web_requests_per_period: 700,
+ throttle_authenticated_web_period_in_seconds: 800,
+ rate_limiting_response_text: 'Custom message'
+ )
+ end
+
it 'changes Issues rate limits settings' do
visit network_admin_application_settings_path
diff --git a/spec/features/projects/settings/service_desk_setting_spec.rb b/spec/features/projects/settings/service_desk_setting_spec.rb
index 91355d8f625..0924f8320e1 100644
--- a/spec/features/projects/settings/service_desk_setting_spec.rb
+++ b/spec/features/projects/settings/service_desk_setting_spec.rb
@@ -38,7 +38,6 @@ RSpec.describe 'Service Desk Setting', :js, :clean_gitlab_redis_cache do
expect(project.service_desk_enabled).to be_truthy
expect(project.service_desk_address).to be_present
expect(find('[data-testid="incoming-email"]').value).to eq(project.service_desk_incoming_address)
- expect(page).not_to have_selector('#service-desk-project-suffix')
end
end
diff --git a/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js b/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js
index 5323c1afbb5..eacf858f22c 100644
--- a/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js
+++ b/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js
@@ -107,6 +107,29 @@ describe('ServiceDeskSetting', () => {
});
});
+ describe('project suffix', () => {
+ it('input is hidden', () => {
+ wrapper = createComponent({
+ props: { customEmailEnabled: false },
+ });
+
+ const input = wrapper.findByTestId('project-suffix');
+
+ expect(input.exists()).toBe(false);
+ });
+
+ it('input is enabled', () => {
+ wrapper = createComponent({
+ props: { customEmailEnabled: true },
+ });
+
+ const input = wrapper.findByTestId('project-suffix');
+
+ expect(input.exists()).toBe(true);
+ expect(input.attributes('disabled')).toBeUndefined();
+ });
+ });
+
describe('customEmail is the same as incomingEmail', () => {
const email = 'foo@bar.com';
diff --git a/spec/helpers/issuables_description_templates_helper_spec.rb b/spec/helpers/issuables_description_templates_helper_spec.rb
index 638dd201fc8..55649e9087a 100644
--- a/spec/helpers/issuables_description_templates_helper_spec.rb
+++ b/spec/helpers/issuables_description_templates_helper_spec.rb
@@ -56,32 +56,17 @@ RSpec.describe IssuablesDescriptionTemplatesHelper, :clean_gitlab_redis_cache do
let(:templates) do
{
"" => [
- { name: "another_issue_template", id: "another_issue_template" },
- { name: "custom_issue_template", id: "custom_issue_template" }
+ { name: "another_issue_template", id: "another_issue_template", project_id: project.id },
+ { name: "custom_issue_template", id: "custom_issue_template", project_id: project.id }
]
}
end
- it 'returns project templates only' do
+ it 'returns project templates' do
expect(helper.issuable_templates_names(Issue.new)).to eq(%w[another_issue_template custom_issue_template])
end
end
- context 'without matching project templates' do
- let(:templates) do
- {
- "Project Templates" => [
- { name: "another_issue_template", id: "another_issue_template", project_id: non_existing_record_id },
- { name: "custom_issue_template", id: "custom_issue_template", project_id: non_existing_record_id }
- ]
- }
- end
-
- it 'returns empty array' do
- expect(helper.issuable_templates_names(Issue.new)).to eq([])
- end
- end
-
context 'when there are not templates in the project' do
let(:templates) { {} }
diff --git a/spec/lib/gitlab/email/handler/service_desk_handler_spec.rb b/spec/lib/gitlab/email/handler/service_desk_handler_spec.rb
index 2ef3b324db8..2916e65528f 100644
--- a/spec/lib/gitlab/email/handler/service_desk_handler_spec.rb
+++ b/spec/lib/gitlab/email/handler/service_desk_handler_spec.rb
@@ -353,13 +353,4 @@ RSpec.describe Gitlab::Email::Handler::ServiceDeskHandler do
expect { receiver.execute rescue nil }.not_to change { Issue.count }
end
end
-
- def email_fixture(path)
- fixture_file(path).gsub('project_id', project.project_id.to_s)
- end
-
- def service_desk_fixture(path, slug: nil, key: 'mykey')
- slug ||= project.full_path_slug.to_s
- fixture_file(path).gsub('project_slug', slug).gsub('project_key', key)
- end
end
diff --git a/spec/lib/gitlab/git/tag_spec.rb b/spec/lib/gitlab/git/tag_spec.rb
index 79ae47f8a7b..4f56595d7d2 100644
--- a/spec/lib/gitlab/git/tag_spec.rb
+++ b/spec/lib/gitlab/git/tag_spec.rb
@@ -38,7 +38,7 @@ RSpec.describe Gitlab::Git::Tag, :seed_helper do
it { expect(tag.tagger.timezone).to eq("+0200") }
end
- shared_examples 'signed tag' do
+ describe 'signed tag' do
let(:project) { create(:project, :repository) }
let(:tag) { project.repository.find_tag('v1.1.1') }
@@ -54,18 +54,6 @@ RSpec.describe Gitlab::Git::Tag, :seed_helper do
it { expect(tag.tagger.timezone).to eq("+0100") }
end
- context 'with :get_tag_signatures enabled' do
- it_behaves_like 'signed tag'
- end
-
- context 'with :get_tag_signatures disabled' do
- before do
- stub_feature_flags(get_tag_signatures: false)
- end
-
- it_behaves_like 'signed tag'
- end
-
it { expect(repository.tags.size).to eq(SeedRepo::Repo::TAGS.size) }
end
diff --git a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
index 09e3692626c..df2506b87dd 100644
--- a/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/ref_service_spec.rb
@@ -92,6 +92,36 @@ RSpec.describe Gitlab::GitalyClient::RefService do
end
end
+ describe '#find_branch' do
+ it 'sends a find_branch message' do
+ expect_any_instance_of(Gitaly::RefService::Stub)
+ .to receive(:find_branch)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return(double(branch: Gitaly::Branch.new(name: 'name', target_commit: build(:gitaly_commit))))
+
+ client.find_branch('name')
+ end
+ end
+
+ describe '#find_tag' do
+ it 'sends a find_tag message' do
+ expect_any_instance_of(Gitaly::RefService::Stub)
+ .to receive(:find_tag)
+ .with(gitaly_request_with_path(storage_name, relative_path), kind_of(Hash))
+ .and_return(double(tag: Gitaly::Tag.new))
+
+ client.find_tag('name')
+ end
+
+ context 'when tag is empty' do
+ it 'does not send a fing_tag message' do
+ expect_any_instance_of(Gitaly::RefService::Stub).not_to receive(:find_tag)
+
+ expect(client.find_tag('')).to be_nil
+ end
+ end
+ end
+
describe '#default_branch_name' do
it 'sends a find_default_branch_name message' do
expect_any_instance_of(Gitaly::RefService::Stub)
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 410fb4ac125..59b75d9626f 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -771,3 +771,5 @@ push_rule:
- group
bulk_import_export:
- group
+service_desk_setting:
+ - file_template_project
diff --git a/spec/lib/gitlab/x509/tag_spec.rb b/spec/lib/gitlab/x509/tag_spec.rb
index be120aaf16a..f52880cfc52 100644
--- a/spec/lib/gitlab/x509/tag_spec.rb
+++ b/spec/lib/gitlab/x509/tag_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe Gitlab::X509::Tag do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '', 'group/project') }
let(:project) { create(:project, :repository) }
- shared_examples 'signed tag' do
+ describe 'signed tag' do
let(:tag) { project.repository.find_tag('v1.1.1') }
let(:certificate_attributes) do
{
@@ -33,24 +33,10 @@ RSpec.describe Gitlab::X509::Tag do
it { expect(signature.x509_certificate.x509_issuer).to have_attributes(issuer_attributes) }
end
- shared_examples 'unsigned tag' do
+ describe 'unsigned tag' do
let(:tag) { project.repository.find_tag('v1.0.0') }
it { expect(signature).to be_nil }
end
-
- context 'with :get_tag_signatures enabled' do
- it_behaves_like 'signed tag'
- it_behaves_like 'unsigned tag'
- end
-
- context 'with :get_tag_signatures disabled' do
- before do
- stub_feature_flags(get_tag_signatures: false)
- end
-
- it_behaves_like 'signed tag'
- it_behaves_like 'unsigned tag'
- end
end
end
diff --git a/spec/migrations/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks_spec.rb b/spec/migrations/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks_spec.rb
new file mode 100644
index 00000000000..8d46ba7eb58
--- /dev/null
+++ b/spec/migrations/20210906100316_drop_temporary_columns_and_triggers_for_ci_build_trace_chunks_spec.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!('drop_temporary_columns_and_triggers_for_ci_build_trace_chunks')
+
+RSpec.describe DropTemporaryColumnsAndTriggersForCiBuildTraceChunks do
+ let(:ci_build_trace_chunks_table) { table(:ci_build_trace_chunks) }
+
+ it 'correctly migrates up and down' do
+ reversible_migration do |migration|
+ migration.before -> {
+ expect(ci_build_trace_chunks_table.column_names).to include('build_id_convert_to_bigint')
+ }
+
+ migration.after -> {
+ ci_build_trace_chunks_table.reset_column_information
+ expect(ci_build_trace_chunks_table.column_names).not_to include('build_id_convert_to_bigint')
+ }
+ end
+ end
+end
diff --git a/spec/migrations/disable_job_token_scope_when_unused_spec.rb b/spec/migrations/disable_job_token_scope_when_unused_spec.rb
new file mode 100644
index 00000000000..d969c98aa0f
--- /dev/null
+++ b/spec/migrations/disable_job_token_scope_when_unused_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+require_migration!
+
+RSpec.describe DisableJobTokenScopeWhenUnused do
+ let(:ci_cd_settings) { table(:project_ci_cd_settings) }
+ let(:links) { table(:ci_job_token_project_scope_links) }
+ let(:namespaces) { table(:namespaces) }
+ let(:projects) { table(:projects) }
+
+ let(:namespace) { namespaces.create!(name: 'test', path: 'path', type: 'Group') }
+
+ let(:project_with_used_scope) { projects.create!(namespace_id: namespace.id) }
+ let!(:used_scope_settings) { ci_cd_settings.create!(project_id: project_with_used_scope.id, job_token_scope_enabled: true) }
+ let(:target_project) { projects.create!(namespace_id: namespace.id) }
+ let!(:link) { links.create!(source_project_id: project_with_used_scope.id, target_project_id: target_project.id) }
+
+ let(:project_with_unused_scope) { projects.create!(namespace_id: namespace.id) }
+ let!(:unused_scope_settings) { ci_cd_settings.create!(project_id: project_with_unused_scope.id, job_token_scope_enabled: true) }
+
+ let(:project_with_disabled_scope) { projects.create!(namespace_id: namespace.id) }
+ let!(:disabled_scope_settings) { ci_cd_settings.create!(project_id: project_with_disabled_scope.id, job_token_scope_enabled: false) }
+
+ describe '#up' do
+ it 'sets job_token_scope_enabled to false for projects not having job token scope configured' do
+ migrate!
+
+ expect(unused_scope_settings.reload.job_token_scope_enabled).to be_falsey
+ end
+
+ it 'keeps the scope enabled for projects that are using it' do
+ migrate!
+
+ expect(used_scope_settings.reload.job_token_scope_enabled).to be_truthy
+ end
+
+ it 'keeps the scope disabled for projects having it disabled' do
+ migrate!
+
+ expect(disabled_scope_settings.reload.job_token_scope_enabled).to be_falsey
+ end
+ end
+end
diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb
index 4dc47a7efc1..9d305e31bad 100644
--- a/spec/models/clusters/cluster_spec.rb
+++ b/spec/models/clusters/cluster_spec.rb
@@ -912,8 +912,8 @@ RSpec.describe Clusters::Cluster, :use_clean_rails_memory_store_caching do
subject { cluster.kubernetes_namespace_for(environment, deployable: build) }
let(:environment_name) { 'the-environment-name' }
- let(:environment) { create(:environment, name: environment_name, project: cluster.project, last_deployable: build) }
- let(:build) { create(:ci_build, environment: environment_name, project: cluster.project) }
+ let(:environment) { create(:environment, name: environment_name, project: cluster.project) }
+ let(:build) { create(:ci_build, environment: environment, project: cluster.project) }
let(:cluster) { create(:cluster, :project, managed: managed_cluster) }
let(:managed_cluster) { true }
let(:default_namespace) { Gitlab::Kubernetes::DefaultNamespace.new(cluster, project: cluster.project).from_environment_slug(environment.slug) }
diff --git a/spec/models/environment_spec.rb b/spec/models/environment_spec.rb
index 7fb6de8b77e..e3e9d1f7a71 100644
--- a/spec/models/environment_spec.rb
+++ b/spec/models/environment_spec.rb
@@ -691,6 +691,28 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
end
end
+ describe '#last_deployable' do
+ subject { environment.last_deployable }
+
+ context 'does not join across databases' do
+ let(:pipeline_a) { create(:ci_pipeline, project: project) }
+ let(:pipeline_b) { create(:ci_pipeline, project: project) }
+ let(:ci_build_a) { create(:ci_build, project: project, pipeline: pipeline_a) }
+ let(:ci_build_b) { create(:ci_build, project: project, pipeline: pipeline_b) }
+
+ before do
+ create(:deployment, :success, project: project, environment: environment, deployable: ci_build_a)
+ create(:deployment, :failed, project: project, environment: environment, deployable: ci_build_b)
+ end
+
+ it 'when called' do
+ with_cross_joins_prevented do
+ expect(subject.id).to eq(ci_build_a.id)
+ end
+ end
+ end
+ end
+
describe '#last_visible_deployment' do
subject { environment.last_visible_deployment }
@@ -733,6 +755,86 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
end
end
+ describe '#last_visible_deployable' do
+ subject { environment.last_visible_deployable }
+
+ context 'does not join across databases' do
+ let(:pipeline_a) { create(:ci_pipeline, project: project) }
+ let(:pipeline_b) { create(:ci_pipeline, project: project) }
+ let(:ci_build_a) { create(:ci_build, project: project, pipeline: pipeline_a) }
+ let(:ci_build_b) { create(:ci_build, project: project, pipeline: pipeline_b) }
+
+ before do
+ create(:deployment, :success, project: project, environment: environment, deployable: ci_build_a)
+ create(:deployment, :failed, project: project, environment: environment, deployable: ci_build_b)
+ end
+
+ it 'for direct call' do
+ with_cross_joins_prevented do
+ expect(subject.id).to eq(ci_build_b.id)
+ end
+ end
+
+ it 'for preload' do
+ environment.reload
+
+ with_cross_joins_prevented do
+ ActiveRecord::Associations::Preloader.new.preload(environment, [last_visible_deployable: []])
+ expect(subject.id).to eq(ci_build_b.id)
+ end
+ end
+ end
+
+ context 'call after preload' do
+ it 'fetches from association cache' do
+ pipeline = create(:ci_pipeline, project: project)
+ ci_build = create(:ci_build, project: project, pipeline: pipeline)
+ create(:deployment, :failed, project: project, environment: environment, deployable: ci_build)
+
+ environment.reload
+ ActiveRecord::Associations::Preloader.new.preload(environment, [last_visible_deployable: []])
+
+ query_count = ActiveRecord::QueryRecorder.new do
+ expect(subject.id).to eq(ci_build.id)
+ end.count
+
+ expect(query_count).to eq(0)
+ end
+ end
+
+ context 'when the feature for disable_join is disabled' do
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+ let(:ci_build) { create(:ci_build, project: project, pipeline: pipeline) }
+
+ before do
+ stub_feature_flags(environment_last_visible_pipeline_disable_joins: false)
+ create(:deployment, :failed, project: project, environment: environment, deployable: ci_build)
+ end
+
+ context 'for preload' do
+ it 'executes the original association instead of override' do
+ environment.reload
+ ActiveRecord::Associations::Preloader.new.preload(environment, [last_visible_deployable: []])
+
+ expect_any_instance_of(Deployment).not_to receive(:deployable)
+
+ query_count = ActiveRecord::QueryRecorder.new do
+ expect(subject.id).to eq(ci_build.id)
+ end.count
+
+ expect(query_count).to eq(0)
+ end
+ end
+
+ context 'for direct call' do
+ it 'executes the original association instead of override' do
+ expect_any_instance_of(Deployment).not_to receive(:deployable)
+ expect(subject.id).to eq(ci_build.id)
+ end
+ end
+ end
+ end
+
describe '#last_visible_pipeline' do
let(:user) { create(:user) }
let_it_be(:project) { create(:project, :repository) }
@@ -777,6 +879,35 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
expect(last_pipeline).to eq(failed_pipeline)
end
+ context 'does not join across databases' do
+ let(:pipeline_a) { create(:ci_pipeline, project: project) }
+ let(:pipeline_b) { create(:ci_pipeline, project: project) }
+ let(:ci_build_a) { create(:ci_build, project: project, pipeline: pipeline_a) }
+ let(:ci_build_b) { create(:ci_build, project: project, pipeline: pipeline_b) }
+
+ before do
+ create(:deployment, :success, project: project, environment: environment, deployable: ci_build_a)
+ create(:deployment, :failed, project: project, environment: environment, deployable: ci_build_b)
+ end
+
+ subject { environment.last_visible_pipeline }
+
+ it 'for direct call' do
+ with_cross_joins_prevented do
+ expect(subject.id).to eq(pipeline_b.id)
+ end
+ end
+
+ it 'for preload' do
+ environment.reload
+
+ with_cross_joins_prevented do
+ ActiveRecord::Associations::Preloader.new.preload(environment, [last_visible_pipeline: []])
+ expect(subject.id).to eq(pipeline_b.id)
+ end
+ end
+ end
+
context 'for the environment' do
it 'returns the last pipeline' do
pipeline = create(:ci_pipeline, project: project, user: user, sha: commit.sha)
@@ -815,6 +946,57 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching do
end
end
end
+
+ context 'call after preload' do
+ it 'fetches from association cache' do
+ pipeline = create(:ci_pipeline, project: project)
+ ci_build = create(:ci_build, project: project, pipeline: pipeline)
+ create(:deployment, :failed, project: project, environment: environment, deployable: ci_build)
+
+ environment.reload
+ ActiveRecord::Associations::Preloader.new.preload(environment, [last_visible_pipeline: []])
+
+ query_count = ActiveRecord::QueryRecorder.new do
+ expect(environment.last_visible_pipeline.id).to eq(pipeline.id)
+ end.count
+
+ expect(query_count).to eq(0)
+ end
+ end
+
+ context 'when the feature for disable_join is disabled' do
+ let(:pipeline) { create(:ci_pipeline, project: project) }
+ let(:ci_build) { create(:ci_build, project: project, pipeline: pipeline) }
+
+ before do
+ stub_feature_flags(environment_last_visible_pipeline_disable_joins: false)
+ create(:deployment, :failed, project: project, environment: environment, deployable: ci_build)
+ end
+
+ subject { environment.last_visible_pipeline }
+
+ context 'for preload' do
+ it 'executes the original association instead of override' do
+ environment.reload
+ ActiveRecord::Associations::Preloader.new.preload(environment, [last_visible_pipeline: []])
+
+ expect_any_instance_of(Ci::Build).not_to receive(:pipeline)
+
+ query_count = ActiveRecord::QueryRecorder.new do
+ expect(subject.id).to eq(pipeline.id)
+ end.count
+
+ expect(query_count).to eq(0)
+ end
+ end
+
+ context 'for direct call' do
+ it 'executes the original association instead of override' do
+ expect_any_instance_of(Ci::Build).not_to receive(:pipeline)
+ expect(subject.id).to eq(pipeline.id)
+ end
+ end
+ end
end
describe '#upcoming_deployment' do
diff --git a/spec/models/project_ci_cd_setting_spec.rb b/spec/models/project_ci_cd_setting_spec.rb
index c206ba27ec1..406485d8cc8 100644
--- a/spec/models/project_ci_cd_setting_spec.rb
+++ b/spec/models/project_ci_cd_setting_spec.rb
@@ -21,12 +21,6 @@ RSpec.describe ProjectCiCdSetting do
end
end
- describe '#job_token_scope_enabled' do
- it 'is true by default' do
- expect(described_class.new.job_token_scope_enabled).to be_truthy
- end
- end
-
describe '#default_git_depth' do
let(:default_value) { described_class::DEFAULT_GIT_DEPTH }
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 047e1ac93e2..9c2f269de46 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -2366,6 +2366,42 @@ RSpec.describe Repository do
end
end
+ describe '#find_tag' do
+ before do
+ allow(Gitlab::GitalyClient).to receive(:call).and_call_original
+ end
+
+ it 'finds a tag with specified name by performing FindTag request' do
+ expect(Gitlab::GitalyClient)
+ .to receive(:call).with(anything, :ref_service, :find_tag, anything, anything).and_call_original
+
+ expect(repository.find_tag('v1.1.0').name).to eq('v1.1.0')
+ end
+
+ it 'does not perform Gitaly call when tags are preloaded' do
+ repository.tags
+
+ expect(Gitlab::GitalyClient).not_to receive(:call)
+
+ expect(repository.find_tag('v1.1.0').name).to eq('v1.1.0')
+ end
+
+ it 'returns nil when tag does not exists' do
+ expect(repository.find_tag('does-not-exist')).to be_nil
+ end
+
+ context 'when find_tag_via_gitaly is disabled' do
+ it 'fetches all tags' do
+ stub_feature_flags(find_tag_via_gitaly: false)
+
+ expect(Gitlab::GitalyClient)
+ .to receive(:call).with(anything, :ref_service, :find_all_tags, anything, anything).and_call_original
+
+ expect(repository.find_tag('v1.1.0').name).to eq('v1.1.0')
+ end
+ end
+ end
+
describe '#avatar' do
it 'returns nil if repo does not exist' do
allow(repository).to receive(:root_ref).and_raise(Gitlab::Git::Repository::NoRepository)
diff --git a/spec/support/shared_contexts/email_shared_context.rb b/spec/support/shared_contexts/email_shared_context.rb
index 14c6c85cc43..0dc66eeb2ee 100644
--- a/spec/support/shared_contexts/email_shared_context.rb
+++ b/spec/support/shared_contexts/email_shared_context.rb
@@ -18,6 +18,15 @@ RSpec.shared_context :email_shared_context do
end
end
+def email_fixture(path)
+ fixture_file(path).gsub('project_id', project.project_id.to_s)
+end
+
+def service_desk_fixture(path, slug: nil, key: 'mykey')
+ slug ||= project.full_path_slug.to_s
+ fixture_file(path).gsub('project_slug', slug).gsub('project_key', key)
+end
+
RSpec.shared_examples :reply_processing_shared_examples do
context 'when the user could not be found' do
before do