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-04-27 18:09:52 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-04-27 18:09:52 +0300
commita2f36202361dcef1f2c9242929f81a4090b9ce97 (patch)
treeba21b187bf565cde47412e89bb1ccde829672dd9
parent154523302b10ab5aeb67bde861880a98e3f8117a (diff)
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--.rubocop_manual_todo.yml1
-rw-r--r--app/assets/javascripts/ci_variable_list/components/ci_variable_table.vue23
-rw-r--r--app/assets/javascripts/pages/projects/settings/packages_and_registries/index/index.js5
-rw-r--r--app/assets/stylesheets/pages/settings_ci_cd.scss4
-rw-r--r--app/controllers/confirmations_controller.rb2
-rw-r--r--app/controllers/projects/settings/packages_and_registries_controller.rb23
-rw-r--r--app/controllers/whats_new_controller.rb5
-rw-r--r--app/helpers/application_settings_helper.rb3
-rw-r--r--app/helpers/projects_helper.rb11
-rw-r--r--app/helpers/whats_new_helper.rb29
-rw-r--r--app/models/application_setting.rb5
-rw-r--r--app/models/application_setting_implementation.rb3
-rw-r--r--app/models/project_services/bamboo_service.rb4
-rw-r--r--app/models/project_services/jenkins_service.rb4
-rw-r--r--app/models/release_highlight.rb34
-rw-r--r--app/views/admin/application_settings/_whats_new.html.haml13
-rw-r--r--app/views/admin/application_settings/preferences.html.haml11
-rw-r--r--app/views/layouts/nav/sidebar/_project_menus.html.haml5
-rw-r--r--app/views/projects/milestones/_form.html.haml2
-rw-r--r--app/views/projects/pipelines/_with_tabs.html.haml6
-rw-r--r--app/views/projects/project_members/index.html.haml6
-rw-r--r--app/views/projects/runners/_group_runners.html.haml2
-rw-r--r--app/views/projects/runners/_shared_runners.html.haml4
-rw-r--r--app/views/projects/settings/packages_and_registries/index.html.haml16
-rw-r--r--app/views/projects/triggers/_trigger.html.haml4
-rw-r--r--app/views/shared/milestones/_form_dates.html.haml4
-rw-r--r--app/views/shared/milestones/_search_form.html.haml2
-rw-r--r--changelogs/unreleased/feat-whats-new-application-setting.yml5
-rw-r--r--changelogs/unreleased/gl-badge-pipelines.yml5
-rw-r--r--changelogs/unreleased/gl-form-milestone-search.yml5
-rw-r--r--changelogs/unreleased/gl-form-new-milestone.yml5
-rw-r--r--changelogs/unreleased/jswain_remember_email_post_confirmation.yml5
-rw-r--r--changelogs/unreleased/ui-text-ci-integrations.yml5
-rw-r--r--config/routes/project.rb2
-rw-r--r--danger/product_intelligence/Dangerfile13
-rw-r--r--db/migrate/20210407111027_add_whats_new_application_setting.rb7
-rw-r--r--db/schema_migrations/202104071110271
-rw-r--r--db/structure.sql1
-rw-r--r--doc/administration/auth/smartcard.md5
-rw-r--r--doc/administration/geo/replication/object_storage.md18
-rw-r--r--doc/administration/geo/replication/security_review.md68
-rw-r--r--doc/administration/housekeeping.md11
-rw-r--r--doc/administration/reference_architectures/troubleshooting.md2
-rw-r--r--doc/administration/whats-new.md18
-rw-r--r--doc/api/settings.md1
-rw-r--r--doc/development/usage_ping/dictionary.md24
-rw-r--r--doc/install/installation.md5
-rw-r--r--doc/update/upgrading_from_source.md7
-rw-r--r--doc/user/admin_area/settings/index.md1
-rw-r--r--doc/user/analytics/index.md8
-rw-r--r--lib/api/settings.rb1
-rw-r--r--lib/gitlab/usage_data_counters/known_events/analytics.yml90
-rw-r--r--lib/gitlab/usage_data_counters/known_events/common.yml86
-rw-r--r--locale/gitlab.pot45
-rw-r--r--spec/features/project_variables_spec.rb2
-rw-r--r--spec/features/projects/navbar_spec.rb20
-rw-r--r--spec/features/projects/settings/registry_settings_spec.rb160
-rw-r--r--spec/features/projects/settings/user_manages_project_members_spec.rb26
-rw-r--r--spec/features/users/signup_spec.rb12
-rw-r--r--spec/features/whats_new_spec.rb18
-rw-r--r--spec/fixtures/whats_new/20201225_01_04.yml19
-rw-r--r--spec/helpers/whats_new_helper_spec.rb57
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb3
-rw-r--r--spec/models/application_setting_spec.rb5
-rw-r--r--spec/models/release_highlight_spec.rb50
-rw-r--r--spec/requests/api/settings_spec.rb28
-rw-r--r--spec/requests/whats_new_controller_spec.rb14
-rw-r--r--spec/support/shared_examples/features/variable_list_shared_examples.rb24
68 files changed, 810 insertions, 303 deletions
diff --git a/.rubocop_manual_todo.yml b/.rubocop_manual_todo.yml
index a0a68f18e13..920638eaa6a 100644
--- a/.rubocop_manual_todo.yml
+++ b/.rubocop_manual_todo.yml
@@ -397,7 +397,6 @@ RSpec/EmptyLineAfterFinalLetItBe:
- ee/spec/features/markdown/metrics_spec.rb
- ee/spec/features/registrations/group_invites_during_signup_flow_spec.rb
- ee/spec/features/subscriptions_spec.rb
- - ee/spec/graphql/types/issue_type_spec.rb
- ee/spec/helpers/ee/graph_helper_spec.rb
- ee/spec/helpers/ee/issues_helper_spec.rb
- ee/spec/helpers/ee/projects/incidents_helper_spec.rb
diff --git a/app/assets/javascripts/ci_variable_list/components/ci_variable_table.vue b/app/assets/javascripts/ci_variable_list/components/ci_variable_table.vue
index e5923124653..b959d97daea 100644
--- a/app/assets/javascripts/ci_variable_list/components/ci_variable_table.vue
+++ b/app/assets/javascripts/ci_variable_list/components/ci_variable_table.vue
@@ -162,23 +162,26 @@ export default {
</p>
</template>
</gl-table>
- <div class="ci-variable-actions" :class="{ 'justify-content-center': !tableIsNotEmpty }">
+ <div
+ class="ci-variable-actions gl-display-flex"
+ :class="{ 'justify-content-center': !tableIsNotEmpty }"
+ >
+ <gl-button
+ ref="add-ci-variable"
+ v-gl-modal-directive="$options.modalId"
+ class="gl-mr-3"
+ data-qa-selector="add_ci_variable_button"
+ variant="confirm"
+ category="primary"
+ >{{ __('Add variable') }}</gl-button
+ >
<gl-button
v-if="tableIsNotEmpty"
ref="secret-value-reveal-button"
data-qa-selector="reveal_ci_variable_value_button"
- class="gl-mr-3"
@click="toggleValues(!valuesHidden)"
>{{ valuesButtonText }}</gl-button
>
- <gl-button
- ref="add-ci-variable"
- v-gl-modal-directive="$options.modalId"
- data-qa-selector="add_ci_variable_button"
- variant="success"
- category="primary"
- >{{ __('Add Variable') }}</gl-button
- >
</div>
</div>
</template>
diff --git a/app/assets/javascripts/pages/projects/settings/packages_and_registries/index/index.js b/app/assets/javascripts/pages/projects/settings/packages_and_registries/index/index.js
new file mode 100644
index 00000000000..93c6a2c63a3
--- /dev/null
+++ b/app/assets/javascripts/pages/projects/settings/packages_and_registries/index/index.js
@@ -0,0 +1,5 @@
+import registrySettingsApp from '~/packages_and_registries/settings/project/registry_settings_bundle';
+import initSettingsPanels from '~/settings_panels';
+
+registrySettingsApp();
+initSettingsPanels();
diff --git a/app/assets/stylesheets/pages/settings_ci_cd.scss b/app/assets/stylesheets/pages/settings_ci_cd.scss
index 346b3f61caa..7d74070b4f2 100644
--- a/app/assets/stylesheets/pages/settings_ci_cd.scss
+++ b/app/assets/stylesheets/pages/settings_ci_cd.scss
@@ -11,10 +11,6 @@
.trigger-actions {
white-space: nowrap;
-
- .btn {
- margin-left: 10px;
- }
}
.auto-devops-card {
diff --git a/app/controllers/confirmations_controller.rb b/app/controllers/confirmations_controller.rb
index c42c9827eaf..163c5fbca67 100644
--- a/app/controllers/confirmations_controller.rb
+++ b/app/controllers/confirmations_controller.rb
@@ -27,7 +27,7 @@ class ConfirmationsController < Devise::ConfirmationsController
else
Gitlab::AppLogger.info("Email Confirmed: username=#{resource.username} email=#{resource.email} ip=#{request.remote_ip}")
flash[:notice] = flash[:notice] + _(" Please sign in.")
- new_session_path(:user, anchor: 'login-pane')
+ new_session_path(:user, anchor: 'login-pane', invite_email: resource.email)
end
end
diff --git a/app/controllers/projects/settings/packages_and_registries_controller.rb b/app/controllers/projects/settings/packages_and_registries_controller.rb
new file mode 100644
index 00000000000..3756f5bb2d6
--- /dev/null
+++ b/app/controllers/projects/settings/packages_and_registries_controller.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+module Projects
+ module Settings
+ class PackagesAndRegistriesController < Projects::ApplicationController
+ layout 'project_settings'
+
+ before_action :authorize_admin_project!
+ before_action :packages_and_registries_settings_enabled!
+
+ feature_category :package_registry
+
+ def index
+ end
+
+ private
+
+ def packages_and_registries_settings_enabled!
+ render_404 unless settings_packages_and_registries_enabled?(project)
+ end
+ end
+ end
+end
diff --git a/app/controllers/whats_new_controller.rb b/app/controllers/whats_new_controller.rb
index e24b0bbc7bb..6f389aa4924 100644
--- a/app/controllers/whats_new_controller.rb
+++ b/app/controllers/whats_new_controller.rb
@@ -5,6 +5,7 @@ class WhatsNewController < ApplicationController
skip_before_action :authenticate_user!
+ before_action :check_whats_new_enabled
before_action :check_valid_page_param, :set_pagination_headers
feature_category :navigation
@@ -19,6 +20,10 @@ class WhatsNewController < ApplicationController
private
+ def check_whats_new_enabled
+ render_404 if Gitlab::CurrentSettings.current_application_settings.whats_new_variant_disabled?
+ end
+
def check_valid_page_param
render_404 if current_page < 1
end
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index 4373f47877f..d643223255f 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -364,7 +364,8 @@ module ApplicationSettingsHelper
:rate_limiting_response_text,
:container_registry_expiration_policies_worker_capacity,
:container_registry_cleanup_tags_service_max_list_size,
- :keep_latest_artifact
+ :keep_latest_artifact,
+ :whats_new_variant
]
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 4be6cd4276b..cfafb0443b9 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -743,6 +743,7 @@ module ProjectsHelper
operations#show
badges#index
pages#show
+ packages_and_registries#index
]
end
@@ -782,6 +783,16 @@ module ProjectsHelper
end
def settings_container_registry_expiration_policy_available?(project)
+ Feature.disabled?(:sidebar_refactor) &&
+ can_destroy_container_registry_image?(current_user, project)
+ end
+
+ def settings_packages_and_registries_enabled?(project)
+ Feature.enabled?(:sidebar_refactor) &&
+ can_destroy_container_registry_image?(current_user, project)
+ end
+
+ def can_destroy_container_registry_image?(current_user, project)
Gitlab.config.registry.enabled &&
can?(current_user, :destroy_container_image, project)
end
diff --git a/app/helpers/whats_new_helper.rb b/app/helpers/whats_new_helper.rb
index 9362ae1491f..5fca00c5dce 100644
--- a/app/helpers/whats_new_helper.rb
+++ b/app/helpers/whats_new_helper.rb
@@ -10,6 +10,33 @@ module WhatsNewHelper
end
def display_whats_new?
- Gitlab.dev_env_org_or_com? || user_signed_in?
+ (Gitlab.dev_env_org_or_com? || user_signed_in?) &&
+ !Gitlab::CurrentSettings.current_application_settings.whats_new_variant_disabled?
+ end
+
+ def whats_new_variants
+ ApplicationSetting.whats_new_variants
+ end
+
+ def whats_new_variants_label(variant)
+ case variant
+ when 'all_tiers'
+ _("Enable What's new: All tiers")
+ when 'current_tier'
+ _("Enable What's new: Current tier only")
+ when 'disabled'
+ _("Disable What's new")
+ end
+ end
+
+ def whats_new_variants_description(variant)
+ case variant
+ when 'all_tiers'
+ _("What's new presents new features from all tiers to help you keep track of all new features.")
+ when 'current_tier'
+ _("What's new presents new features for your current subscription tier, while hiding new features not available to your subscription tier.")
+ when 'disabled'
+ _("What's new is disabled and can no longer be viewed.")
+ end
end
end
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index 9ed0ebe49cc..0be511e5f6e 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -13,6 +13,8 @@ class ApplicationSetting < ApplicationRecord
KROKI_URL_ERROR_MESSAGE = 'Please check your Kroki URL setting in ' \
'Admin Area > Settings > General > Kroki'
+ enum whats_new_variant: { all_tiers: 0, current_tier: 1, disabled: 2 }, _prefix: true
+
add_authentication_token_field :runners_registration_token, encrypted: -> { Feature.enabled?(:application_settings_tokens_optional_encryption) ? :optional : :required }
add_authentication_token_field :health_check_access_token
add_authentication_token_field :static_objects_external_storage_auth_token
@@ -491,6 +493,9 @@ class ApplicationSetting < ApplicationRecord
allow_nil: true,
numericality: { only_integer: true, greater_than: 0 }
+ validates :whats_new_variant,
+ inclusion: { in: ApplicationSetting.whats_new_variants.keys }
+
attr_encrypted :asset_proxy_secret_key,
mode: :per_attribute_iv,
key: Settings.attr_encrypted_db_key_base_truncated,
diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb
index 88fd17133f2..140669c0695 100644
--- a/app/models/application_setting_implementation.rb
+++ b/app/models/application_setting_implementation.rb
@@ -187,7 +187,8 @@ module ApplicationSettingImplementation
kroki_enabled: false,
kroki_url: nil,
kroki_formats: { blockdiag: false, bpmn: false, excalidraw: false },
- rate_limiting_response_text: nil
+ rate_limiting_response_text: nil,
+ whats_new_variant: 0
}
end
diff --git a/app/models/project_services/bamboo_service.rb b/app/models/project_services/bamboo_service.rb
index a892d1a4314..60f53bd4a7d 100644
--- a/app/models/project_services/bamboo_service.rb
+++ b/app/models/project_services/bamboo_service.rb
@@ -36,12 +36,12 @@ class BambooService < CiService
end
def description
- s_('BambooService|Use the Atlassian Bamboo CI/CD server with GitLab.')
+ s_('BambooService|Run CI/CD pipelines with Atlassian Bamboo.')
end
def help
docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('user/project/integrations/bamboo'), target: '_blank', rel: 'noopener noreferrer'
- s_('BambooService|Use Atlassian Bamboo to run CI/CD pipelines. You must set up automatic revision labeling and a repository trigger in Bamboo. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
+ s_('BambooService|Run CI/CD pipelines with Atlassian Bamboo. You must set up automatic revision labeling and a repository trigger in Bamboo. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
def self.to_param
diff --git a/app/models/project_services/jenkins_service.rb b/app/models/project_services/jenkins_service.rb
index 6a123517b84..990a35cd617 100644
--- a/app/models/project_services/jenkins_service.rb
+++ b/app/models/project_services/jenkins_service.rb
@@ -64,12 +64,12 @@ class JenkinsService < CiService
end
def description
- s_('An extendable open source CI/CD server.')
+ s_('Run CI/CD pipelines with Jenkins.')
end
def help
docs_link = link_to _('Learn more.'), Rails.application.routes.url_helpers.help_page_url('integration/jenkins'), target: '_blank', rel: 'noopener noreferrer'
- s_('Trigger Jenkins builds when you push to a repository, or when a merge request is created, updated, or merged. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
+ s_('Run CI/CD pipelines with Jenkins when you push to a repository, or when a merge request is created, updated, or merged. %{docs_link}').html_safe % { docs_link: docs_link.html_safe }
end
def self.to_param
diff --git a/app/models/release_highlight.rb b/app/models/release_highlight.rb
index 4b0ae251a9f..9c30d0611e6 100644
--- a/app/models/release_highlight.rb
+++ b/app/models/release_highlight.rb
@@ -4,6 +4,10 @@ class ReleaseHighlight
CACHE_DURATION = 1.hour
FILES_PATH = Rails.root.join('data', 'whats_new', '*.yml')
+ FREE_PACKAGE = 'Free'
+ PREMIUM_PACKAGE = 'Premium'
+ ULTIMATE_PACKAGE = 'Ultimate'
+
def self.paginated(page: 1)
key = self.cache_key("items:page-#{page}")
@@ -25,10 +29,8 @@ class ReleaseHighlight
file = File.read(file_path)
items = YAML.safe_load(file, permitted_classes: [Date])
- platform = Gitlab.com? ? 'gitlab-com' : 'self-managed'
-
items&.map! do |item|
- next unless item[platform]
+ next unless include_item?(item)
begin
item.tap {|i| i['body'] = Kramdown::Document.new(i['body']).to_html }
@@ -53,7 +55,8 @@ class ReleaseHighlight
end
def self.cache_key(key)
- ['release_highlight', key, Gitlab.revision].join(':')
+ variant = Gitlab::CurrentSettings.current_application_settings.whats_new_variant
+ ['release_highlight', variant, key, Gitlab.revision].join(':')
end
def self.next_page(current_page: 1)
@@ -88,4 +91,27 @@ class ReleaseHighlight
delegate :each, to: :items
end
+
+ def self.current_package
+ return FREE_PACKAGE unless defined?(License)
+
+ case License.current&.plan&.downcase
+ when License::PREMIUM_PLAN
+ PREMIUM_PACKAGE
+ when License::ULTIMATE_PLAN
+ ULTIMATE_PACKAGE
+ else
+ FREE_PACKAGE
+ end
+ end
+
+ def self.include_item?(item)
+ platform = Gitlab.com? ? 'gitlab-com' : 'self-managed'
+
+ return false unless item[platform]
+
+ return true unless Gitlab::CurrentSettings.current_application_settings.whats_new_variant_current_tier?
+
+ item['packages']&.include?(current_package)
+ end
end
diff --git a/app/views/admin/application_settings/_whats_new.html.haml b/app/views/admin/application_settings/_whats_new.html.haml
new file mode 100644
index 00000000000..70ba994d21e
--- /dev/null
+++ b/app/views/admin/application_settings/_whats_new.html.haml
@@ -0,0 +1,13 @@
+= form_for @application_setting, url: preferences_admin_application_settings_path(anchor: 'js-whats-new-settings'), html: { class: 'fieldset-form whats-new-settings' } do |f|
+ = form_errors(@application_setting)
+
+ - whats_new_variants.keys.each do |variant|
+ .form-check.gl-mb-4
+ = f.radio_button :whats_new_variant, variant, class: 'form-check-input'
+ = f.label :whats_new_variant, value: variant, class: 'form-check-label' do
+ .font-weight-bold
+ = whats_new_variants_label(variant)
+ .option-description
+ = whats_new_variants_description(variant)
+
+ = f.submit _('Save changes'), class: "gl-button btn btn-confirm"
diff --git a/app/views/admin/application_settings/preferences.html.haml b/app/views/admin/application_settings/preferences.html.haml
index fd5ce890648..17bf9ba84a2 100644
--- a/app/views/admin/application_settings/preferences.html.haml
+++ b/app/views/admin/application_settings/preferences.html.haml
@@ -13,6 +13,17 @@
.settings-content
= render 'email'
+%section.settings.as-whats-new-page.no-animate#js-whats-new-settings{ class: ('expanded' if expanded_by_default?) }
+ .settings-header
+ %h4
+ = _("What's new")
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded_by_default? ? _('Collapse') : _('Expand')
+ %p
+ = _("Configure What's new drawer and content.")
+ .settings-content
+ = render 'whats_new'
+
%section.settings.as-help-page.no-animate#js-help-settings{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
diff --git a/app/views/layouts/nav/sidebar/_project_menus.html.haml b/app/views/layouts/nav/sidebar/_project_menus.html.haml
index d26a138cfc7..0507f6d4b16 100644
--- a/app/views/layouts/nav/sidebar/_project_menus.html.haml
+++ b/app/views/layouts/nav/sidebar/_project_menus.html.haml
@@ -274,6 +274,11 @@
= link_to project_pages_path(@project), title: _('Pages') do
%span
= _('Pages')
+ - if settings_packages_and_registries_enabled?(@project)
+ = nav_link(controller: :packages_and_registries) do
+ = link_to project_settings_packages_and_registries_path(@project), title: _('Packages & Registries'), data: { qa_selector: 'project_package_settings_link' } do
+ %span
+ = _('Packages & Registries')
-# Shortcut to Project > Activity
%li.hidden
diff --git a/app/views/projects/milestones/_form.html.haml b/app/views/projects/milestones/_form.html.haml
index 56906eb6e66..a6adfd31834 100644
--- a/app/views/projects/milestones/_form.html.haml
+++ b/app/views/projects/milestones/_form.html.haml
@@ -7,7 +7,7 @@
.col-form-label.col-sm-2
= f.label :title, _('Title')
.col-sm-10
- = f.text_field :title, maxlength: 255, class: 'form-control', data: { qa_selector: 'milestone_title_field' }, required: true, autofocus: true
+ = f.text_field :title, maxlength: 255, class: 'form-control gl-form-input', data: { qa_selector: 'milestone_title_field' }, required: true, autofocus: true
.form-group.row.milestone-description
.col-form-label.col-sm-2
= f.label :description, _('Description')
diff --git a/app/views/projects/pipelines/_with_tabs.html.haml b/app/views/projects/pipelines/_with_tabs.html.haml
index 8af3764650c..e56a240c487 100644
--- a/app/views/projects/pipelines/_with_tabs.html.haml
+++ b/app/views/projects/pipelines/_with_tabs.html.haml
@@ -11,16 +11,16 @@
%li.js-builds-tab-link
= link_to builds_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-builds', action: 'builds', toggle: 'tab' }, class: 'builds-tab' do
= _('Jobs')
- %span.badge.badge-pill.js-builds-counter= pipeline.total_size
+ %span.badge.badge-pill.gl-badge.badge-muted.sm.js-builds-counter= pipeline.total_size
- if @pipeline.failed_builds.present?
%li.js-failures-tab-link
= link_to failures_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-failures', action: 'failures', toggle: 'tab' }, class: 'failures-tab' do
= _('Failed Jobs')
- %span.badge.badge-pill.js-failures-counter= @pipeline.failed_builds.count
+ %span.badge.badge-pill.gl-badge.badge-muted.sm.js-failures-counter= @pipeline.failed_builds.count
%li.js-tests-tab-link
= link_to test_report_project_pipeline_path(@project, @pipeline), data: { target: '#js-tab-tests', action: 'test_report', toggle: 'tab' }, class: 'test-tab' do
= s_('TestReports|Tests')
- %span.badge.badge-pill.js-test-report-badge-counter= @pipeline.test_report_summary.total[:count]
+ %span.badge.badge-pill.gl-badge.badge-muted.sm.js-test-report-badge-counter= @pipeline.test_report_summary.total[:count]
= render_if_exists "projects/pipelines/tabs_holder", pipeline: @pipeline, project: @project
.tab-content
diff --git a/app/views/projects/project_members/index.html.haml b/app/views/projects/project_members/index.html.haml
index 0e4100208d9..01114b8b4f7 100644
--- a/app/views/projects/project_members/index.html.haml
+++ b/app/views/projects/project_members/index.html.haml
@@ -18,7 +18,11 @@
= html_escape(_("Members can be added by project %{i_open}Maintainers%{i_close} or %{i_open}Owners%{i_close}")) % { i_open: '<i>'.html_safe, i_close: '</i>'.html_safe }
.col-md-12.col-lg-6
.gl-display-flex.gl-flex-wrap.gl-justify-content-end
- .js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full', display_text: _('Invite a group') } }
+ = link_to _("Import a project"),
+ import_project_project_members_path(@project),
+ class: "btn btn-default btn-md gl-button gl-mt-3 gl-sm-w-auto gl-w-full",
+ title: _("Import members from another project")
+ .js-invite-group-trigger{ data: { classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite a group') } }
.js-invite-members-trigger{ data: { variant: 'success', classes: 'gl-mt-3 gl-sm-w-auto gl-w-full gl-sm-ml-3', display_text: _('Invite members') } }
= render 'projects/invite_members_modal', project: @project
diff --git a/app/views/projects/runners/_group_runners.html.haml b/app/views/projects/runners/_group_runners.html.haml
index b37b530c33f..5d737bb3901 100644
--- a/app/views/projects/runners/_group_runners.html.haml
+++ b/app/views/projects/runners/_group_runners.html.haml
@@ -13,7 +13,7 @@
%br
%br
- if @project.group_runners_enabled?
- = link_to toggle_group_runners_project_runners_path(@project), class: 'btn gl-button btn-warning-secondary', method: :post do
+ = link_to toggle_group_runners_project_runners_path(@project), class: 'btn gl-button btn-default', method: :post do
= _('Disable group runners')
- else
= link_to toggle_group_runners_project_runners_path(@project), class: 'btn gl-button btn-confirm-secondary', method: :post do
diff --git a/app/views/projects/runners/_shared_runners.html.haml b/app/views/projects/runners/_shared_runners.html.haml
index fccfca38013..f7248baeb27 100644
--- a/app/views/projects/runners/_shared_runners.html.haml
+++ b/app/views/projects/runners/_shared_runners.html.haml
@@ -9,10 +9,10 @@
= _('Shared runners disabled on group level')
- else
- if @project.shared_runners_enabled?
- = link_to toggle_shared_runners_project_runners_path(@project), class: 'btn gl-button btn-warning-secondary', method: :post do
+ = link_to toggle_shared_runners_project_runners_path(@project), class: 'btn gl-button btn-default', method: :post do
= _('Disable shared runners')
- else
- = link_to toggle_shared_runners_project_runners_path(@project), class: 'btn gl-button btn-confirm', method: :post do
+ = link_to toggle_shared_runners_project_runners_path(@project), class: 'btn gl-button btn-confirm-secondary', method: :post do
= _('Enable shared runners')
&nbsp; for this project
diff --git a/app/views/projects/settings/packages_and_registries/index.html.haml b/app/views/projects/settings/packages_and_registries/index.html.haml
new file mode 100644
index 00000000000..561ac7b347d
--- /dev/null
+++ b/app/views/projects/settings/packages_and_registries/index.html.haml
@@ -0,0 +1,16 @@
+- breadcrumb_title _('Packages & Registries')
+- page_title _('Packages & Registries')
+- @content_class = 'limit-container-width' unless fluid_layout
+- expanded = true
+
+%section.settings.no-animate#js-registry-policies{ class: ('expanded' if expanded) }
+ .settings-header
+ %h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
+ = _("Clean up image tags")
+ %button.btn.gl-button.btn-default.js-settings-toggle{ type: 'button' }
+ = expanded ? _('Collapse') : _('Expand')
+ %p
+ = _("Save space and find images in the Container Registry. Remove unneeded tags and keep only the ones you want.")
+ = link_to _('How does cleanup work?'), help_page_path('user/packages/container_registry/index', anchor: 'cleanup-policy'), target: '_blank', rel: 'noopener noreferrer'
+ .settings-content
+ = render 'projects/registry/settings/index'
diff --git a/app/views/projects/triggers/_trigger.html.haml b/app/views/projects/triggers/_trigger.html.haml
index 2def6c06458..081afacdaa6 100644
--- a/app/views/projects/triggers/_trigger.html.haml
+++ b/app/views/projects/triggers/_trigger.html.haml
@@ -30,8 +30,8 @@
%td.text-right.trigger-actions
- revoke_trigger_confirmation = "By revoking a trigger you will break any processes making use of it. Are you sure?"
- if can?(current_user, :admin_trigger, trigger)
- = link_to edit_project_trigger_path(@project, trigger), method: :get, title: "Edit", class: "gl-button btn btn-default btn-sm" do
+ = link_to edit_project_trigger_path(@project, trigger), method: :get, title: "Edit", class: "gl-button btn btn-default btn-icon" do
= sprite_icon('pencil')
- if can?(current_user, :manage_trigger, trigger)
- = link_to project_trigger_path(@project, trigger), data: { confirm: revoke_trigger_confirmation, testid: 'trigger_revoke_button' }, method: :delete, title: "Revoke", class: "gl-button btn btn-default btn-sm btn-trigger-revoke" do
+ = link_to project_trigger_path(@project, trigger), data: { confirm: revoke_trigger_confirmation, testid: 'trigger_revoke_button' }, method: :delete, title: "Revoke", class: "gl-button btn btn-default btn-icon btn-trigger-revoke gl-ml-3" do
= sprite_icon('remove')
diff --git a/app/views/shared/milestones/_form_dates.html.haml b/app/views/shared/milestones/_form_dates.html.haml
index e995584309a..e0664c1feba 100644
--- a/app/views/shared/milestones/_form_dates.html.haml
+++ b/app/views/shared/milestones/_form_dates.html.haml
@@ -3,11 +3,11 @@
.col-form-label.col-sm-2
= f.label :start_date, _('Start Date')
.col-sm-10
- = f.text_field :start_date, class: "datepicker form-control", data: { qa_selector: "start_date_field" }, placeholder: _('Select start date'), autocomplete: 'off'
+ = f.text_field :start_date, class: "datepicker form-control gl-form-input", data: { qa_selector: "start_date_field" }, placeholder: _('Select start date'), autocomplete: 'off'
%a.inline.float-right.gl-mt-2.js-clear-start-date{ href: "#" }= _('Clear start date')
.form-group.row
.col-form-label.col-sm-2
= f.label :due_date, _('Due Date')
.col-sm-10
- = f.text_field :due_date, class: "datepicker form-control", data: { qa_selector: "due_date_field" }, placeholder: _('Select due date'), autocomplete: 'off'
+ = f.text_field :due_date, class: "datepicker form-control gl-form-input", data: { qa_selector: "due_date_field" }, placeholder: _('Select due date'), autocomplete: 'off'
%a.inline.float-right.gl-mt-2.js-clear-due-date{ href: "#" }= _('Clear due date')
diff --git a/app/views/shared/milestones/_search_form.html.haml b/app/views/shared/milestones/_search_form.html.haml
index 403a0224a85..1c51f1ad09d 100644
--- a/app/views/shared/milestones/_search_form.html.haml
+++ b/app/views/shared/milestones/_search_form.html.haml
@@ -1,7 +1,7 @@
= form_tag request.path, method: :get do |f|
= search_field_tag :search_title, params[:search_title],
placeholder: _('Filter by milestone name'),
- class: 'form-control input-short',
+ class: 'form-control gl-form-input input-short',
spellcheck: false
= hidden_field_tag :state, params[:state]
= hidden_field_tag :sort, params[:sort]
diff --git a/changelogs/unreleased/feat-whats-new-application-setting.yml b/changelogs/unreleased/feat-whats-new-application-setting.yml
new file mode 100644
index 00000000000..2851becf8b9
--- /dev/null
+++ b/changelogs/unreleased/feat-whats-new-application-setting.yml
@@ -0,0 +1,5 @@
+---
+title: Add application setting for What's new
+merge_request: 59011
+author: Jonas Wälter @wwwjon
+type: added
diff --git a/changelogs/unreleased/gl-badge-pipelines.yml b/changelogs/unreleased/gl-badge-pipelines.yml
new file mode 100644
index 00000000000..19ce5c75a74
--- /dev/null
+++ b/changelogs/unreleased/gl-badge-pipelines.yml
@@ -0,0 +1,5 @@
+---
+title: Add gl-badge for badges in pipeline page nav
+merge_request: 57970
+author: Yogi (@yo)
+type: changed
diff --git a/changelogs/unreleased/gl-form-milestone-search.yml b/changelogs/unreleased/gl-form-milestone-search.yml
new file mode 100644
index 00000000000..f181fc609b6
--- /dev/null
+++ b/changelogs/unreleased/gl-form-milestone-search.yml
@@ -0,0 +1,5 @@
+---
+title: Apply gl-form-input for search field in milestone page
+merge_request: 58007
+author: Yogi (@yo)
+type: changed
diff --git a/changelogs/unreleased/gl-form-new-milestone.yml b/changelogs/unreleased/gl-form-new-milestone.yml
new file mode 100644
index 00000000000..4f4384875c1
--- /dev/null
+++ b/changelogs/unreleased/gl-form-new-milestone.yml
@@ -0,0 +1,5 @@
+---
+title: Apply gl-form-input for fields in new project milestone page
+merge_request: 58010
+author: Yogi (@yo)
+type: changed
diff --git a/changelogs/unreleased/jswain_remember_email_post_confirmation.yml b/changelogs/unreleased/jswain_remember_email_post_confirmation.yml
new file mode 100644
index 00000000000..4c1c4649672
--- /dev/null
+++ b/changelogs/unreleased/jswain_remember_email_post_confirmation.yml
@@ -0,0 +1,5 @@
+---
+title: Pre-fill user email address after confirming
+merge_request: 60179
+author:
+type: changed
diff --git a/changelogs/unreleased/ui-text-ci-integrations.yml b/changelogs/unreleased/ui-text-ci-integrations.yml
new file mode 100644
index 00000000000..662a2ca9350
--- /dev/null
+++ b/changelogs/unreleased/ui-text-ci-integrations.yml
@@ -0,0 +1,5 @@
+---
+title: Align UI text for CI integrations with each other
+merge_request: 60352
+author:
+type: other
diff --git a/config/routes/project.rb b/config/routes/project.rb
index 09b212bc1a2..edce34acc67 100644
--- a/config/routes/project.rb
+++ b/config/routes/project.rb
@@ -129,6 +129,8 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
put :revoke
end
end
+
+ resources :packages_and_registries, only: [:index]
end
resources :autocomplete_sources, only: [] do
diff --git a/danger/product_intelligence/Dangerfile b/danger/product_intelligence/Dangerfile
index d2bed7629ff..8019fad57db 100644
--- a/danger/product_intelligence/Dangerfile
+++ b/danger/product_intelligence/Dangerfile
@@ -86,8 +86,13 @@ if matching_changed_files.any?
fail format(UPDATE_DICTIONARY_MESSAGE) if required_dictionary_update_changed_files.any? && dictionary_changed_file.empty?
- labels = ['product intelligence']
- labels << 'product intelligence::review pending' unless helper.mr_has_labels?('product intelligence::approved')
-
- markdown(helper.prepare_labels_for_mr(labels))
+ labels = []
+ labels << 'product intelligence' unless helper.mr_has_labels?('product intelligence')
+ labels << 'product intelligence::review pending' unless helper.mr_has_labels?(['product intelligence::approved', 'product intelligence::review pending'])
+
+ if labels.any?
+ gitlab.api.update_merge_request(gitlab.mr_json['project_id'],
+ gitlab.mr_json['iid'],
+ add_labels: helper.prepare_labels_for_mr(labels))
+ end
end
diff --git a/db/migrate/20210407111027_add_whats_new_application_setting.rb b/db/migrate/20210407111027_add_whats_new_application_setting.rb
new file mode 100644
index 00000000000..450c26e2199
--- /dev/null
+++ b/db/migrate/20210407111027_add_whats_new_application_setting.rb
@@ -0,0 +1,7 @@
+# frozen_string_literal: true
+
+class AddWhatsNewApplicationSetting < ActiveRecord::Migration[6.0]
+ def change
+ add_column :application_settings, :whats_new_variant, :integer, limit: 2, default: 0
+ end
+end
diff --git a/db/schema_migrations/20210407111027 b/db/schema_migrations/20210407111027
new file mode 100644
index 00000000000..573100cba8a
--- /dev/null
+++ b/db/schema_migrations/20210407111027
@@ -0,0 +1 @@
+0ae4e5224aeb0c0a78f3730b7c83505946d3aa40680b64fa2f89370ccefdfd45 \ No newline at end of file
diff --git a/db/structure.sql b/db/structure.sql
index eed3851e127..e27a8c0403b 100644
--- a/db/structure.sql
+++ b/db/structure.sql
@@ -9501,6 +9501,7 @@ CREATE TABLE application_settings (
throttle_unauthenticated_packages_api_enabled boolean DEFAULT false NOT NULL,
throttle_authenticated_packages_api_enabled boolean DEFAULT false NOT NULL,
deactivate_dormant_users boolean DEFAULT false NOT NULL,
+ whats_new_variant smallint DEFAULT 0,
CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)),
CONSTRAINT app_settings_ext_pipeline_validation_service_url_text_limit CHECK ((char_length(external_pipeline_validation_service_url) <= 255)),
CONSTRAINT app_settings_registry_exp_policies_worker_capacity_positive CHECK ((container_registry_expiration_policies_worker_capacity >= 0)),
diff --git a/doc/administration/auth/smartcard.md b/doc/administration/auth/smartcard.md
index 4fe69d0160e..07c29984552 100644
--- a/doc/administration/auth/smartcard.md
+++ b/doc/administration/auth/smartcard.md
@@ -108,6 +108,11 @@ attribute. As a prerequisite, you must use an LDAP server that:
- Supports the `certificateExactMatch` matching rule.
- Has the certificate stored in the `userCertificate` attribute.
+NOTE:
+Active Directory doesn't support the `certificateExactMatch` matching rule so
+[it is not supported at this time](https://gitlab.com/gitlab-org/gitlab/-/issues/327491). For
+more information, see [the relevant issue](https://gitlab.com/gitlab-org/gitlab/-/issues/328074).
+
## Configure GitLab for smartcard authentication
**For Omnibus installations**
diff --git a/doc/administration/geo/replication/object_storage.md b/doc/administration/geo/replication/object_storage.md
index ad419f999b3..7dd831092a3 100644
--- a/doc/administration/geo/replication/object_storage.md
+++ b/doc/administration/geo/replication/object_storage.md
@@ -9,9 +9,9 @@ type: howto
Geo can be used in combination with Object Storage (AWS S3, or other compatible object storage).
-Currently, **secondary** nodes can use either:
+Currently, **secondary** sites can use either:
-- The same storage bucket as the **primary** node.
+- The same storage bucket as the **primary** site.
- A replicated storage bucket.
To have:
@@ -28,13 +28,13 @@ To have:
WARNING:
This is a [**beta** feature](https://about.gitlab.com/handbook/product/#beta) and is not ready yet for production use at any scale. The main limitations are a lack of testing at scale and no verification of any replicated data.
-**Secondary** nodes can replicate files stored on the **primary** node regardless of
+**Secondary** sites can replicate files stored on the **primary** site regardless of
whether they are stored on the local file system or in object storage.
To enable GitLab replication, you must:
1. Go to **Admin Area > Geo**.
-1. Press **Edit** on the **secondary** node.
+1. Press **Edit** on the **secondary** site.
1. In the **Synchronization Settings** section, find the **Allow this secondary node to replicate content on Object Storage**
checkbox to enable it.
@@ -46,7 +46,7 @@ For CI job artifacts, there is similar documentation to configure
For user uploads, there is similar documentation to configure [upload object storage](../../uploads.md#using-object-storage)
-If you want to migrate the **primary** node's files to object storage, you can
+If you want to migrate the **primary** site's files to object storage, you can
configure the **secondary** in a few ways:
- Use the exact same object storage.
@@ -57,15 +57,15 @@ configure the **secondary** in a few ways:
GitLab does not currently support the case where both:
-- The **primary** node uses local storage.
-- A **secondary** node uses object storage.
+- The **primary** site uses local storage.
+- A **secondary** site uses object storage.
## Third-party replication services
When using Amazon S3, you can use
[CRR](https://docs.aws.amazon.com/AmazonS3/latest/dev/crr.html) to
-have automatic replication between the bucket used by the **primary** node and
-the bucket used by **secondary** nodes.
+have automatic replication between the bucket used by the **primary** site and
+the bucket used by **secondary** sites.
If you are using Google Cloud Storage, consider using
[Multi-Regional Storage](https://cloud.google.com/storage/docs/storage-classes#multi-regional).
diff --git a/doc/administration/geo/replication/security_review.md b/doc/administration/geo/replication/security_review.md
index abb84b95623..f84d7a2171d 100644
--- a/doc/administration/geo/replication/security_review.md
+++ b/doc/administration/geo/replication/security_review.md
@@ -36,7 +36,7 @@ from [owasp.org](https://owasp.org/).
- The GitLab model of sensitivity is centered around public vs. internal vs.
private projects. Geo replicates them all indiscriminately. "Selective sync"
exists for files and repositories (but not database content), which would permit
- only less-sensitive projects to be replicated to a **secondary** node if desired.
+ only less-sensitive projects to be replicated to a **secondary** site if desired.
- See also: [GitLab data classification policy](https://about.gitlab.com/handbook/engineering/security/data-classification-standard.html).
### What data backup and retention requirements have been defined for the application?
@@ -48,18 +48,18 @@ from [owasp.org](https://owasp.org/).
### Who are the application's end‐users?
-- **Secondary** nodes are created in regions that are distant (in terms of
- Internet latency) from the main GitLab installation (the **primary** node). They are
- intended to be used by anyone who would ordinarily use the **primary** node, who finds
- that the **secondary** node is closer to them (in terms of Internet latency).
+- **Secondary** sites are created in regions that are distant (in terms of
+ Internet latency) from the main GitLab installation (the **primary** site). They are
+ intended to be used by anyone who would ordinarily use the **primary** site, who finds
+ that the **secondary** site is closer to them (in terms of Internet latency).
### How do the end‐users interact with the application?
-- **Secondary** nodes provide all the interfaces a **primary** node does
+- **Secondary** sites provide all the interfaces a **primary** site does
(notably a HTTP/HTTPS web application, and HTTP/HTTPS or SSH Git repository
access), but is constrained to read-only activities. The principal use case is
- envisioned to be cloning Git repositories from the **secondary** node in favor of the
- **primary** node, but end-users may use the GitLab web interface to view projects,
+ envisioned to be cloning Git repositories from the **secondary** site in favor of the
+ **primary** site, but end-users may use the GitLab web interface to view projects,
issues, merge requests, snippets, etc.
### What security expectations do the end‐users have?
@@ -67,10 +67,10 @@ from [owasp.org](https://owasp.org/).
- The replication process must be secure. It would typically be unacceptable to
transmit the entire database contents or all files and repositories across the
public Internet in plaintext, for instance.
-- **Secondary** nodes must have the same access controls over its content as the
- **primary** node - unauthenticated users must not be able to gain access to privileged
- information on the **primary** node by querying the **secondary** node.
-- Attackers must not be able to impersonate the **secondary** node to the **primary** node, and
+- **Secondary** sites must have the same access controls over its content as the
+ **primary** site - unauthenticated users must not be able to gain access to privileged
+ information on the **primary** site by querying the **secondary** site.
+- Attackers must not be able to impersonate the **secondary** site to the **primary** site, and
thus gain access to privileged information.
## Administrators
@@ -86,7 +86,7 @@ from [owasp.org](https://owasp.org/).
### What administrative capabilities does the application offer?
-- **Secondary** nodes may be added, modified, or removed by users with
+- **Secondary** sites may be added, modified, or removed by users with
administrative access.
- The replication process may be controlled (start/stop) via the Sidekiq
administrative controls.
@@ -95,9 +95,9 @@ from [owasp.org](https://owasp.org/).
### What details regarding routing, switching, firewalling, and load‐balancing have been defined?
-- Geo requires the **primary** node and **secondary** node to be able to communicate with each
- other across a TCP/IP network. In particular, the **secondary** nodes must be able to
- access HTTP/HTTPS and PostgreSQL services on the **primary** node.
+- Geo requires the **primary** site and **secondary** site to be able to communicate with each
+ other across a TCP/IP network. In particular, the **secondary** sites must be able to
+ access HTTP/HTTPS and PostgreSQL services on the **primary** site.
### What core network devices support the application?
@@ -105,9 +105,9 @@ from [owasp.org](https://owasp.org/).
### What network performance requirements exist?
-- Maximum replication speeds between **primary** node and **secondary** node is limited by the
+- Maximum replication speeds between **primary** site and **secondary** site is limited by the
available bandwidth between sites. No hard requirements exist - time to complete
- replication (and ability to keep up with changes on the **primary** node) is a function
+ replication (and ability to keep up with changes on the **primary** site) is a function
of the size of the data set, tolerance for latency, and available network
capacity.
@@ -189,9 +189,9 @@ from [owasp.org](https://owasp.org/).
### How will database connection strings, encryption keys, and other sensitive components be stored, accessed, and protected from unauthorized detection?
- There are some Geo-specific values. Some are shared secrets which must be
- securely transmitted from the **primary** node to the **secondary** node at setup time. Our
- documentation recommends transmitting them from the **primary** node to the system
- administrator via SSH, and then back out to the **secondary** node in the same manner.
+ securely transmitted from the **primary** site to the **secondary** site at setup time. Our
+ documentation recommends transmitting them from the **primary** site to the system
+ administrator via SSH, and then back out to the **secondary** site in the same manner.
In particular, this includes the PostgreSQL replication credentials and a secret
key (`db_key_base`) which is used to decrypt certain columns in the database.
The `db_key_base` secret is stored unencrypted on the file system, in
@@ -205,25 +205,25 @@ from [owasp.org](https://owasp.org/).
- Data is entered via the web application exposed by GitLab itself. Some data is
also entered using system administration commands on the GitLab servers (e.g.,
`gitlab-ctl set-primary-node`).
-- **Secondary** nodes also receive inputs via PostgreSQL streaming replication from the **primary** node.
+- **Secondary** sites also receive inputs via PostgreSQL streaming replication from the **primary** site.
### What data output paths does the application support?
-- **Primary** nodes output via PostgreSQL streaming replication to the **secondary** node.
+- **Primary** sites output via PostgreSQL streaming replication to the **secondary** site.
Otherwise, principally via the web application exposed by GitLab itself, and via
SSH `git clone` operations initiated by the end-user.
### How does data flow across the application's internal components?
-- **Secondary** nodes and **primary** nodes interact via HTTP/HTTPS (secured with JSON web
+- **Secondary** sites and **primary** sites interact via HTTP/HTTPS (secured with JSON web
tokens) and via PostgreSQL streaming replication.
-- Within a **primary** node or **secondary** node, the SSOT is the file system and the database
- (including Geo tracking database on **secondary** node). The various internal components
+- Within a **primary** site or **secondary** site, the SSOT is the file system and the database
+ (including Geo tracking database on **secondary** site). The various internal components
are orchestrated to make alterations to these stores.
### What data input validation requirements have been defined?
-- **Secondary** nodes must have a faithful replication of the **primary** node's data.
+- **Secondary** sites must have a faithful replication of the **primary** site's data.
### What data does the application store and how?
@@ -231,11 +231,11 @@ from [owasp.org](https://owasp.org/).
### What data is or may need to be encrypted and what key management requirements have been defined?
-- Neither **primary** nodes or **secondary** nodes encrypt Git repository or file system data at
+- Neither **primary** sites or **secondary** sites encrypt Git repository or file system data at
rest. A subset of database columns are encrypted at rest using the `db_otp_key`.
- A static secret shared across all hosts in a GitLab deployment.
- In transit, data should be encrypted, although the application does permit
- communication to proceed unencrypted. The two main transits are the **secondary** node's
+ communication to proceed unencrypted. The two main transits are the **secondary** site's
replication process for PostgreSQL, and for Git repositories/files. Both should
be protected using TLS, with the keys for that managed via Omnibus per existing
configuration for end-user access to GitLab.
@@ -253,19 +253,19 @@ from [owasp.org](https://owasp.org/).
### What user privilege levels does the application support?
-- Geo adds one type of privilege: **secondary** nodes can access a special Geo API to
+- Geo adds one type of privilege: **secondary** sites can access a special Geo API to
download files over HTTP/HTTPS, and to clone repositories using HTTP/HTTPS.
### What user identification and authentication requirements have been defined?
-- **Secondary** nodes identify to Geo **primary** nodes via OAuth or JWT authentication
+- **Secondary** sites identify to Geo **primary** sites via OAuth or JWT authentication
based on the shared database (HTTP access) or a PostgreSQL replication user (for
database replication). The database replication also requires IP-based access
controls to be defined.
### What user authorization requirements have been defined?
-- **Secondary** nodes must only be able to *read* data. They are not currently able to mutate data on the **primary** node.
+- **Secondary** sites must only be able to *read* data. They are not currently able to mutate data on the **primary** site.
### What session management requirements have been defined?
@@ -279,9 +279,9 @@ from [owasp.org](https://owasp.org/).
### What access requirements have been defined for URI and Service calls?
-- **Secondary** nodes make many calls to the **primary** node's API. This is how file
+- **Secondary** sites make many calls to the **primary** site's API. This is how file
replication proceeds, for instance. This endpoint is only accessible with a JWT token.
-- The **primary** node also makes calls to the **secondary** node to get status information.
+- The **primary** site also makes calls to the **secondary** site to get status information.
## Application Monitoring
diff --git a/doc/administration/housekeeping.md b/doc/administration/housekeeping.md
index 0e24ab40157..82891e68a0f 100644
--- a/doc/administration/housekeeping.md
+++ b/doc/administration/housekeeping.md
@@ -4,9 +4,10 @@ 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/#assignments
---
-# Housekeeping
+# Housekeeping **(FREE)**
-> [Introduced](https://gitlab.com/gitlab-org/gitlab-foss/-/issues/3041) in GitLab 8.4.
+GitLab supports and automates housekeeping tasks within your current repository,
+such as compressing file revisions and removing unreachable objects.
## Automatic housekeeping
@@ -37,9 +38,11 @@ the `pushes_since_gc` value is 200 a `git gc` runs.
Housekeeping also [removes unreferenced LFS files](../raketasks/cleanup.md#remove-unreferenced-lfs-files)
from your project on the same schedule as the `git gc` operation, freeing up storage space for your project.
-You can find this option under your project's **Settings > General > Advanced**.
+To manually start the housekeeping process:
-![Housekeeping settings](img/housekeeping_settings.png)
+1. In your project, go to **Settings > General**.
+1. Expand the **Advanced** section.
+1. Select **Run housekeeping**.
## How housekeeping handles pool repositories
diff --git a/doc/administration/reference_architectures/troubleshooting.md b/doc/administration/reference_architectures/troubleshooting.md
index e5d65264a5c..d5f57965a80 100644
--- a/doc/administration/reference_architectures/troubleshooting.md
+++ b/doc/administration/reference_architectures/troubleshooting.md
@@ -4,7 +4,7 @@ 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/#assignments
---
-# Troubleshooting a reference architecture setup
+# Troubleshooting a reference architecture setup **(FREE SELF)**
This page serves as the troubleshooting documentation if you followed one of
the [reference architectures](index.md#reference-architectures).
diff --git a/doc/administration/whats-new.md b/doc/administration/whats-new.md
index 4cbb0b854ae..a5e3a232890 100644
--- a/doc/administration/whats-new.md
+++ b/doc/administration/whats-new.md
@@ -19,11 +19,23 @@ feature list, the feature list is tailored to your subscription type:
- Features only available to self-managed installations are not shown on GitLab.com.
- Features only available on GitLab.com are not shown to self-managed installations.
-The **What's new** feature cannot be disabled, but
-[is planned](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59011) for a future release.
-
## Self-managed installations
Due to our release post process, the content for **What's new** is not yet finalized
when a new version (`.0` release) is cut. The updated **What's new** is included
in the first patch release, such as `13.10.1`.
+
+## Configure What's new variant
+
+You can configure the What's new variant:
+
+1. Navigate to **Admin Area > Settings > Preferences**, then expand **What's new**.
+1. Choose one of the following options:
+
+ | Option | Description |
+ | ------ | ----------- |
+ | Enable What's new: All tiers | What's new presents new features from all tiers to help you keep track of all new features. |
+ | Enable What's new: Current tier only | What's new presents new features for your current subscription tier, while hiding new features not available to your subscription tier. |
+ | Disable What's new | What's new is disabled and can no longer be viewed. |
+
+1. Save your changes.
diff --git a/doc/api/settings.md b/doc/api/settings.md
index 146cd1628ff..1ba6ba2e42a 100644
--- a/doc/api/settings.md
+++ b/doc/api/settings.md
@@ -410,6 +410,7 @@ listed in the descriptions of the relevant settings.
| `user_oauth_applications` | boolean | no | Allow users to register any application to use GitLab as an OAuth provider. |
| `user_show_add_ssh_key_message` | boolean | no | When set to `false` disable the "You won't be able to pull or push project code via SSH" warning shown to users with no uploaded SSH key. |
| `version_check_enabled` | boolean | no | Let GitLab inform you when an update is available. |
+| `whats_new_variant` | string | no | What's new variant, possible values: `all_tiers`, `current_tier`, and `disabled`. |
| `web_ide_clientside_preview_enabled` | boolean | no | Live Preview (allow live previews of JavaScript projects in the Web IDE using CodeSandbox Live Preview). |
| `wiki_page_max_content_bytes` | integer | no | Maximum wiki page content size in **bytes**. Default: 52428800 Bytes (50 MB). The minimum value is 1024 bytes. |
diff --git a/doc/development/usage_ping/dictionary.md b/doc/development/usage_ping/dictionary.md
index d69de6a6e9e..d640b6f8023 100644
--- a/doc/development/usage_ping/dictionary.md
+++ b/doc/development/usage_ping/dictionary.md
@@ -7592,6 +7592,30 @@ Status: `data_available`
Tiers:
+### `redis_hll_counters.analytics.users_viewing_analytics_group_devops_adoption_monthly`
+
+Counts visits to DevOps Adoption page per month
+
+[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_28d/20210419105414_users_viewing_analytics_group_devops_adoption_monthly.yml)
+
+Group: `group::optimize`
+
+Status: `implemented`
+
+Tiers: `premium`, `ultimate`
+
+### `redis_hll_counters.analytics.users_viewing_analytics_group_devops_adoption_weekly`
+
+Counts visits to DevOps Adoption page per week
+
+[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/ee/config/metrics/counts_7d/20210419105408_users_viewing_analytics_group_devops_adoption_weekly.yml)
+
+Group: `group::optimize`
+
+Status: `implemented`
+
+Tiers: `premium`, `ultimate`
+
### `redis_hll_counters.ci_secrets_management.i_ci_secrets_management_vault_build_created_monthly`
Missing description
diff --git a/doc/install/installation.md b/doc/install/installation.md
index eb8c3784cfa..37ab4ccbcd2 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -276,10 +276,7 @@ we need to install through the following commands:
curl --location "https://deb.nodesource.com/setup_14.x" | sudo bash -
sudo apt-get install -y nodejs
-curl --silent --show-error "https://dl.yarnpkg.com/debian/pubkey.gpg" | sudo apt-key add -
-echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
-sudo apt-get update
-sudo apt-get install yarn
+npm install --global yarn
```
Visit the official websites for [node](https://nodejs.org/en/download/package-manager/) and [yarn](https://classic.yarnpkg.com/en/docs/install/) if you have any trouble with these steps.
diff --git a/doc/update/upgrading_from_source.md b/doc/update/upgrading_from_source.md
index 33ae9befd16..93d2c2cb288 100644
--- a/doc/update/upgrading_from_source.md
+++ b/doc/update/upgrading_from_source.md
@@ -90,10 +90,9 @@ dependencies.
In Debian or Ubuntu:
```shell
-curl --silent --show-error "https://dl.yarnpkg.com/debian/pubkey.gpg" | sudo apt-key add -
-echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
-sudo apt-get update
-sudo apt-get install yarn
+sudo apt-get remove yarn
+
+npm install --global yarn
```
More information can be found on the [Yarn website](https://classic.yarnpkg.com/en/docs/install).
diff --git a/doc/user/admin_area/settings/index.md b/doc/user/admin_area/settings/index.md
index 023c4548d73..a1f4c6a06e2 100644
--- a/doc/user/admin_area/settings/index.md
+++ b/doc/user/admin_area/settings/index.md
@@ -108,6 +108,7 @@ Access the default page for admin area settings by navigating to **Admin Area >
| Option | Description |
| ------ | ----------- |
| [Email](email.md) | Various email settings. |
+| [What's new](../../../administration/whats-new.md) | Configure What's new drawer and content. |
| [Help page](help_page.md) | Help page text and support page URL. |
| [Pages](../../../administration/pages/index.md#custom-domain-verification) | Size and domain settings for static websites |
| [Real-time features](../../../administration/polling.md) | Change this value to influence how frequently the GitLab UI polls for updates. |
diff --git a/doc/user/analytics/index.md b/doc/user/analytics/index.md
index 6e3c9cf7a5f..e6f7b6750b3 100644
--- a/doc/user/analytics/index.md
+++ b/doc/user/analytics/index.md
@@ -10,7 +10,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w
When we describe GitLab analytics, we use the following terms:
-- Cycle time: The duration of your value stream, from start to finish. Often displayed in combination with "lead time." GitLab measures cycle time from issue creation to issue close. GitLab displays cycle time in [Value Stream Analytics](value_stream_analytics.md).
+- Cycle time: The duration of your value stream, from start to finish. Often displayed in combination with "lead time." GitLab measures cycle time from issue creation to issue close. GitLab displays cycle time in [group-level Value Stream Analytics](../group/value_stream_analytics/index.md).
- DORA (DevOps Research and Assessment) ["Four Keys"](https://cloud.google.com/blog/products/devops-sre/using-the-four-keys-to-measure-your-devops-performance):
- Speed
- Deployment Frequency: How often an organization successfully releases to production.
@@ -19,11 +19,11 @@ as described in ([Measuring DevOps Performance](https://devops.com/measuring-dev
- Stability
- Change Failure Rate: The percentage of deployments causing a failure in production.
- Time to Restore Service: How long it takes an organization to recover from a failure in production.
+- Lead time: The duration of the work itself. Often displayed in combination with "cycle time." GitLab measures from issue first merge request creation to issue close. Note: Work started before the creation of the first merge request. We [plan to start measuring from "issue first commit"](https://gitlab.com/gitlab-org/gitlab/-/issues/328459) as a better proxy, although still imperfect. GitLab displays lead time in [group-level Value Stream Analytics](../group/value_stream_analytics/index.md).
- MTTC (Mean Time to Change): The average duration between idea and delivery. GitLab measures MTTC from issue creation to the issue's latest related merge request's deployment to production.
- MTTD (Mean Time to Detect): The average duration that a bug goes undetected in production. GitLab measures MTTD from deployment of bug to issue creation.
- MTTM (Mean Time To Merge): The average lifespan of a merge request. GitLab measures MTTM from merge request creation to merge request merge (and closed/un-merged merge requests are excluded). For more information, see [Merge Request Analytics](merge_request_analytics.md).
- MTTR (Mean Time to Recover/Repair/Resolution/Resolve/Restore): The average duration that a bug is not fixed in production. GitLab measures MTTR from deployment of bug to deployment of fix.
-- Lead time: The duration of the work itself. Often displayed in combination with "cycle time." GitLab measures from issue first merge request creation to issue close. Note: Work started before the creation of the first merge request. We plan to start measuring from "issue first commit" as a better proxy, although still imperfect. GitLab displays lead time in [Value Stream Analytics](value_stream_analytics.md).
- Throughput: The number of issues closed or merge requests merged (not closed) in some period of time. Often measured per sprint. GitLab displays merge request throughput in [Merge Request Analytics](merge_request_analytics.md).
- Value Stream: The entire work process that is followed to deliver value to customers. For example, the [DevOps lifecycle](https://about.gitlab.com/stages-devops-lifecycle/) is a value stream that starts with "plan" and ends with "monitor". GitLab helps you track your value stream using [Value Stream Analytics](value_stream_analytics.md).
- Velocity: The total issue burden completed in some period of time. The burden is usually measured in points or weight, often per sprint. For example, your velocity may be "30 points per sprint". GitLab measures velocity as the total points/weight of issues closed in a given period of time.
@@ -45,6 +45,7 @@ in one place.
The following analytics features are available at the group level:
+- [Application Security](../application_security/security_dashboard/#group-security-dashboard). **(ULTIMATE)**
- [Contribution](../group/contribution_analytics/index.md). **(PREMIUM)**
- [DevOps Adoption](../group/devops_adoption/index.md). **(ULTIMATE)**
- [Insights](../group/insights/index.md). **(ULTIMATE)**
@@ -52,12 +53,12 @@ The following analytics features are available at the group level:
- [Productivity](productivity_analytics.md). **(PREMIUM)**
- [Repositories](../group/repositories_analytics/index.md). **(PREMIUM)**
- [Value Stream](../group/value_stream_analytics/index.md). **(PREMIUM)**
-- [Application Security](../application_security/security_dashboard/#group-security-dashboard). **(ULTIMATE)**
## Project-level analytics
The following analytics features are available at the project level:
+- [Application Security](../application_security/security_dashboard/#project-security-dashboard). **(ULTIMATE)**
- [CI/CD](ci_cd_analytics.md). **(FREE)**
- [Code Review](code_review_analytics.md). **(PREMIUM)**
- [Insights](../project/insights/index.md). **(ULTIMATE)**
@@ -66,7 +67,6 @@ The following analytics features are available at the project level:
[feature flag](../../development/feature_flags/index.md#enabling-a-feature-flag-locally-in-development). **(PREMIUM)**
- [Repository](repository_analytics.md). **(FREE)**
- [Value Stream](value_stream_analytics.md). **(FREE)**
-- [Application Security](../application_security/security_dashboard/#project-security-dashboard). **(ULTIMATE)**
## User-configurable analytics
diff --git a/lib/api/settings.rb b/lib/api/settings.rb
index 95d0c525ced..b40ff469af2 100644
--- a/lib/api/settings.rb
+++ b/lib/api/settings.rb
@@ -169,6 +169,7 @@ module API
optional :raw_blob_request_limit, type: Integer, desc: "Maximum number of requests per minute for each raw path. Set to 0 for unlimited requests per minute."
optional :wiki_page_max_content_bytes, type: Integer, desc: "Maximum wiki page content size in bytes"
optional :require_admin_approval_after_user_signup, type: Boolean, desc: 'Require explicit admin approval for new signups'
+ optional :whats_new_variant, type: String, values: ApplicationSetting.whats_new_variants.keys, desc: "What's new variant, possible values: `all_tiers`, `current_tier`, and `disabled`."
ApplicationSetting::SUPPORTED_KEY_TYPES.each do |type|
optional :"#{type}_key_restriction",
diff --git a/lib/gitlab/usage_data_counters/known_events/analytics.yml b/lib/gitlab/usage_data_counters/known_events/analytics.yml
new file mode 100644
index 00000000000..db0bed79ac4
--- /dev/null
+++ b/lib/gitlab/usage_data_counters/known_events/analytics.yml
@@ -0,0 +1,90 @@
+- name: users_viewing_analytics_group_devops_adoption
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
+- name: i_analytics_dev_ops_adoption
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
+- name: g_analytics_merge_request
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
+- name: i_analytics_dev_ops_score
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
+- name: p_analytics_merge_request
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
+- name: i_analytics_instance_statistics
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
+- name: g_analytics_contribution
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
+- name: g_analytics_insights
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
+- name: g_analytics_issues
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
+- name: g_analytics_productivity
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
+- name: g_analytics_valuestream
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
+- name: p_analytics_pipelines
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
+- name: p_analytics_code_reviews
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
+- name: p_analytics_valuestream
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
+- name: p_analytics_insights
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
+- name: p_analytics_issues
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
+- name: p_analytics_repo
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
+- name: i_analytics_cohorts
+ category: analytics
+ redis_slot: analytics
+ aggregation: weekly
+ feature_flag: track_unique_visits
diff --git a/lib/gitlab/usage_data_counters/known_events/common.yml b/lib/gitlab/usage_data_counters/known_events/common.yml
index 81890aa0d8a..a89c61d93e8 100644
--- a/lib/gitlab/usage_data_counters/known_events/common.yml
+++ b/lib/gitlab/usage_data_counters/known_events/common.yml
@@ -25,92 +25,6 @@
redis_slot: compliance
aggregation: weekly
feature_flag: usage_data_a_compliance_audit_events_api
-# Analytics category
-- name: g_analytics_contribution
- category: analytics
- redis_slot: analytics
- aggregation: weekly
- feature_flag: track_unique_visits
-- name: g_analytics_insights
- category: analytics
- redis_slot: analytics
- aggregation: weekly
- feature_flag: track_unique_visits
-- name: g_analytics_issues
- category: analytics
- redis_slot: analytics
- aggregation: weekly
- feature_flag: track_unique_visits
-- name: g_analytics_productivity
- category: analytics
- redis_slot: analytics
- aggregation: weekly
- feature_flag: track_unique_visits
-- name: g_analytics_valuestream
- category: analytics
- redis_slot: analytics
- aggregation: weekly
- feature_flag: track_unique_visits
-- name: p_analytics_pipelines
- category: analytics
- redis_slot: analytics
- aggregation: weekly
- feature_flag: track_unique_visits
-- name: p_analytics_code_reviews
- category: analytics
- redis_slot: analytics
- aggregation: weekly
- feature_flag: track_unique_visits
-- name: p_analytics_valuestream
- category: analytics
- redis_slot: analytics
- aggregation: weekly
- feature_flag: track_unique_visits
-- name: p_analytics_insights
- category: analytics
- redis_slot: analytics
- aggregation: weekly
- feature_flag: track_unique_visits
-- name: p_analytics_issues
- category: analytics
- redis_slot: analytics
- aggregation: weekly
- feature_flag: track_unique_visits
-- name: p_analytics_repo
- category: analytics
- redis_slot: analytics
- aggregation: weekly
- feature_flag: track_unique_visits
-- name: i_analytics_cohorts
- category: analytics
- redis_slot: analytics
- aggregation: weekly
- feature_flag: track_unique_visits
-- name: i_analytics_dev_ops_score
- category: analytics
- redis_slot: analytics
- aggregation: weekly
- feature_flag: track_unique_visits
-- name: i_analytics_dev_ops_adoption
- category: analytics
- redis_slot: analytics
- aggregation: weekly
- feature_flag: track_unique_visits
-- name: g_analytics_merge_request
- category: analytics
- redis_slot: analytics
- aggregation: weekly
- feature_flag: track_unique_visits
-- name: p_analytics_merge_request
- category: analytics
- redis_slot: analytics
- aggregation: weekly
- feature_flag: track_unique_visits
-- name: i_analytics_instance_statistics
- category: analytics
- redis_slot: analytics
- aggregation: weekly
- feature_flag: track_unique_visits
- name: g_edit_by_web_ide
category: ide_edit
redis_slot: edit
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 52fb6933e68..276737cdfef 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -1868,9 +1868,6 @@ msgstr ""
msgid "Add README"
msgstr ""
-msgid "Add Variable"
-msgstr ""
-
msgid "Add Zoom meeting"
msgstr ""
@@ -3736,9 +3733,6 @@ msgstr ""
msgid "An example showing how to use Jsonnet with GitLab dynamic child pipelines"
msgstr ""
-msgid "An extendable open source CI/CD server."
-msgstr ""
-
msgid "An instance-level serverless domain already exists."
msgstr ""
@@ -4917,13 +4911,13 @@ msgstr ""
msgid "BambooService|Bamboo service root URL."
msgstr ""
-msgid "BambooService|The user with API access to the Bamboo server."
+msgid "BambooService|Run CI/CD pipelines with Atlassian Bamboo."
msgstr ""
-msgid "BambooService|Use Atlassian Bamboo to run CI/CD pipelines. You must set up automatic revision labeling and a repository trigger in Bamboo. %{docs_link}"
+msgid "BambooService|Run CI/CD pipelines with Atlassian Bamboo. You must set up automatic revision labeling and a repository trigger in Bamboo. %{docs_link}"
msgstr ""
-msgid "BambooService|Use the Atlassian Bamboo CI/CD server with GitLab."
+msgid "BambooService|The user with API access to the Bamboo server."
msgstr ""
msgid "Based on"
@@ -8314,6 +8308,9 @@ msgstr ""
msgid "Configure Tracing"
msgstr ""
+msgid "Configure What's new drawer and content."
+msgstr ""
+
msgid "Configure a %{codeStart}.gitlab-webide.yml%{codeEnd} file in the %{codeStart}.gitlab%{codeEnd} directory to start using the Web Terminal. %{helpStart}Learn more.%{helpEnd}"
msgstr ""
@@ -11379,6 +11376,9 @@ msgstr ""
msgid "Disable Two-factor Authentication"
msgstr ""
+msgid "Disable What's new"
+msgstr ""
+
msgid "Disable for this project"
msgstr ""
@@ -12029,6 +12029,12 @@ msgstr ""
msgid "Enable Spam Check via external API endpoint"
msgstr ""
+msgid "Enable What's new: All tiers"
+msgstr ""
+
+msgid "Enable What's new: Current tier only"
+msgstr ""
+
msgid "Enable access to Grafana"
msgstr ""
@@ -16481,6 +16487,9 @@ msgstr ""
msgid "Import Projects from Gitea"
msgstr ""
+msgid "Import a project"
+msgstr ""
+
msgid "Import an exported GitLab project"
msgstr ""
@@ -27648,6 +27657,12 @@ msgstr ""
msgid "Run CI/CD pipelines for external repositories"
msgstr ""
+msgid "Run CI/CD pipelines with Jenkins when you push to a repository, or when a merge request is created, updated, or merged. %{docs_link}"
+msgstr ""
+
+msgid "Run CI/CD pipelines with Jenkins."
+msgstr ""
+
msgid "Run housekeeping"
msgstr ""
@@ -33719,9 +33734,6 @@ msgstr ""
msgid "Trigger"
msgstr ""
-msgid "Trigger Jenkins builds when you push to a repository, or when a merge request is created, updated, or merged. %{docs_link}"
-msgstr ""
-
msgid "Trigger a pipeline for a branch or tag by generating a trigger token and using it with an API call. The token impersonates a user's project access and permissions."
msgstr ""
@@ -35907,6 +35919,15 @@ msgstr ""
msgid "What's new"
msgstr ""
+msgid "What's new is disabled and can no longer be viewed."
+msgstr ""
+
+msgid "What's new presents new features for your current subscription tier, while hiding new features not available to your subscription tier."
+msgstr ""
+
+msgid "What's new presents new features from all tiers to help you keep track of all new features."
+msgstr ""
+
msgid "What’s your experience level?"
msgstr ""
diff --git a/spec/features/project_variables_spec.rb b/spec/features/project_variables_spec.rb
index 327d8133411..62565eaabe1 100644
--- a/spec/features/project_variables_spec.rb
+++ b/spec/features/project_variables_spec.rb
@@ -18,7 +18,7 @@ RSpec.describe 'Project variables', :js do
it_behaves_like 'variable list'
it 'adds a new variable with an environment scope' do
- click_button('Add Variable')
+ click_button('Add variable')
page.within('#add-ci-variable') do
find('[data-qa-selector="ci_variable_key_field"] input').set('akey')
diff --git a/spec/features/projects/navbar_spec.rb b/spec/features/projects/navbar_spec.rb
index 7dc3ee63669..9bb8f0b2f21 100644
--- a/spec/features/projects/navbar_spec.rb
+++ b/spec/features/projects/navbar_spec.rb
@@ -12,6 +12,7 @@ RSpec.describe 'Project navbar' do
let_it_be(:project) { create(:project, :repository) }
before do
+ stub_feature_flags(sidebar_refactor: false)
insert_package_nav(_('Operations'))
insert_infrastructure_registry_nav
stub_config(registry: { enabled: false })
@@ -69,4 +70,23 @@ RSpec.describe 'Project navbar' do
it_behaves_like 'verified navigation bar'
end
+
+ context 'when sidebar refactor feature flag is on' do
+ before do
+ stub_feature_flags(sidebar_refactor: true)
+ stub_config(registry: { enabled: true })
+
+ insert_container_nav
+
+ insert_after_sub_nav_item(
+ _('Operations'),
+ within: _('Settings'),
+ new_sub_nav_item_name: _('Packages & Registries')
+ )
+
+ visit project_path(project)
+ end
+
+ it_behaves_like 'verified navigation bar'
+ end
end
diff --git a/spec/features/projects/settings/registry_settings_spec.rb b/spec/features/projects/settings/registry_settings_spec.rb
index bc60cdd2f8e..6a2769d11fd 100644
--- a/spec/features/projects/settings/registry_settings_spec.rb
+++ b/spec/features/projects/settings/registry_settings_spec.rb
@@ -11,105 +11,125 @@ RSpec.describe 'Project > Settings > CI/CD > Container registry tag expiration p
let(:container_registry_enabled) { true }
let(:container_registry_enabled_on_project) { true }
- subject { visit project_settings_ci_cd_path(project) }
+ shared_examples 'an expiration policy form' do
+ before do
+ project.update!(container_registry_enabled: container_registry_enabled_on_project)
+ project.container_expiration_policy.update!(enabled: true)
- before do
- project.update!(container_registry_enabled: container_registry_enabled_on_project)
- project.container_expiration_policy.update!(enabled: true)
+ sign_in(user)
+ stub_container_registry_config(enabled: container_registry_enabled)
+ end
- sign_in(user)
- stub_container_registry_config(enabled: container_registry_enabled)
- end
+ context 'as owner' do
+ it 'shows available section' do
+ subject
- context 'as owner' do
- it 'shows available section' do
- subject
+ settings_block = find('#js-registry-policies')
+ expect(settings_block).to have_text 'Clean up image tags'
+ end
- settings_block = find('#js-registry-policies')
- expect(settings_block).to have_text 'Clean up image tags'
- end
+ it 'saves cleanup policy submit the form' do
+ subject
- it 'saves cleanup policy submit the form' do
- subject
+ within '#js-registry-policies' do
+ select('Every day', from: 'Run cleanup')
+ select('50 tags per image name', from: 'Keep the most recent:')
+ fill_in('Keep tags matching:', with: 'stable')
+ select('7 days', from: 'Remove tags older than:')
+ fill_in('Remove tags matching:', with: '.*-production')
+
+ submit_button = find('[data-testid="save-button"')
+ expect(submit_button).not_to be_disabled
+ submit_button.click
+ end
- within '#js-registry-policies' do
- select('Every day', from: 'Run cleanup')
- select('50 tags per image name', from: 'Keep the most recent:')
- fill_in('Keep tags matching:', with: 'stable')
- select('7 days', from: 'Remove tags older than:')
- fill_in('Remove tags matching:', with: '.*-production')
+ expect(find('.gl-toast')).to have_content('Cleanup policy successfully saved.')
+ end
- submit_button = find('[data-testid="save-button"')
- expect(submit_button).not_to be_disabled
- submit_button.click
+ it 'does not save cleanup policy submit form with invalid regex' do
+ subject
+
+ within '#js-registry-policies' do
+ fill_in('Remove tags matching:', with: '*-production')
+
+ submit_button = find('[data-testid="save-button"')
+ expect(submit_button).not_to be_disabled
+ submit_button.click
+ end
+
+ expect(find('.gl-toast')).to have_content('Something went wrong while updating the cleanup policy.')
end
- toast = find('.gl-toast')
- expect(toast).to have_content('Cleanup policy successfully saved.')
end
- it 'does not save cleanup policy submit form with invalid regex' do
- subject
+ context 'with a project without expiration policy' do
+ where(:application_setting, :feature_flag, :result) do
+ true | true | :available_section
+ true | false | :available_section
+ false | true | :available_section
+ false | false | :disabled_message
+ end
- within '#js-registry-policies' do
- fill_in('Remove tags matching:', with: '*-production')
+ with_them do
+ before do
+ project.container_expiration_policy.destroy!
+ stub_feature_flags(container_expiration_policies_historic_entry: false)
+ stub_application_setting(container_expiration_policies_enable_historic_entries: application_setting)
+ stub_feature_flags(container_expiration_policies_historic_entry: project) if feature_flag
+ end
- submit_button = find('[data-testid="save-button"')
- expect(submit_button).not_to be_disabled
- submit_button.click
+ it 'displays the expected result' do
+ subject
+
+ within '#js-registry-policies' do
+ case result
+ when :available_section
+ expect(find('[data-testid="enable-toggle"]')).to have_content('Disabled - Tags will not be automatically deleted.')
+ when :disabled_message
+ expect(find('.gl-alert-title')).to have_content('Cleanup policy for tags is disabled')
+ end
+ end
+ end
end
- toast = find('.gl-toast')
- expect(toast).to have_content('Something went wrong while updating the cleanup policy.')
end
- end
- context 'with a project without expiration policy' do
- where(:application_setting, :feature_flag, :result) do
- true | true | :available_section
- true | false | :available_section
- false | true | :available_section
- false | false | :disabled_message
- end
+ context 'when registry is disabled' do
+ let(:container_registry_enabled) { false }
+
+ it 'does not exists' do
+ subject
- with_them do
- before do
- project.container_expiration_policy.destroy!
- stub_feature_flags(container_expiration_policies_historic_entry: false)
- stub_application_setting(container_expiration_policies_enable_historic_entries: application_setting)
- stub_feature_flags(container_expiration_policies_historic_entry: project) if feature_flag
+ expect(page).not_to have_selector('#js-registry-policies')
end
+ end
- it 'displays the expected result' do
+ context 'when container registry is disabled on project' do
+ let(:container_registry_enabled_on_project) { false }
+
+ it 'does not exists' do
subject
- within '#js-registry-policies' do
- case result
- when :available_section
- expect(find('[data-testid="enable-toggle"]')).to have_content('Disabled - Tags will not be automatically deleted.')
- when :disabled_message
- expect(find('.gl-alert-title')).to have_content('Cleanup policy for tags is disabled')
- end
- end
+ expect(page).not_to have_selector('#js-registry-policies')
end
end
end
- context 'when registry is disabled' do
- let(:container_registry_enabled) { false }
+ context 'with sidebar feature flag off' do
+ subject { visit project_settings_ci_cd_path(project) }
- it 'does not exists' do
- subject
-
- expect(page).not_to have_selector('#js-registry-policies')
+ before do
+ stub_feature_flags(sidebar_refactor: false)
end
- end
- context 'when container registry is disabled on project' do
- let(:container_registry_enabled_on_project) { false }
+ it_behaves_like 'an expiration policy form'
+ end
- it 'does not exists' do
- subject
+ context 'with sidebar feature flag on' do
+ subject { visit project_settings_packages_and_registries_path(project) }
- expect(page).not_to have_selector('#js-registry-policies')
+ before do
+ stub_feature_flags(sidebar_refactor: true)
end
+
+ it_behaves_like 'an expiration policy form'
end
end
diff --git a/spec/features/projects/settings/user_manages_project_members_spec.rb b/spec/features/projects/settings/user_manages_project_members_spec.rb
index b237e7e8ce7..5980246944e 100644
--- a/spec/features/projects/settings/user_manages_project_members_spec.rb
+++ b/spec/features/projects/settings/user_manages_project_members_spec.rb
@@ -38,16 +38,12 @@ RSpec.describe 'Projects > Settings > User manages project members' do
end
it 'imports a team from another project', :js do
- stub_feature_flags(invite_members_group_modal: false)
-
project2.add_maintainer(user)
project2.add_reporter(user_mike)
visit(project_project_members_path(project))
- page.within('.invite-users-form') do
- click_link('Import')
- end
+ click_link('Import a project')
select2(project2.id, from: '#source_project_id')
click_button('Import project members')
@@ -55,6 +51,26 @@ RSpec.describe 'Projects > Settings > User manages project members' do
expect(find_member_row(user_mike)).to have_content('Reporter')
end
+ describe 'when the :invite_members_group_modal is disabled' do
+ it 'imports a team from another project', :js do
+ stub_feature_flags(invite_members_group_modal: false)
+
+ project2.add_maintainer(user)
+ project2.add_reporter(user_mike)
+
+ visit(project_project_members_path(project))
+
+ page.within('.invite-users-form') do
+ click_link('Import')
+ end
+
+ select2(project2.id, from: '#source_project_id')
+ click_button('Import project members')
+
+ expect(find_member_row(user_mike)).to have_content('Reporter')
+ end
+ end
+
it 'shows all members of project shared group', :js do
group.add_owner(user)
group.add_developer(user_dmitriy)
diff --git a/spec/features/users/signup_spec.rb b/spec/features/users/signup_spec.rb
index 5f70517224e..17a6abb99e0 100644
--- a/spec/features/users/signup_spec.rb
+++ b/spec/features/users/signup_spec.rb
@@ -57,6 +57,12 @@ RSpec.describe 'Signup' do
fill_in 'new_user_password', with: new_user.password
end
+ def confirm_email
+ new_user_token = User.find_by_email(new_user.email).confirmation_token
+
+ visit user_confirmation_path(confirmation_token: new_user_token)
+ end
+
describe 'username validation', :js do
before do
visit new_user_registration_path
@@ -191,7 +197,7 @@ RSpec.describe 'Signup' do
stub_feature_flags(soft_email_confirmation: false)
end
- it 'creates the user account and sends a confirmation email' do
+ it 'creates the user account and sends a confirmation email, and pre-fills email address after confirming' do
visit new_user_registration_path
fill_in_signup_form
@@ -199,6 +205,10 @@ RSpec.describe 'Signup' do
expect { click_button 'Register' }.to change { User.count }.by(1)
expect(current_path).to eq users_almost_there_path
expect(page).to have_content('Please check your email to confirm your account')
+
+ confirm_email
+
+ expect(find_field('Username or email').value).to eq(new_user.email)
end
end
diff --git a/spec/features/whats_new_spec.rb b/spec/features/whats_new_spec.rb
index 55b96361f03..2938ea1b1e8 100644
--- a/spec/features/whats_new_spec.rb
+++ b/spec/features/whats_new_spec.rb
@@ -34,6 +34,24 @@ RSpec.describe "renders a `whats new` dropdown item" do
sign_in(user)
end
+ it 'renders dropdown item when feature enabled' do
+ Gitlab::CurrentSettings.update!(whats_new_variant: ApplicationSetting.whats_new_variants[:all_tiers])
+
+ visit root_dashboard_path
+ find('.header-help-dropdown-toggle').click
+
+ expect(page).to have_button(text: "What's new")
+ end
+
+ it 'does not render dropdown item when feature disabled' do
+ Gitlab::CurrentSettings.update!(whats_new_variant: ApplicationSetting.whats_new_variants[:disabled])
+
+ visit root_dashboard_path
+ find('.header-help-dropdown-toggle').click
+
+ expect(page).not_to have_button(text: "What's new")
+ end
+
it 'shows notification dot and count and removes it once viewed' do
visit root_dashboard_path
diff --git a/spec/fixtures/whats_new/20201225_01_04.yml b/spec/fixtures/whats_new/20201225_01_04.yml
new file mode 100644
index 00000000000..0dfd0d780c7
--- /dev/null
+++ b/spec/fixtures/whats_new/20201225_01_04.yml
@@ -0,0 +1,19 @@
+---
+- title: View epics on a board
+ body: |
+ ## View epics on a board
+ self-managed: true
+ gitlab-com: false
+ packages: ["Free", "Premium", "Ultimate"]
+- title: View Jira issue details in GitLab
+ body: |
+ ## View Jira issue details in GitLab
+ self-managed: true
+ gitlab-com: false
+ packages: ["Premium", "Ultimate"]
+- title: Integrate any IT alerting tool with GitLab
+ body: |
+ ## Integrate any IT alerting tool with GitLab
+ self-managed: true
+ gitlab-com: false
+ packages: ["Ultimate"] \ No newline at end of file
diff --git a/spec/helpers/whats_new_helper_spec.rb b/spec/helpers/whats_new_helper_spec.rb
index 0e4b4621560..9ae7ef38736 100644
--- a/spec/helpers/whats_new_helper_spec.rb
+++ b/spec/helpers/whats_new_helper_spec.rb
@@ -59,5 +59,62 @@ RSpec.describe WhatsNewHelper do
expect(subject).to be false
end
end
+
+ context 'depending on whats_new_variant' do
+ using RSpec::Parameterized::TableSyntax
+
+ where(:variant, :result) do
+ :all_tiers | true
+ :current_tier | true
+ :disabled | false
+ end
+
+ with_them do
+ it 'returns correct result depending on variant' do
+ allow(Gitlab).to receive(:dev_env_org_or_com?).and_return(true)
+ Gitlab::CurrentSettings.update!(whats_new_variant: ApplicationSetting.whats_new_variants[variant])
+
+ expect(subject).to eq(result)
+ end
+ end
+ end
+ end
+
+ describe '#whats_new_variants' do
+ it 'returns ApplicationSetting.whats_new_variants' do
+ expect(helper.whats_new_variants).to eq(ApplicationSetting.whats_new_variants)
+ end
+ end
+
+ describe '#whats_new_variants_label' do
+ let(:labels) do
+ [
+ helper.whats_new_variants_label('all_tiers'),
+ helper.whats_new_variants_label('current_tier'),
+ helper.whats_new_variants_label('disabled'),
+ helper.whats_new_variants_label(nil)
+ ]
+ end
+
+ it 'returns different labels depending on variant' do
+ expect(labels.uniq.size).to eq(labels.size)
+ expect(labels[3]).to be_nil
+ end
+ end
+
+ describe '#whats_new_variants_description' do
+ let(:descriptions) do
+ [
+ helper.whats_new_variants_description('all_tiers'),
+ helper.whats_new_variants_description('current_tier'),
+ helper.whats_new_variants_description('disabled'),
+ helper.whats_new_variants_description(nil)
+ ]
+ end
+
+ it 'returns different descriptions depending on variant' do
+ expect(descriptions.uniq.size).to eq(descriptions.size)
+ expect(descriptions[3]).to be_nil
+ end
end
end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index dda033c94b7..42d502b9d23 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -1303,10 +1303,11 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
'p_analytics_repo' => 123,
'i_analytics_cohorts' => 123,
'i_analytics_dev_ops_score' => 123,
- 'i_analytics_dev_ops_adoption' => 123,
'i_analytics_instance_statistics' => 123,
'p_analytics_merge_request' => 123,
'g_analytics_merge_request' => 123,
+ 'i_analytics_dev_ops_adoption' => 123,
+ 'users_viewing_analytics_group_devops_adoption' => 123,
'analytics_unique_visits_for_any_target' => 543,
'analytics_unique_visits_for_any_target_monthly' => 987
}
diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb
index 4b0731e0720..c7d05b64235 100644
--- a/spec/models/application_setting_spec.rb
+++ b/spec/models/application_setting_spec.rb
@@ -129,6 +129,11 @@ RSpec.describe ApplicationSetting do
it { is_expected.not_to allow_value(nil).for(:notes_create_limit_allowlist) }
it { is_expected.to allow_value([]).for(:notes_create_limit_allowlist) }
+ it { is_expected.to allow_value('all_tiers').for(:whats_new_variant) }
+ it { is_expected.to allow_value('current_tier').for(:whats_new_variant) }
+ it { is_expected.to allow_value('disabled').for(:whats_new_variant) }
+ it { is_expected.not_to allow_value(nil).for(:whats_new_variant) }
+
context 'help_page_documentation_base_url validations' do
it { is_expected.to allow_value(nil).for(:help_page_documentation_base_url) }
it { is_expected.to allow_value('https://docs.gitlab.com').for(:help_page_documentation_base_url) }
diff --git a/spec/models/release_highlight_spec.rb b/spec/models/release_highlight_spec.rb
index 673451b5e76..b4dff4c33ff 100644
--- a/spec/models/release_highlight_spec.rb
+++ b/spec/models/release_highlight_spec.rb
@@ -7,6 +7,7 @@ RSpec.describe ReleaseHighlight, :clean_gitlab_redis_cache do
before do
allow(Dir).to receive(:glob).with(Rails.root.join('data', 'whats_new', '*.yml')).and_return(fixture_dir_glob)
+ Gitlab::CurrentSettings.update!(whats_new_variant: ApplicationSetting.whats_new_variants[:all_tiers])
end
after do
@@ -24,16 +25,16 @@ RSpec.describe ReleaseHighlight, :clean_gitlab_redis_cache do
subject { ReleaseHighlight.paginated(page: page) }
context 'when there is another page of results' do
- let(:page) { 2 }
+ let(:page) { 3 }
it 'responds with paginated results' do
expect(subject[:items].first['title']).to eq('bright')
- expect(subject[:next_page]).to eq(3)
+ expect(subject[:next_page]).to eq(4)
end
end
context 'when there is NOT another page of results' do
- let(:page) { 3 }
+ let(:page) { 4 }
it 'responds with paginated results and no next_page' do
expect(subject[:items].first['title']).to eq("It's gonna be a bright")
@@ -54,8 +55,8 @@ RSpec.describe ReleaseHighlight, :clean_gitlab_redis_cache do
subject { ReleaseHighlight.paginated }
it 'uses multiple levels of cache' do
- expect(Rails.cache).to receive(:fetch).with("release_highlight:items:page-1:#{Gitlab.revision}", { expires_in: described_class::CACHE_DURATION }).and_call_original
- expect(Rails.cache).to receive(:fetch).with("release_highlight:file_paths:#{Gitlab.revision}", { expires_in: described_class::CACHE_DURATION }).and_call_original
+ expect(Rails.cache).to receive(:fetch).with("release_highlight:all_tiers:items:page-1:#{Gitlab.revision}", { expires_in: described_class::CACHE_DURATION }).and_call_original
+ expect(Rails.cache).to receive(:fetch).with("release_highlight:all_tiers:file_paths:#{Gitlab.revision}", { expires_in: described_class::CACHE_DURATION }).and_call_original
subject
end
@@ -101,7 +102,7 @@ RSpec.describe ReleaseHighlight, :clean_gitlab_redis_cache do
subject { ReleaseHighlight.most_recent_item_count }
it 'uses process memory cache' do
- expect(Gitlab::ProcessMemoryCache.cache_backend).to receive(:fetch).with("release_highlight:recent_item_count:#{Gitlab.revision}", expires_in: described_class::CACHE_DURATION)
+ expect(Gitlab::ProcessMemoryCache.cache_backend).to receive(:fetch).with("release_highlight:all_tiers:recent_item_count:#{Gitlab.revision}", expires_in: described_class::CACHE_DURATION)
subject
end
@@ -127,7 +128,7 @@ RSpec.describe ReleaseHighlight, :clean_gitlab_redis_cache do
subject { ReleaseHighlight.most_recent_version_digest }
it 'uses process memory cache' do
- expect(Gitlab::ProcessMemoryCache.cache_backend).to receive(:fetch).with("release_highlight:most_recent_version_digest:#{Gitlab.revision}", expires_in: described_class::CACHE_DURATION)
+ expect(Gitlab::ProcessMemoryCache.cache_backend).to receive(:fetch).with("release_highlight:all_tiers:most_recent_version_digest:#{Gitlab.revision}", expires_in: described_class::CACHE_DURATION)
subject
end
@@ -148,6 +149,33 @@ RSpec.describe ReleaseHighlight, :clean_gitlab_redis_cache do
end
end
+ describe '.load_items' do
+ context 'whats new for all tiers' do
+ before do
+ Gitlab::CurrentSettings.update!(whats_new_variant: ApplicationSetting.whats_new_variants[:all_tiers])
+ end
+
+ it 'returns all items' do
+ items = described_class.load_items(page: 2)
+
+ expect(items.count).to eq(3)
+ end
+ end
+
+ context 'whats new for current tier only' do
+ before do
+ Gitlab::CurrentSettings.update!(whats_new_variant: ApplicationSetting.whats_new_variants[:current_tier])
+ end
+
+ it 'returns items with package=Free' do
+ items = described_class.load_items(page: 2)
+
+ expect(items.count).to eq(1)
+ expect(items.first['title']).to eq("View epics on a board")
+ end
+ end
+ end
+
describe 'QueryResult' do
subject { ReleaseHighlight::QueryResult.new(items: items, next_page: 2) }
@@ -157,4 +185,12 @@ RSpec.describe ReleaseHighlight, :clean_gitlab_redis_cache do
expect(subject.map(&:to_s)).to eq(items.map(&:to_s))
end
end
+
+ describe '.current_package' do
+ subject { described_class.current_package }
+
+ it 'returns Free' do
+ expect(subject).to eq('Free')
+ end
+ end
end
diff --git a/spec/requests/api/settings_spec.rb b/spec/requests/api/settings_spec.rb
index 48f5bd114a1..b61ccee512a 100644
--- a/spec/requests/api/settings_spec.rb
+++ b/spec/requests/api/settings_spec.rb
@@ -45,6 +45,7 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting do
expect(json_response['require_admin_approval_after_user_signup']).to eq(true)
expect(json_response['personal_access_token_prefix']).to be_nil
expect(json_response['admin_mode']).to be(false)
+ expect(json_response['whats_new_variant']).to eq('all_tiers')
end
end
@@ -485,5 +486,32 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting do
end
end
end
+
+ context 'whats_new_variant setting' do
+ before do
+ Gitlab::CurrentSettings.current_application_settings.whats_new_variant_disabled!
+ end
+
+ it 'updates setting' do
+ new_value = 'all_tiers'
+ put api("/application/settings", admin),
+ params: {
+ whats_new_variant: new_value
+ }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['whats_new_variant']).to eq(new_value)
+ end
+
+ it 'fails to update setting with invalid value' do
+ put api("/application/settings", admin),
+ params: {
+ whats_new_variant: 'invalid_value'
+ }
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(json_response['error']).to eq('whats_new_variant does not have a valid value')
+ end
+ end
end
end
diff --git a/spec/requests/whats_new_controller_spec.rb b/spec/requests/whats_new_controller_spec.rb
index ffb31bdf9bb..d4976a2bba3 100644
--- a/spec/requests/whats_new_controller_spec.rb
+++ b/spec/requests/whats_new_controller_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe WhatsNewController, :clean_gitlab_redis_cache do
ReleaseHighlight.instance_variable_set(:@file_paths, nil)
end
- describe 'whats_new_path' do
+ describe 'GET #index' do
let(:item) { double(:item) }
let(:highlights) { double(:highlight, items: [item], map: [item].map, next_page: 2) }
@@ -35,5 +35,17 @@ RSpec.describe WhatsNewController, :clean_gitlab_redis_cache do
expect(response).to have_gitlab_http_status(:not_found)
end
end
+
+ context 'with whats_new_variant = disabled' do
+ before do
+ Gitlab::CurrentSettings.current_application_settings.whats_new_variant_disabled!
+ end
+
+ it 'returns a 404' do
+ get whats_new_path, xhr: true
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
end
end
diff --git a/spec/support/shared_examples/features/variable_list_shared_examples.rb b/spec/support/shared_examples/features/variable_list_shared_examples.rb
index 2fd88b610e9..4b94411f009 100644
--- a/spec/support/shared_examples/features/variable_list_shared_examples.rb
+++ b/spec/support/shared_examples/features/variable_list_shared_examples.rb
@@ -8,7 +8,7 @@ RSpec.shared_examples 'variable list' do
end
it 'adds a new CI variable' do
- click_button('Add Variable')
+ click_button('Add variable')
fill_variable('key', 'key_value') do
click_button('Add variable')
@@ -22,7 +22,7 @@ RSpec.shared_examples 'variable list' do
end
it 'adds a new protected variable' do
- click_button('Add Variable')
+ click_button('Add variable')
fill_variable('key', 'key_value') do
click_button('Add variable')
@@ -37,7 +37,7 @@ RSpec.shared_examples 'variable list' do
end
it 'defaults to unmasked' do
- click_button('Add Variable')
+ click_button('Add variable')
fill_variable('key', 'key_value') do
click_button('Add variable')
@@ -149,7 +149,7 @@ RSpec.shared_examples 'variable list' do
end
it 'shows a validation error box about duplicate keys' do
- click_button('Add Variable')
+ click_button('Add variable')
fill_variable('key', 'key_value') do
click_button('Add variable')
@@ -157,7 +157,7 @@ RSpec.shared_examples 'variable list' do
wait_for_requests
- click_button('Add Variable')
+ click_button('Add variable')
fill_variable('key', 'key_value') do
click_button('Add variable')
@@ -170,7 +170,7 @@ RSpec.shared_examples 'variable list' do
end
it 'prevents a variable to be added if no values are provided when a variable is set to masked' do
- click_button('Add Variable')
+ click_button('Add variable')
page.within('#add-ci-variable') do
find('[data-qa-selector="ci_variable_key_field"] input').set('empty_mask_key')
@@ -182,7 +182,7 @@ RSpec.shared_examples 'variable list' do
end
it 'shows validation error box about unmaskable values' do
- click_button('Add Variable')
+ click_button('Add variable')
fill_variable('empty_mask_key', '???', protected: true, masked: true) do
expect(page).to have_content('This variable can not be masked')
@@ -192,7 +192,7 @@ RSpec.shared_examples 'variable list' do
it 'handles multiple edits and a deletion' do
# Create two variables
- click_button('Add Variable')
+ click_button('Add variable')
fill_variable('akey', 'akeyvalue') do
click_button('Add variable')
@@ -200,7 +200,7 @@ RSpec.shared_examples 'variable list' do
wait_for_requests
- click_button('Add Variable')
+ click_button('Add variable')
fill_variable('zkey', 'zkeyvalue') do
click_button('Add variable')
@@ -224,7 +224,7 @@ RSpec.shared_examples 'variable list' do
wait_for_requests
# Add another variable
- click_button('Add Variable')
+ click_button('Add variable')
fill_variable('ckey', 'ckeyvalue') do
click_button('Add variable')
@@ -249,7 +249,7 @@ RSpec.shared_examples 'variable list' do
end
it 'defaults to protected' do
- click_button('Add Variable')
+ click_button('Add variable')
page.within('#add-ci-variable') do
expect(find('[data-testid="ci-variable-protected-checkbox"]')).to be_checked
@@ -269,7 +269,7 @@ RSpec.shared_examples 'variable list' do
end
it 'defaults to unprotected' do
- click_button('Add Variable')
+ click_button('Add variable')
page.within('#add-ci-variable') do
expect(find('[data-testid="ci-variable-protected-checkbox"]')).not_to be_checked