Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2023-07-06 06:08:29 +00:00
parent b8fbfa9c70
commit d111e00680
72 changed files with 582 additions and 465 deletions

View File

@ -40,4 +40,3 @@ Graphql/ResourceNotAvailableError:
- 'ee/app/graphql/mutations/projects/set_locked.rb'
- 'ee/app/graphql/resolvers/incident_management/oncall_shifts_resolver.rb'
- 'ee/app/graphql/resolvers/product_analytics/visualization_resolver.rb'
- 'ee/app/graphql/resolvers/remote_development/workspaces_resolver.rb'

View File

@ -149,7 +149,6 @@ RSpec/BeforeAllRoleAssignment:
- 'ee/spec/features/projects/wiki/user_views_wiki_empty_spec.rb'
- 'ee/spec/features/projects_spec.rb'
- 'ee/spec/features/protected_branches_spec.rb'
- 'ee/spec/features/remote_development/workspaces_spec.rb'
- 'ee/spec/features/search/user_searches_for_epics_spec.rb'
- 'ee/spec/features/search/zoekt/search_spec.rb'
- 'ee/spec/features/subscriptions/expiring_subscription_message_spec.rb'
@ -360,7 +359,6 @@ RSpec/BeforeAllRoleAssignment:
- 'ee/spec/policies/merge_requests/external_status_check_policy_spec.rb'
- 'ee/spec/policies/packages/policies/project_policy_spec.rb'
- 'ee/spec/policies/project_policy_spec.rb'
- 'ee/spec/policies/remote_development/workspace_policy_spec.rb'
- 'ee/spec/policies/requirements_management/requirement_policy_spec.rb'
- 'ee/spec/policies/resource_iteration_event_policy_spec.rb'
- 'ee/spec/policies/resource_weight_event_policy_spec.rb'
@ -465,8 +463,6 @@ RSpec/BeforeAllRoleAssignment:
- 'ee/spec/requests/api/graphql/mutations/projects/set_compliance_framework_spec.rb'
- 'ee/spec/requests/api/graphql/mutations/releases/create_spec.rb'
- 'ee/spec/requests/api/graphql/mutations/releases/update_spec.rb'
- 'ee/spec/requests/api/graphql/mutations/remote_development/workspaces/create_spec.rb'
- 'ee/spec/requests/api/graphql/mutations/remote_development/workspaces/update_spec.rb'
- 'ee/spec/requests/api/graphql/mutations/requirements_management/create_requirement_spec.rb'
- 'ee/spec/requests/api/graphql/mutations/requirements_management/export_requirements_spec.rb'
- 'ee/spec/requests/api/graphql/mutations/requirements_management/update_requirement_spec.rb'

View File

@ -127,10 +127,15 @@ export default {
},
actionsFieldTdClass(value, key, member) {
if (this.hasActionButtons(member)) {
return 'col-actions';
return ['col-actions', 'gl-vertical-align-middle!'];
}
return ['col-actions', 'gl-display-none!', 'gl-lg-display-table-cell!'];
return [
'col-actions',
'gl-display-none!',
'gl-lg-display-table-cell!',
'gl-vertical-align-middle!',
];
},
tbodyTrAttr(member) {
return {

View File

@ -32,12 +32,13 @@ export const FIELDS = [
asc: 'name_asc',
desc: 'name_desc',
},
tdClass: 'gl-vertical-align-middle!',
},
{
key: FIELD_KEY_SOURCE,
label: __('Source'),
thClass: 'col-meta',
tdClass: 'col-meta',
tdClass: 'col-meta gl-vertical-align-middle!',
},
{
key: FIELD_KEY_GRANTED,
@ -46,24 +47,25 @@ export const FIELDS = [
asc: 'last_joined',
desc: 'oldest_joined',
},
tdClass: 'gl-vertical-align-middle!',
},
{
key: FIELD_KEY_INVITED,
label: __('Invited'),
thClass: 'col-meta',
tdClass: 'col-meta',
tdClass: 'col-meta gl-vertical-align-middle!',
},
{
key: FIELD_KEY_REQUESTED,
label: __('Requested'),
thClass: 'col-meta',
tdClass: 'col-meta',
tdClass: 'col-meta gl-vertical-align-middle!',
},
{
key: FIELD_KEY_MAX_ROLE,
label: __('Max role'),
thClass: 'col-max-role',
tdClass: 'col-max-role',
tdClass: 'col-max-role gl-vertical-align-middle!',
sort: {
asc: 'access_level_asc',
desc: 'access_level_desc',
@ -73,13 +75,13 @@ export const FIELDS = [
key: FIELD_KEY_EXPIRATION,
label: __('Expiration'),
thClass: 'col-expiration',
tdClass: 'col-expiration',
tdClass: 'col-expiration gl-vertical-align-middle!',
},
{
key: FIELD_KEY_ACTIVITY,
label: s__('Members|Activity'),
thClass: 'col-activity',
tdClass: 'col-activity',
tdClass: 'col-activity gl-vertical-align-middle!',
},
{
key: FIELD_KEY_USER_CREATED_AT,

View File

@ -105,7 +105,6 @@ export default {
icon="dash"
:aria-label="$options.i18n.removeItem"
:title="$options.i18n.removeItem"
class="gl-align-self-center gl-mr-2"
data-testid="item-remove"
@click.stop.prevent="handleItemRemove(item)"
/>

View File

@ -19,13 +19,7 @@ export default {
<template>
<ul class="gl-p-0 gl-list-style-none">
<nav-item
v-for="item in items"
:key="item.id"
:item="item"
:link-classes="{ 'gl-py-2!': true }"
is-subitem
>
<nav-item v-for="item in items" :key="item.id" :item="item" is-subitem>
<template #icon>
<project-avatar
:project-id="item.id"
@ -33,7 +27,6 @@ export default {
:project-avatar-url="item.avatar"
:size="24"
aria-hidden="true"
class="gl-mr-n2"
/>
</template>
<template #actions>

View File

@ -71,7 +71,7 @@ export default {
<component :is="tag">
<hr v-if="separated" aria-hidden="true" class="gl-mx-4 gl-my-2" />
<button
class="gl-rounded-base gl-relative gl-display-flex gl-align-items-center gl-line-height-normal gl-mb-2 gl-py-3 gl-px-0 gl-text-black-normal! gl-hover-bg-t-gray-a-08 gl-focus-bg-t-gray-a-08 gl-text-decoration-none! gl-appearance-none gl-border-0 gl-bg-transparent gl-text-left gl-w-full gl-focus--focus"
class="gl-rounded-base gl-relative gl-display-flex gl-align-items-center gl-min-h-7 gl-gap-3 gl-mb-2 gl-py-2 gl-px-3 gl-text-black-normal! gl-hover-bg-t-gray-a-08 gl-focus-bg-t-gray-a-08 gl-text-decoration-none! gl-appearance-none gl-border-0 gl-bg-transparent gl-text-left gl-w-full gl-focus--focus"
:class="computedLinkClasses"
data-qa-selector="menu_section_button"
:data-qa-section-name="item.title"
@ -84,17 +84,17 @@ export default {
aria-hidden="true"
style="width: 3px; border-radius: 3px; margin-right: 1px"
></span>
<span class="gl-flex-shrink-0 gl-w-6 gl-mx-3">
<span class="gl-flex-shrink-0 gl-w-6 gl-display-flex">
<slot name="icon">
<gl-icon v-if="item.icon" :name="item.icon" class="gl-ml-2 item-icon" />
<gl-icon v-if="item.icon" :name="item.icon" class="gl-m-auto item-icon" />
</slot>
</span>
<span class="gl-pr-3 gl-text-gray-900 gl-truncate-end">
<span class="gl-flex-grow-1 gl-text-gray-900 gl-truncate-end">
{{ item.title }}
</span>
<span class="gl-flex-grow-1 gl-text-right gl-mr-3 gl-text-gray-400">
<span class="gl-text-right gl-text-gray-400">
<gl-icon :name="collapseIcon" />
</span>
</button>

View File

@ -102,9 +102,8 @@ export default {
},
computedLinkClasses() {
return {
'gl-py-2': this.isPinnable,
'gl-py-3': !this.isPinnable,
'gl-mx-2': this.isSubitem,
'gl-px-2 gl-mx-2 gl-line-height-normal': this.isSubitem,
'gl-px-3': !this.isSubitem,
[this.item.link_classes]: this.item.link_classes,
...this.linkClasses,
};
@ -112,9 +111,6 @@ export default {
navItemLinkComponent() {
return this.item.to ? NavItemRouterLink : NavItemLink;
},
iconClasses() {
return this.isSubitem === true ? 'gl-ml-2 gl-mr-4' : 'gl-w-6 gl-mx-3';
},
},
};
</script>
@ -125,7 +121,7 @@ export default {
:is="navItemLinkComponent"
#default="{ isActive }"
v-bind="linkProps"
class="nav-item-link gl-rounded-base gl-relative gl-display-flex gl-align-items-center gl-mb-1 gl-px-0 gl-line-height-normal gl-text-black-normal! gl-hover-bg-t-gray-a-08 gl-focus-bg-t-gray-a-08 gl-text-decoration-none! gl-focus--focus"
class="nav-item-link gl-rounded-base gl-relative gl-display-flex gl-align-items-center gl-min-h-7 gl-gap-3 gl-mb-1 gl-py-2 gl-text-black-normal! gl-hover-bg-t-gray-a-08 gl-focus-bg-t-gray-a-08 gl-text-decoration-none! gl-focus--focus"
:class="computedLinkClasses"
data-qa-selector="nav_item_link"
data-testid="nav-item-link"
@ -137,13 +133,13 @@ export default {
style="width: 3px; border-radius: 3px; margin-right: 1px"
data-testid="active-indicator"
></div>
<div :class="iconClasses" class="gl-flex-shrink-0">
<div class="gl-flex-shrink-0 gl-w-6 gl-display-flex">
<slot name="icon">
<gl-icon v-if="item.icon" :name="item.icon" class="gl-ml-2 item-icon" />
<gl-icon v-if="item.icon" :name="item.icon" class="gl-m-auto item-icon" />
<gl-icon
v-else-if="isInPinnedSection"
name="grip"
class="gl-text-gray-400 gl-ml-2 draggable-icon"
class="gl-m-auto gl-text-gray-400 draggable-icon"
/>
</slot>
</div>
@ -154,7 +150,7 @@ export default {
</div>
</div>
<slot name="actions"></slot>
<span v-if="hasPill || isPinnable" class="gl-text-right gl-mr-3 gl-relative">
<span v-if="hasPill || isPinnable" class="gl-text-right gl-relative">
<gl-badge
v-if="hasPill"
size="sm"

View File

@ -1,8 +1,6 @@
# frozen_string_literal: true
class Projects::PagesController < Projects::ApplicationController
layout :resolve_layout
before_action :require_pages_enabled!
before_action :authorize_read_pages!, only: [:show]
before_action :authorize_update_pages!, except: [:show, :destroy]
@ -10,10 +8,6 @@ class Projects::PagesController < Projects::ApplicationController
feature_category :pages
before_action do
push_frontend_feature_flag(:show_pages_in_deployments_menu, current_user, type: :experiment)
end
def new
@pipeline_wizard_data = {
project_path: @project.full_path,
@ -66,10 +60,6 @@ class Projects::PagesController < Projects::ApplicationController
private
def resolve_layout
'project_settings' unless Feature.enabled?(:show_pages_in_deployments_menu, current_user, type: :experiment)
end
def project_params
params.require(:project).permit(project_params_attributes)
end

View File

@ -35,6 +35,11 @@ module Mutations
required: false,
description: 'Cluster agent of the environment.'
argument :kubernetes_namespace,
GraphQL::Types::String,
required: false,
description: 'Kubernetes namespace of the environment.'
field :environment,
Types::EnvironmentType,
null: true,

View File

@ -28,6 +28,11 @@ module Mutations
required: false,
description: 'Cluster agent of the environment.'
argument :kubernetes_namespace,
GraphQL::Types::String,
required: false,
description: 'Kubernetes namespace of the environment.'
field :environment,
Types::EnvironmentType,
null: true,

View File

@ -33,6 +33,9 @@ module Types
field :external_url, GraphQL::Types::String, null: true,
description: 'External URL of the environment.'
field :kubernetes_namespace, GraphQL::Types::String, null: true,
description: 'Kubernetes namespace of the environment.'
field :created_at, Types::TimeType,
description: 'When the environment was created.'

View File

@ -166,7 +166,7 @@ module Ci
raise FailedToPersistDataError, 'Modifed build trace chunk detected' if has_changes_to_save?
self.class.with_read_consistency(build) do
reset.then(&:unsafe_persist_data!)
reset.unsafe_persist_data!
end
end
rescue FailedToObtainLockError

View File

@ -18,7 +18,7 @@ class Environment < ApplicationRecord
belongs_to :cluster_agent, class_name: 'Clusters::Agent', optional: true, inverse_of: :environments
use_fast_destroy :all_deployments
nullify_if_blank :external_url
nullify_if_blank :external_url, :kubernetes_namespace
has_many :all_deployments, class_name: 'Deployment'
has_many :deployments, -> { visible }
@ -70,6 +70,14 @@ class Environment < ApplicationRecord
length: { maximum: 255 },
allow_nil: true
validates :kubernetes_namespace,
allow_nil: true,
length: 1..63,
format: {
with: Gitlab::Regex.kubernetes_namespace_regex,
message: Gitlab::Regex.kubernetes_namespace_regex_message
}
# Currently, the tier presence is validaed for newly created environments.
# After the `BackfillEnvironmentTiers` background migration has been completed, we should remove `on: :create`.
# See https://gitlab.com/gitlab-org/gitlab/-/issues/385253.

View File

@ -2,7 +2,7 @@
module Environments
class CreateService < BaseService
ALLOWED_ATTRIBUTES = %i[name external_url tier cluster_agent].freeze
ALLOWED_ATTRIBUTES = %i[name external_url tier cluster_agent kubernetes_namespace].freeze
def execute
unless can?(current_user, :create_environment, project)

View File

@ -2,7 +2,7 @@
module Environments
class UpdateService < BaseService
ALLOWED_ATTRIBUTES = %i[external_url tier cluster_agent].freeze
ALLOWED_ATTRIBUTES = %i[external_url tier cluster_agent kubernetes_namespace].freeze
def execute(environment)
unless can?(current_user, :update_environment, environment)

View File

@ -7,12 +7,10 @@
= render_if_exists 'shared/ultimate_feature_removal_banner', project: @project
- if Feature.enabled?(:show_pages_in_deployments_menu, current_user, type: :experiment)
= render Pajamas::AlertComponent.new(variant: :info,
title: _('GitLab Pages has moved'),
alert_options: { class: 'gl-my-5', data: { feature_id: Users::CalloutsHelper::PAGES_MOVED_CALLOUT, dismiss_endpoint: callouts_path, defer_links: 'true' } }) do |c|
- c.with_body do
= _('To go to GitLab Pages, on the left sidebar, select %{pages_link}.').html_safe % {pages_link: link_to('Deployments > Pages', project_pages_path(@project)).html_safe}
= render Pajamas::AlertComponent.new(title: _('GitLab Pages has moved'),
alert_options: { class: 'gl-my-5', data: { feature_id: Users::CalloutsHelper::PAGES_MOVED_CALLOUT, dismiss_endpoint: callouts_path, defer_links: 'true' } }) do |c|
- c.with_body do
= _('To go to GitLab Pages, on the left sidebar, select %{pages_link}.').html_safe % {pages_link: link_to('Deploy > Pages', project_pages_path(@project)).html_safe}
%section.settings.general-settings.no-animate.expanded#js-general-settings
.settings-header

View File

@ -1,9 +1,5 @@
- if Feature.enabled?(:show_pages_in_deployments_menu, current_user, type: :experiment)
- @breadcrumb_link = project_pages_path(@project)
- breadcrumb_title s_('GitLabPages|Pages')
- page_title s_('GitLabPages|Pages')
- else
%section.js-search-settings-section
- @breadcrumb_link = project_pages_path(@project)
- page_title s_('GitLabPages|Pages')
- if Feature.enabled?(:use_pipeline_wizard_for_pages, @project.group)
#js-pages{ data: @pipeline_wizard_data }

View File

@ -1,4 +1,4 @@
- page_title _('Pages')
- page_title s_('GitLabPages|Pages')
- unless @project.pages_deployed?
= render 'waiting'

View File

@ -1,8 +0,0 @@
---
name: show_pages_in_deployments_menu
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97783
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/373561
milestone: '15.4'
type: experiment
group: group::incubation
default_enabled: false

View File

@ -53,7 +53,7 @@ Sidekiq.configure_server do |config|
config.server_middleware(&Gitlab::SidekiqMiddleware.server_configurator(
metrics: Settings.monitoring.sidekiq_exporter,
arguments_logger: SidekiqLogArguments.enabled? && !enable_json_logs,
defer_jobs: Gitlab::Utils.to_boolean(ENV['SIDEKIQ_DEFER_JOBS'], default: true)
skip_jobs: Gitlab::Utils.to_boolean(ENV['SIDEKIQ_SKIP_JOBS'], default: true)
))
config.client_middleware(&Gitlab::SidekiqMiddleware.client_configurator)

View File

@ -0,0 +1,25 @@
---
key_path: redis_hll_counters.kubernetes_agent.flux_git_push_notified_unique_projects_monthly
description: MAU of the unique projects which were notified by agentk about new Git push events in order to reconcile their Flux workloads
product_section: ops
product_stage: deploy
product_group: environment
value_type: number
status: active
milestone: "16.2"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125146
time_frame: 28d
data_source: redis_hll
data_category: optional
instrumentation_class: RedisHLLMetric
options:
events:
- flux_git_push_notified_unique_projects
performance_indicator_type: []
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View File

@ -0,0 +1,25 @@
---
key_path: redis_hll_counters.kubernetes_agent.flux_git_push_notified_unique_projects_weekly
description: WAU of the unique projects which were notified by agentk about new Git push events in order to reconcile their Flux workloads
product_section: ops
product_stage: deploy
product_group: environment
value_type: number
status: active
milestone: "16.2"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/125146
time_frame: 7d
data_source: redis_hll
data_category: optional
instrumentation_class: RedisHLLMetric
options:
events:
- flux_git_push_notified_unique_projects
performance_indicator_type: []
distribution:
- ce
- ee
tier:
- free
- premium
- ultimate

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
class AddKubernetesNamespaceColumnToEnvironments < Gitlab::Database::Migration[2.1]
disable_ddl_transaction!
def up
with_lock_retries do
add_column :environments, :kubernetes_namespace, :text unless column_exists?(:environments, :kubernetes_namespace)
end
add_text_limit :environments, :kubernetes_namespace, 63
end
def down
remove_column :environments, :kubernetes_namespace
end
end

View File

@ -0,0 +1 @@
5aa32c9cc47402adbb622bb7e8a2cd4f7714973d25a5b787c1156f3dee517433

View File

@ -15682,7 +15682,9 @@ CREATE TABLE environments (
auto_delete_at timestamp with time zone,
tier smallint,
merge_request_id bigint,
cluster_agent_id bigint
cluster_agent_id bigint,
kubernetes_namespace text,
CONSTRAINT check_b5373a1804 CHECK ((char_length(kubernetes_namespace) <= 63))
);
CREATE SEQUENCE environments_id_seq

View File

@ -11,6 +11,3 @@ ignorecase: true
link: https://docs.gitlab.com/ee/development/documentation/styleguide/index.html
tokens:
- '\bI[ ,;:?!"]|\bI\x27.{1,2}'
- me
- myself
- mine

View File

@ -206,7 +206,7 @@ configuration option in `gitlab.yml`. These metrics are served from the
| `sidekiq_jobs_dead_total` | Counter | 13.7 | Sidekiq dead jobs (jobs that have run out of retries) | `queue`, `boundary`, `external_dependencies`, `feature_category`, `urgency` |
| `sidekiq_redis_requests_total` | Counter | 13.1 | Redis requests during a Sidekiq job execution | `queue`, `boundary`, `external_dependencies`, `feature_category`, `job_status`, `urgency` |
| `sidekiq_elasticsearch_requests_total` | Counter | 13.1 | Elasticsearch requests during a Sidekiq job execution | `queue`, `boundary`, `external_dependencies`, `feature_category`, `job_status`, `urgency` |
| `sidekiq_jobs_deferred_total` | Counter | 16.1 | Number of jobs being deferred (either via `run_sidekiq_jobs` feature flag or DB health status indicator) | `worker` |
| `sidekiq_jobs_skipped_total` | Counter | 16.2 | Number of jobs being skipped (dropped or deferred) when `drop_sidekiq_jobs` feature flag is enabled or `run_sidekiq_jobs` feature flag is disabled | `worker`, `action` |
| `sidekiq_running_jobs` | Gauge | 12.2 | Number of Sidekiq jobs running | `queue`, `boundary`, `external_dependencies`, `feature_category`, `urgency` |
| `sidekiq_concurrency` | Gauge | 12.5 | Maximum number of Sidekiq jobs | |
| `sidekiq_mem_total_bytes` | Gauge | 15.3 | Number of bytes allocated for both objects consuming an object slot and objects that required a malloc'| |

View File

@ -719,10 +719,7 @@ Prerequisite:
To set the maximum size of GitLab Pages site in a project, overriding the inherited setting:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. On the left sidebar, select **Settings > Pages**.
If this path is not visible, select **Deployments > Pages**.
[This location is part of an experiment](../../user/project/pages/index.md#menu-position-test).
1. On the left sidebar, select **Deploy > Pages**.
1. In **Maximum size of pages**, enter the size in MB.
1. Select **Save changes**.

View File

@ -3183,6 +3183,7 @@ Input type: `EnvironmentCreateInput`
| <a id="mutationenvironmentcreateclientmutationid"></a>`clientMutationId` | [`String`](#string) | A unique identifier for the client performing the mutation. |
| <a id="mutationenvironmentcreateclusteragentid"></a>`clusterAgentId` | [`ClustersAgentID`](#clustersagentid) | Cluster agent of the environment. |
| <a id="mutationenvironmentcreateexternalurl"></a>`externalUrl` | [`String`](#string) | External URL of the environment. |
| <a id="mutationenvironmentcreatekubernetesnamespace"></a>`kubernetesNamespace` | [`String`](#string) | Kubernetes namespace of the environment. |
| <a id="mutationenvironmentcreatename"></a>`name` | [`String!`](#string) | Name of the environment. |
| <a id="mutationenvironmentcreateprojectpath"></a>`projectPath` | [`ID!`](#id) | Full path of the project. |
| <a id="mutationenvironmentcreatetier"></a>`tier` | [`DeploymentTier`](#deploymenttier) | Tier of the environment. |
@ -3251,6 +3252,7 @@ Input type: `EnvironmentUpdateInput`
| <a id="mutationenvironmentupdateclusteragentid"></a>`clusterAgentId` | [`ClustersAgentID`](#clustersagentid) | Cluster agent of the environment. |
| <a id="mutationenvironmentupdateexternalurl"></a>`externalUrl` | [`String`](#string) | External URL of the environment. |
| <a id="mutationenvironmentupdateid"></a>`id` | [`EnvironmentID!`](#environmentid) | Global ID of the environment to update. |
| <a id="mutationenvironmentupdatekubernetesnamespace"></a>`kubernetesNamespace` | [`String`](#string) | Kubernetes namespace of the environment. |
| <a id="mutationenvironmentupdatetier"></a>`tier` | [`DeploymentTier`](#deploymenttier) | Tier of the environment. |
#### Fields
@ -14772,6 +14774,7 @@ Describes where code is deployed for a project.
| <a id="environmentenvironmenttype"></a>`environmentType` | [`String`](#string) | Folder name of the environment. |
| <a id="environmentexternalurl"></a>`externalUrl` | [`String`](#string) | External URL of the environment. |
| <a id="environmentid"></a>`id` | [`ID!`](#id) | ID of the environment. |
| <a id="environmentkubernetesnamespace"></a>`kubernetesNamespace` | [`String`](#string) | Kubernetes namespace of the environment. |
| <a id="environmentlatestopenedmostseverealert"></a>`latestOpenedMostSevereAlert` | [`AlertManagementAlert`](#alertmanagementalert) | Most severe open alert for the environment. If multiple alerts have equal severity, the most recent is returned. |
| <a id="environmentname"></a>`name` | [`String!`](#string) | Human-readable name of the environment. |
| <a id="environmentpath"></a>`path` | [`String!`](#string) | Path to the environment. |

View File

@ -693,7 +693,7 @@ Instead of:
## I
Do not use first-person singular. Use **you**, **we**, or **us** instead. ([Vale](../testing.md#vale) rule: [`FirstPerson.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/FirstPerson.yml))
Do not use first-person singular. Use **you** or rewrite the phrase instead. ([Vale](../testing.md#vale) rule: [`FirstPerson.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/FirstPerson.yml))
## i.e.
@ -897,10 +897,6 @@ Instead of:
For **MB** and **GB**, follow the [Microsoft guidance](https://learn.microsoft.com/en-us/style-guide/a-z-word-list-term-collections/term-collections/bits-bytes-terms).
## me, myself, mine
Do not use first-person singular. Use **you**, **we**, or **us** instead. ([Vale](../testing.md#vale) rule: [`FirstPerson.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/.vale/gitlab/FirstPerson.yml))
## member
When you add a [user account](#user-account) to a group or project,

View File

@ -717,10 +717,10 @@ When disabled, feature flags with the format of `run_sidekiq_jobs_{WorkerName}`
by scheduling the job at a later time. This feature flag is enabled by default for all workers.
Deferring jobs can be useful during an incident where contentious behavior from
worker instances are saturating infrastructure resources (such as database and database connection pool).
The implementation can be found at [DeferJobs Sidekiq server middleware](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/sidekiq_middleware/defer_jobs.rb).
The implementation can be found at [SkipJobs Sidekiq server middleware](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/sidekiq_middleware/skip_jobs.rb).
NOTE:
Jobs are deferred indefinitely as long as the feature flag is disabled. It is important to enable the
Jobs are deferred indefinitely as long as the feature flag is disabled. It is important to remove the
feature flag after the worker is deemed safe to continue processing.
When set to false, 100% of the jobs are deferred. When you want processing to resume, you can
@ -737,5 +737,23 @@ use a **percentage of time** rollout. For example:
/chatops run feature set run_sidekiq_jobs_SlowRunningWorker 50
# back to running all jobs normally
/chatops run feature set run_sidekiq_jobs_SlowRunningWorker true
/chatops run feature delete run_sidekiq_jobs_SlowRunningWorker
```
### Dropping Sidekiq jobs
Instead of [deferring jobs](#deferring-sidekiq-jobs), jobs can be entirely dropped by enabling the feature flag
`drop_sidekiq_jobs_{WorkerName}`. Use this feature flag when you are certain the jobs are safe to be dropped, i.e.
the jobs do not need to be processed in the future.
```shell
# drop all the jobs
/chatops run feature set drop_sidekiq_jobs_SlowRunningWorker true
# process jobs normally
/chatops run feature delete drop_sidekiq_jobs_SlowRunningWorker
```
NOTE:
Dropping feature flag (`drop_sidekiq_jobs_{WorkerName}`) takes precedence over deferring feature flag (`run_sidekiq_jobs_{WorkerName}`),
i.e. when `drop_sidekiq_jobs` is enabled and `run_sidekiq_jobs` is disabled, jobs are entirely dropped.

View File

@ -506,6 +506,7 @@ metric counters.
| `unique_counters["k8s_api_proxy_requests_unique_agents_via_ci_access"]` | integer array | no | The set of unique user ids that have interacted a CI Tunnel via `ci_access` to track the `k8s_api_proxy_requests_unique_agents_via_ci_access` metric event |
| `unique_counters["k8s_api_proxy_requests_unique_users_via_user_access"]` | integer array | no | The set of unique user ids that have interacted a CI Tunnel via `user_access` to track the `k8s_api_proxy_requests_unique_users_via_user_access` metric event |
| `unique_counters["k8s_api_proxy_requests_unique_agents_via_user_access"]` | integer array | no | The set of unique user ids that have interacted a CI Tunnel via `user_access` to track the `k8s_api_proxy_requests_unique_agents_via_user_access` metric event |
| `unique_counters["flux_git_push_notified_unique_projects"]` | integer array | no | The set of unique projects ids that have been notified to reconcile their Flux workloads to track the `flux_git_push_notified_unique_projects` metric event |
```plaintext
POST /internal/kubernetes/usage_metrics

View File

@ -54,10 +54,7 @@ this document for an [overview on DNS records](dns_concepts.md).
To add your custom domain to GitLab Pages:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > Pages**.
If this path is not visible, select **Deployments > Pages**.
[This location is part of an experiment](../index.md#menu-position-test).
1. On the left sidebar, select **Deploy > Pages**.
1. In the upper-right corner, select **New Domain**.
1. In **Domain**, enter the domain name.
1. Optional. In **Certificate**, turn off the **Automatic certificate management using Let's Encrypt** toggle to add an [SSL/TLS certificate](#adding-an-ssltls-certificate-to-pages). You can also add the certificate and key later.
@ -168,10 +165,7 @@ If you're using Cloudflare, check
After you have added all the DNS records:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > Pages**.
If this path is not visible, select **Deployments > Pages**.
[This location is part of an experiment](../index.md#menu-position-test).
1. On the left sidebar, select **Deploy > Pages**.
1. Next to the domain name, select **Edit**.
1. In **Verification status**, select **Retry verification** (**{retry}**).
@ -263,10 +257,7 @@ meet these requirements.
- To add the certificate at the time you add a new domain:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > Pages**.
If this path is not visible, select **Deployments > Pages**.
[This location is part of an experiment](../index.md#menu-position-test).
1. On the left sidebar, select **Deploy > Pages**.
1. In the upper-right corner, select **New Domain**.
1. In **Domain**, enter the domain name.
1. In **Certificate**, turn off the **Automatic certificate management using Let's Encrypt** toggle to add an [SSL/TLS certificate](#adding-an-ssltls-certificate-to-pages).
@ -275,17 +266,11 @@ meet these requirements.
- To add the certificate to a domain previously added:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > Pages**.
If this path is not visible, select **Deployments > Pages**.
[This location is part of an experiment](../index.md#menu-position-test).
1. On the left sidebar, select **Deploy > Pages**.
1. Next to the domain name, select **Edit**.
1. In **Certificate**, turn off the **Automatic certificate management using Let's Encrypt** toggle to add an [SSL/TLS certificate](#adding-an-ssltls-certificate-to-pages).
1. Select **Save changes**.
NOTE:
The Pages menu entry may also be located at **Deployments > Pages**, [more information](../index.md#menu-position-test)
1. Add the PEM certificate to its corresponding field.
1. If your certificate is missing its intermediate, copy
and paste the root certificate (usually available from your CA website)
@ -309,10 +294,7 @@ domain (as long as you've set a valid certificate for it).
To enable this setting:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > Pages**.
If this path is not visible, select **Deployments > Pages**.
[This location is part of an experiment](../index.md#menu-position-test).
1. On the left sidebar, select **Deploy > Pages**.
1. Select the **Force HTTPS (requires valid certificates)** checkbox.
1. Select **Save changes**.

View File

@ -43,10 +43,7 @@ For **self-managed** GitLab instances, make sure your administrator has
Once you've met the requirements, enable Let's Encrypt integration:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > Pages**.
If this path is not visible, select **Deployments > Pages**.
[This location is part of an experiment](../index.md#menu-position-test).
1. On the left sidebar, select **Deploy > Pages**.
1. Next to the domain name, select **Edit**.
1. Turn on the **Automatic certificate management using Let's Encrypt** toggle.
@ -73,10 +70,7 @@ associated Pages domain. GitLab also renews it automatically.
If you get an error **Something went wrong while obtaining the Let's Encrypt certificate**, first, make sure that your pages site is set to "Everyone" in your project's **Settings > General > Visibility**. This allows the Let's Encrypt Servers reach your pages site. Once this is confirmed, you can try obtaining the certificate again by following these steps:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > Pages**.
If this path is not visible, select **Deployments > Pages**.
[This location is part of an experiment](../index.md#menu-position-test).
1. On the left sidebar, select **Deploy > Pages**.
1. Next to the domain name, select **Edit**.
1. In **Verification status**, select **Retry verification** (**{retry}**).
1. If you're still getting the same error:
@ -91,10 +85,7 @@ If you get an error **Something went wrong while obtaining the Let's Encrypt cer
If you've enabled Let's Encrypt integration, but a certificate is absent after an hour and you see the message, "GitLab is obtaining a Let's Encrypt SSL certificate for this domain. This process can take some time. Please try again later.", try to remove and add the domain for GitLab Pages again by following these steps:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > Pages**.
If this path is not visible, select **Deployments > Pages**.
[This location is part of an experiment](../index.md#menu-position-test).
1. On the left sidebar, select **Deploy > Pages**.
1. Next to the domain name, select **Remove**.
1. [Add the domain again, and verify it](index.md#1-add-a-custom-domain).
1. [Enable Let's Encrypt integration for your domain](#enabling-lets-encrypt-integration-for-your-custom-domain).

View File

@ -27,10 +27,8 @@ If everything is configured correctly, the site can take approximately 30 minute
To view the pipeline, go to **CI/CD > Pipelines**.
When the pipeline is finished, go to **Settings > Pages** to find the link to
When the pipeline is finished, go to **Deploy > Pages** to find the link to
your Pages website.
If this path is not visible, select **Deployments > Pages**.
[This location is part of an experiment](../index.md#menu-position-test).
For every change pushed to your repository, GitLab CI/CD runs a new pipeline
that immediately publishes your changes to the Pages site.

View File

@ -24,10 +24,8 @@ To fork a sample project and create a Pages website:
GitLab CI/CD builds and deploys your site.
The site can take approximately 30 minutes to deploy.
When the pipeline is finished, go to **Settings > Pages** to find the link to
When the pipeline is finished, go to **Deploy > Pages** to find the link to
your Pages website.
If this path is not visible, select **Deployments > Pages**.
[This location is part of an experiment](../index.md#menu-position-test).
For every change pushed to your repository, GitLab CI/CD runs a new pipeline
that immediately publishes your changes to the Pages site.

View File

@ -175,11 +175,9 @@ deploy your website:
1. Save and commit the `.gitlab-ci.yml` file.
1. Go to **CI/CD > Pipelines** to watch the pipeline.
1. When the pipeline is finished, go to **Settings > Pages** to find the link to
1. When the pipeline is finished, go to **Deploy > Pages** to find the link to
your Pages website.
If this path is not visible, select **Deployments > Pages**.
[This location is part of an experiment](../index.md#menu-position-test).
When this `pages` job completes successfully, a special `pages:deploy` job
appears in the pipeline view. It prepares the content of the website for the
GitLab Pages daemon. GitLab runs it in the background and doesn't use a runner.

View File

@ -23,10 +23,8 @@ configured to generate a Pages site.
and select **Run pipeline** to trigger GitLab CI/CD to build and deploy your
site.
When the pipeline is finished, go to **Settings > Pages** to find the link to
When the pipeline is finished, go to **Deploy > Pages** to find the link to
your Pages website.
If this path is not visible, select **Deployments > Pages**.
[This location is part of an experiment](../index.md#menu-position-test).
For every change pushed to your repository, GitLab CI/CD runs a new pipeline
that immediately publishes your changes to the Pages site.

View File

@ -34,10 +34,8 @@ a pipeline deploys your Pages website.
To complete the setup and generate a GitLab Pages deployment:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > Pages**.
1. On the left sidebar, select **Deploy > Pages**.
If this path is not visible, select **Deployments > Pages**.
[This location is part of an experiment](../index.md#menu-position-test).
A **Get Started with Pages** form appears. If this form is not available,
see [Troubleshooting](#if-the-get-started-with-pages-form-is-not-available).
1. For **Step 1**, enter an image name and verify that your files are in a `public` folder.

View File

@ -34,13 +34,6 @@ Pages does not support dynamic server-side processing, for instance, as `.php` a
For more information, see
[Static vs dynamic websites](https://about.gitlab.com/blog/2016/06/03/ssg-overview-gitlab-pages-part-1-dynamic-x-static/).
## Menu Position Test
NOTE:
We are currently conducting an A/B test where some users may see the Pages
Menu entry under "Deployments" instead of "Settings". We think that this may
be a more accurate position. Feel free to add any feedback to [the experiment issue](https://gitlab.com/gitlab-org/gitlab/-/issues/373547).
## Getting started
To create a GitLab Pages website:

View File

@ -65,10 +65,7 @@ You can configure redirects for your site using a `_redirects` file. For more in
To remove your pages:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > Pages**.
If this path is not visible, select **Deployments > Pages**.
[This location is part of an experiment](index.md#menu-position-test).
1. On the left sidebar, select **Deploy > Pages**.
1. Select **Remove pages**.
## Subdomains of subdomains
@ -102,7 +99,7 @@ By default, every project in a group shares the same domain, for example, `group
To ensure your project uses a unique Pages domain, enable the unique domains feature for the project:
1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project.
1. Select **Settings > Pages**.
1. On the left sidebar, select **Deploy > Pages**.
1. Select the **Use unique domain** checkbox.
1. Select **Save changes**.

View File

@ -64,7 +64,8 @@ module API
events = params[:unique_counters]&.slice(
:agent_users_using_ci_tunnel,
:k8s_api_proxy_requests_unique_users_via_ci_access, :k8s_api_proxy_requests_unique_agents_via_ci_access,
:k8s_api_proxy_requests_unique_users_via_user_access, :k8s_api_proxy_requests_unique_agents_via_user_access
:k8s_api_proxy_requests_unique_users_via_user_access, :k8s_api_proxy_requests_unique_agents_via_user_access,
:flux_git_push_notified_unique_projects
)
events&.each do |event, entity_ids|
@ -220,6 +221,7 @@ module API
optional :k8s_api_proxy_requests_unique_agents_via_ci_access, type: Array[Integer], desc: 'An array of agents that have interacted with the CI tunnel via `ci_access`'
optional :k8s_api_proxy_requests_unique_users_via_user_access, type: Array[Integer], desc: 'An array of users that have interacted with the CI tunnel via `user_access`'
optional :k8s_api_proxy_requests_unique_agents_via_user_access, type: Array[Integer], desc: 'An array of agents that have interacted with the CI tunnel via `user_access`'
optional :flux_git_push_notified_unique_projects, type: Array[Integer], desc: 'An array of projects that have been notified to reconcile their Flux workloads'
end
end
post '/', feature_category: :deployment_management do

View File

@ -78,6 +78,8 @@ module Gitlab
job_status = if job_exception
'fail'
elsif job['dropped']
'dropped'
elsif job['deferred']
'deferred'
else

View File

@ -7,7 +7,7 @@ module Gitlab
# The result of this method should be passed to
# Sidekiq's `config.server_middleware` method
# eg: `config.server_middleware(&Gitlab::SidekiqMiddleware.server_configurator)`
def self.server_configurator(metrics: true, arguments_logger: true, defer_jobs: true)
def self.server_configurator(metrics: true, arguments_logger: true, skip_jobs: true)
lambda do |chain|
# Size limiter should be placed at the top
chain.add ::Gitlab::SidekiqMiddleware::SizeLimiter::Server
@ -40,7 +40,7 @@ module Gitlab
# so we can compare the latest WAL location against replica
chain.add ::Gitlab::SidekiqMiddleware::DuplicateJobs::Server
chain.add ::Gitlab::Database::LoadBalancing::SidekiqServerMiddleware
chain.add ::Gitlab::SidekiqMiddleware::DeferJobs if defer_jobs
chain.add ::Gitlab::SidekiqMiddleware::SkipJobs if skip_jobs
end
end

View File

@ -1,89 +0,0 @@
# frozen_string_literal: true
module Gitlab
module SidekiqMiddleware
class DeferJobs
DELAY = ENV.fetch("SIDEKIQ_DEFER_JOBS_DELAY", 5.minutes)
RUN_FEATURE_FLAG_PREFIX = "run_sidekiq_jobs"
DatabaseHealthStatusChecker = Struct.new(:id, :job_class_name)
DEFERRED_COUNTER = :sidekiq_jobs_deferred_total
def initialize
@metrics = init_metrics
end
# There are 2 scenarios under which this middleware defers a job
# 1. When run_sidekiq_jobs_#{worker_name} FF is disabled. This FF is enabled by default
# for all workers.
# 2. Gitlab::Database::HealthStatus, on evaluating the db health status if it returns any indicator
# with stop signal, the jobs will be delayed by 'x' seconds (set in worker).
def call(worker, job, _queue)
# ActiveJobs have wrapped class stored in 'wrapped' key
resolved_class = job['wrapped']&.safe_constantize || worker.class
defer_job, delay, deferred_by = defer_job_info(resolved_class, job)
if !!defer_job
# Referred in job_logger's 'log_job_done' method to compute proper 'job_status'
job['deferred'] = true
job['deferred_by'] = deferred_by
job['deferred_count'] ||= 0
job['deferred_count'] += 1
worker.class.perform_in(delay, *job['args'])
@metrics.fetch(DEFERRED_COUNTER).increment({ worker: worker.class.name })
# This breaks the middleware chain and return
return
end
yield
end
private
def defer_job_info(worker_class, job)
if !run_job_by_ff?(worker_class)
[true, DELAY, :feature_flag]
elsif defer_job_by_database_health_signal?(job, worker_class)
[true, worker_class.database_health_check_attrs[:delay_by], :database_health_check]
end
end
def run_job_by_ff?(worker_class)
# always returns true by default for all workers unless the FF is specifically disabled, e.g. during an incident
Feature.enabled?(
:"#{RUN_FEATURE_FLAG_PREFIX}_#{worker_class.name}",
type: :worker,
default_enabled_if_undefined: true
)
end
def defer_job_by_database_health_signal?(job, worker_class)
unless worker_class.respond_to?(:defer_on_database_health_signal?) &&
worker_class.defer_on_database_health_signal?
return false
end
health_check_attrs = worker_class.database_health_check_attrs
job_base_model = Gitlab::Database.schemas_to_base_models[health_check_attrs[:gitlab_schema]].first
health_context = Gitlab::Database::HealthStatus::Context.new(
DatabaseHealthStatusChecker.new(job['jid'], worker_class.name),
job_base_model.connection,
health_check_attrs[:gitlab_schema],
health_check_attrs[:tables]
)
Gitlab::Database::HealthStatus.evaluate(health_context).any?(&:stop?)
end
def init_metrics
{
DEFERRED_COUNTER => Gitlab::Metrics.counter(DEFERRED_COUNTER, 'The number of jobs deferred')
}
end
end
end
end

View File

@ -0,0 +1,125 @@
# frozen_string_literal: true
module Gitlab
module SidekiqMiddleware
class SkipJobs
DELAY = ENV.fetch("SIDEKIQ_DEFER_JOBS_DELAY", 5.minutes)
RUN_FEATURE_FLAG_PREFIX = "run_sidekiq_jobs"
DROP_FEATURE_FLAG_PREFIX = "drop_sidekiq_jobs"
DatabaseHealthStatusChecker = Struct.new(:id, :job_class_name)
COUNTER = :sidekiq_jobs_skipped_total
def initialize
@metrics = init_metrics
end
# This middleware decides whether a job is dropped, deferred or runs normally.
# In short:
# - `drop_sidekiq_jobs_#{worker_name}` FF enabled (disabled by default) --> drops the job
# - `run_sidekiq_jobs_#{worker_name}` FF disabled (enabled by default) --> defers the job
#
# DROPPING JOBS
# A job is dropped when `drop_sidekiq_jobs_#{worker_name}` FF is enabled. This FF is disabled by default for
# all workers. Dropped jobs are completely ignored and not requeued for future processing.
#
# DEFERRING JOBS
# Deferred jobs are rescheduled to perform in the future.
# There are 2 scenarios under which this middleware defers a job:
# 1. When run_sidekiq_jobs_#{worker_name} FF is disabled. This FF is enabled by default
# for all workers.
# 2. Gitlab::Database::HealthStatus, on evaluating the db health status if it returns any indicator
# with stop signal, the jobs will be delayed by 'x' seconds (set in worker).
#
# Dropping jobs takes higher priority over deferring jobs. For example, when `drop_sidekiq_jobs` is enabled and
# `run_sidekiq_jobs` is disabled, it results to jobs being dropped.
def call(worker, job, _queue)
# ActiveJobs have wrapped class stored in 'wrapped' key
resolved_class = job['wrapped']&.safe_constantize || worker.class
if drop_job?(resolved_class)
# no-op, drop the job entirely
drop_job!(job, worker)
return
elsif !!defer_job?(resolved_class, job)
defer_job!(job, worker)
return
end
yield
end
private
def defer_job?(worker_class, job)
if !run_job_by_ff?(worker_class)
@delay = DELAY
@deferred_by = :feature_flag
true
elsif defer_job_by_database_health_signal?(job, worker_class)
@delay = worker_class.database_health_check_attrs[:delay_by]
@deferred_by = :database_health_check
true
end
end
def run_job_by_ff?(worker_class)
# always returns true by default for all workers unless the FF is specifically disabled, e.g. during an incident
Feature.enabled?(
:"#{RUN_FEATURE_FLAG_PREFIX}_#{worker_class.name}",
type: :worker,
default_enabled_if_undefined: true
)
end
def defer_job_by_database_health_signal?(job, worker_class)
unless worker_class.respond_to?(:defer_on_database_health_signal?) &&
worker_class.defer_on_database_health_signal?
return false
end
health_check_attrs = worker_class.database_health_check_attrs
job_base_model = Gitlab::Database.schemas_to_base_models[health_check_attrs[:gitlab_schema]].first
health_context = Gitlab::Database::HealthStatus::Context.new(
DatabaseHealthStatusChecker.new(job['jid'], worker_class.name),
job_base_model.connection,
health_check_attrs[:gitlab_schema],
health_check_attrs[:tables]
)
Gitlab::Database::HealthStatus.evaluate(health_context).any?(&:stop?)
end
def drop_job?(worker_class)
Feature.enabled?(
:"#{DROP_FEATURE_FLAG_PREFIX}_#{worker_class.name}",
type: :worker,
default_enabled_if_undefined: false
)
end
def drop_job!(job, worker)
job['dropped'] = true
@metrics.fetch(COUNTER).increment({ worker: worker.class.name, action: "dropped" })
end
def defer_job!(job, worker)
# Referred in job_logger's 'log_job_done' method to compute proper 'job_status'
job['deferred'] = true
job['deferred_by'] = @deferred_by
job['deferred_count'] ||= 0
job['deferred_count'] += 1
worker.class.perform_in(@delay, *job['args'])
@metrics.fetch(COUNTER).increment({ worker: worker.class.name, action: "deferred" })
end
def init_metrics
{
COUNTER => Gitlab::Metrics.counter(COUNTER, 'The number of skipped jobs')
}
end
end
end
end

View File

@ -16,3 +16,7 @@
aggregation: weekly
- name: k8s_api_proxy_requests_unique_agents_via_user_access
aggregation: monthly
- name: flux_git_push_notified_unique_projects
aggregation: weekly
- name: flux_git_push_notified_unique_projects
aggregation: monthly

View File

@ -9,10 +9,7 @@ module Sidebars
add_item(environments_menu_item)
add_item(feature_flags_menu_item)
add_item(releases_menu_item)
if Feature.enabled?(:show_pages_in_deployments_menu, context.current_user, type: :experiment)
add_item(pages_menu_item)
end
add_item(pages_menu_item)
true
end
@ -95,8 +92,8 @@ module Sidebars
::Sidebars::MenuItem.new(
title: _('Pages'),
link: project_pages_path(context.project),
super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::OperationsMenu,
active_routes: { path: 'pages#show' },
super_sidebar_parent: Sidebars::Projects::SuperSidebarMenus::DeployMenu,
active_routes: { path: %w[pages#new pages#show] },
item_id: :pages
)
end

View File

@ -16,11 +16,6 @@ module Sidebars
add_item(merge_requests_menu_item)
add_item(ci_cd_menu_item)
add_item(packages_and_registries_menu_item)
if Feature.disabled?(:show_pages_in_deployments_menu, context.current_user, type: :experiment)
add_item(pages_menu_item)
end
add_item(monitor_menu_item)
add_item(usage_quotas_menu_item)
@ -131,19 +126,6 @@ module Sidebars
)
end
def pages_menu_item
unless context.project.pages_available?
return ::Sidebars::NilMenuItem.new(item_id: :pages)
end
::Sidebars::MenuItem.new(
title: _('Pages'),
link: project_pages_path(context.project),
active_routes: { path: 'pages#show' },
item_id: :pages
)
end
def monitor_menu_item
if context.project.archived? || !can?(context.current_user, :admin_operations, context.project)
return ::Sidebars::NilMenuItem.new(item_id: :monitor)

View File

@ -4596,6 +4596,9 @@ msgstr ""
msgid "All changes are committed"
msgstr ""
msgid "All default branches"
msgstr ""
msgid "All eligible users"
msgstr ""

View File

@ -30,9 +30,6 @@ module QA
end
before do
# Pages Menu Experiment currently progress https://gitlab.com/gitlab-org/gitlab/-/merge_requests/98044
# Update spec along with Feature Flag Removal.
Runtime::Feature.disable(:show_pages_in_deployments_menu)
Flow::Login.sign_in
Resource::ProjectRunner.fabricate_via_api! do |runner|
runner.project = project
@ -41,10 +38,6 @@ module QA
pipeline.visit!
end
after do
Runtime::Feature.enable(:show_pages_in_deployments_menu)
end
it 'creates a Pages website',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347669' do
Page::Project::Pipeline::Show.perform do |show|
@ -57,7 +50,7 @@ module QA
end
Page::Project::Menu.perform(&:go_to_pages_settings)
Page::Project::Settings::Pages.perform(&:go_to_access_page)
Page::Project::Deployments::Pages.perform(&:go_to_access_page)
Support::Waiter.wait_until(
sleep_interval: 2,

View File

@ -15,8 +15,6 @@ RSpec.describe 'Project navbar', :with_license, feature_category: :groups_and_pr
before do
sign_in(user)
stub_feature_flags(show_pages_in_deployments_menu: false)
stub_config(registry: { enabled: false })
stub_feature_flags(harbor_registry_integration: false)
stub_feature_flags(ml_experiment_tracking: false)
@ -53,8 +51,8 @@ RSpec.describe 'Project navbar', :with_license, feature_category: :groups_and_pr
stub_config(pages: { enabled: true })
insert_after_sub_nav_item(
_('Packages and registries'),
within: _('Settings'),
_('Releases'),
within: _('Deployments'),
new_sub_nav_item_name: _('Pages')
)

View File

@ -10,8 +10,6 @@ RSpec.describe 'Pages edits pages settings', :js, feature_category: :pages do
before do
allow(Gitlab.config.pages).to receive(:enabled).and_return(true)
stub_feature_flags(show_pages_in_deployments_menu: false)
project.add_maintainer(user)
sign_in(user)
@ -82,25 +80,39 @@ RSpec.describe 'Pages edits pages settings', :js, feature_category: :pages do
end
end
describe 'project settings page' do
it 'renders "Pages" tab' do
visit edit_project_path(project)
describe 'menu entry' do
describe 'on the pages page' do
it 'renders "Pages" tab' do
visit project_pages_path(project)
page.within '.nav-sidebar' do
expect(page).to have_link('Pages')
page.within '.nav-sidebar' do
expect(page).to have_link('Pages')
end
end
end
context 'when pages are disabled' do
before do
allow(Gitlab.config.pages).to receive(:enabled).and_return(false)
describe 'in another menu entry under deployments' do
context 'when pages are enabled' do
it 'renders "Pages" tab' do
visit project_environments_path(project)
page.within '.nav-sidebar' do
expect(page).to have_link('Pages')
end
end
end
it 'does not render "Pages" tab' do
visit edit_project_path(project)
context 'when pages are disabled' do
before do
allow(Gitlab.config.pages).to receive(:enabled).and_return(false)
end
page.within '.nav-sidebar' do
expect(page).not_to have_link('Pages')
it 'does not render "Pages" tab' do
visit project_environments_path(project)
page.within '.nav-sidebar' do
expect(page).not_to have_link('Pages')
end
end
end
end

View File

@ -65,15 +65,4 @@ RSpec.describe 'User searches project settings', :js, feature_category: :groups_
it_behaves_like 'can search settings', 'Alerts', 'Error tracking'
end
context 'in Pages page' do
before do
stub_feature_flags(show_pages_in_deployments_menu: false)
allow(Gitlab.config.pages).to receive(:enabled).and_return(true)
visit project_pages_path(project)
end
it_behaves_like 'can highlight results', 'static website'
end
end

View File

@ -221,9 +221,11 @@ describe('MembersTable', () => {
'col-actions',
'gl-display-none!',
'gl-lg-display-table-cell!',
'gl-vertical-align-middle!',
]);
expect(findTableCellByMemberId('Actions', members[1].id).classes()).toStrictEqual([
'col-actions',
'gl-vertical-align-middle!',
]);
});
});

View File

@ -2,8 +2,7 @@
require 'spec_helper'
RSpec.describe Resolvers::DesignManagement::VersionResolver, feature_category: :shared,
quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/416627' do
RSpec.describe Resolvers::DesignManagement::VersionResolver, feature_category: :shared do
include GraphqlHelpers
include DesignManagementTestHelpers

View File

@ -98,7 +98,7 @@ RSpec.describe Gitlab::Database::HealthStatus, feature_category: :database do
end
let(:deferred_worker_health_checker) do
Gitlab::SidekiqMiddleware::DeferJobs::DatabaseHealthStatusChecker.new(
Gitlab::SidekiqMiddleware::SkipJobs::DatabaseHealthStatusChecker.new(
123,
deferred_worker.name
)
@ -116,7 +116,7 @@ RSpec.describe Gitlab::Database::HealthStatus, feature_category: :database do
it 'captures sidekiq job class in the log' do
expect(Gitlab::Database::HealthStatus::Logger).to receive(:info).with(
status_checker_id: deferred_worker_health_checker.id,
status_checker_type: 'Gitlab::SidekiqMiddleware::DeferJobs::DatabaseHealthStatusChecker',
status_checker_type: 'Gitlab::SidekiqMiddleware::SkipJobs::DatabaseHealthStatusChecker',
job_class_name: deferred_worker_health_checker.job_class_name,
health_status_indicator: autovacuum_indicator_class.to_s,
indicator_signal: 'Stop',

View File

@ -426,7 +426,7 @@ RSpec.describe Gitlab::SidekiqLogging::StructuredLogger do
end
context 'when the job is deferred' do
it 'logs start and end of job with deferred job_status' do
it 'logs start and end of job with "deferred" job_status' do
travel_to(timestamp) do
expect(logger).to receive(:info).with(start_payload).ordered
expect(logger).to receive(:info).with(deferred_payload).ordered
@ -441,6 +441,21 @@ RSpec.describe Gitlab::SidekiqLogging::StructuredLogger do
end
end
end
context 'when the job is dropped' do
it 'logs start and end of job with "dropped" job_status' do
travel_to(timestamp) do
expect(logger).to receive(:info).with(start_payload).ordered
expect(logger).to receive(:info).with(dropped_payload).ordered
expect(subject).to receive(:log_job_start).and_call_original
expect(subject).to receive(:log_job_done).and_call_original
call_subject(job, 'test_queue') do
job['dropped'] = true
end
end
end
end
end
describe '#add_time_keys!' do

View File

@ -1,95 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::SidekiqMiddleware::DeferJobs, feature_category: :scalability do
let(:job) { { 'jid' => 123, 'args' => [456] } }
let(:queue) { 'test_queue' }
let(:test_worker) do
Class.new do
def self.name
'TestWorker'
end
include ApplicationWorker
end
end
subject { described_class.new }
before do
stub_const('TestWorker', test_worker)
end
describe '#call' do
context 'with worker not opted for database health check' do
context 'when run_sidekiq_jobs feature flag is disabled' do
let(:deferred_jobs_metric) { instance_double(Prometheus::Client::Counter, increment: true) }
before do
stub_feature_flags(run_sidekiq_jobs_TestWorker: false)
allow(Gitlab::Metrics).to receive(:counter).and_call_original
allow(Gitlab::Metrics).to receive(:counter).with(described_class::DEFERRED_COUNTER, anything)
.and_return(deferred_jobs_metric)
end
it 'defers the job' do
expect(TestWorker).to receive(:perform_in).with(described_class::DELAY, *job['args'])
expect { |b| subject.call(TestWorker.new, job, queue, &b) }.not_to yield_control
end
it 'increments the defer_count' do
(1..5).each do |count|
subject.call(TestWorker.new, job, queue)
expect(job).to include('deferred_count' => count)
end
end
it 'increments the counter' do
expect(deferred_jobs_metric).to receive(:increment).with({ worker: "TestWorker" })
subject.call(TestWorker.new, job, queue)
end
end
context 'when run_sidekiq_jobs feature flag is enabled' do
it 'runs the job normally' do
expect { |b| subject.call(TestWorker.new, job, queue, &b) }.to yield_control
end
end
end
context 'with worker opted for database health check' do
let(:health_signal_attrs) { { gitlab_schema: :gitlab_main, delay: 1.minute, tables: [:users] } }
around do |example|
with_sidekiq_server_middleware do |chain|
chain.add described_class
Sidekiq::Testing.inline! { example.run }
end
end
before do
TestWorker.defer_on_database_health_signal(*health_signal_attrs.values)
end
context 'without any stop signal from database health check' do
it 'runs the job normally' do
expect { |b| subject.call(TestWorker.new, job, queue, &b) }.to yield_control
end
end
context 'with stop signal from database health check' do
before do
stop_signal = instance_double("Gitlab::Database::HealthStatus::Signals::Stop", stop?: true)
allow(Gitlab::Database::HealthStatus).to receive(:evaluate).and_return([stop_signal])
end
it 'defers the job by set time' do
expect(TestWorker).to receive(:perform_in).with(health_signal_attrs[:delay], *job['args'])
TestWorker.perform_async(*job['args'])
end
end
end
end
end

View File

@ -400,7 +400,7 @@ RSpec.describe Gitlab::SidekiqMiddleware::ServerMetrics do
Gitlab::SidekiqMiddleware.server_configurator(
metrics: true,
arguments_logger: false,
defer_jobs: false
skip_jobs: false
).call(chain)
Sidekiq::Testing.inline! { example.run }

View File

@ -0,0 +1,151 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::SidekiqMiddleware::SkipJobs, feature_category: :scalability do
let(:job) { { 'jid' => 123, 'args' => [456] } }
let(:queue) { 'test_queue' }
let(:worker) do
Class.new do
def self.name
'TestWorker'
end
include ApplicationWorker
end
end
subject { described_class.new }
before do
stub_const('TestWorker', worker)
stub_feature_flags("drop_sidekiq_jobs_#{TestWorker.name}": false)
end
describe '#call' do
context 'with worker not opted for database health check' do
describe "with all combinations of drop and defer FFs" do
using RSpec::Parameterized::TableSyntax
let(:metric) { instance_double(Prometheus::Client::Counter, increment: true) }
shared_examples 'runs the job normally' do
it 'yields control' do
expect { |b| subject.call(TestWorker.new, job, queue, &b) }.to yield_control
end
it 'does not increment any metric counter' do
expect(metric).not_to receive(:increment)
subject.call(TestWorker.new, job, queue) { nil }
end
it 'does not increment deferred_count' do
subject.call(TestWorker.new, job, queue) { nil }
expect(job).not_to include('deferred_count')
end
end
shared_examples 'drops the job' do
it 'does not yield control' do
expect { |b| subject.call(TestWorker.new, job, queue, &b) }.not_to yield_control
end
it 'increments counter' do
expect(metric).to receive(:increment).with({ worker: "TestWorker", action: "dropped" })
subject.call(TestWorker.new, job, queue) { nil }
end
it 'does not increment deferred_count' do
subject.call(TestWorker.new, job, queue) { nil }
expect(job).not_to include('deferred_count')
end
it 'has dropped field in job equal to true' do
subject.call(TestWorker.new, job, queue) { nil }
expect(job).to include({ 'dropped' => true })
end
end
shared_examples 'defers the job' do
it 'does not yield control' do
expect { |b| subject.call(TestWorker.new, job, queue, &b) }.not_to yield_control
end
it 'delays the job' do
expect(TestWorker).to receive(:perform_in).with(described_class::DELAY, *job['args'])
subject.call(TestWorker.new, job, queue) { nil }
end
it 'increments counter' do
expect(metric).to receive(:increment).with({ worker: "TestWorker", action: "deferred" })
subject.call(TestWorker.new, job, queue) { nil }
end
it 'has deferred related fields in job payload' do
subject.call(TestWorker.new, job, queue) { nil }
expect(job).to include({ 'deferred' => true, 'deferred_by' => :feature_flag, 'deferred_count' => 1 })
end
end
before do
stub_feature_flags("drop_sidekiq_jobs_#{TestWorker.name}": drop_ff)
stub_feature_flags("run_sidekiq_jobs_#{TestWorker.name}": run_ff)
allow(Gitlab::Metrics).to receive(:counter).and_call_original
allow(Gitlab::Metrics).to receive(:counter).with(described_class::COUNTER, anything).and_return(metric)
end
where(:drop_ff, :run_ff, :resulting_behavior) do
false | true | "runs the job normally"
true | true | "drops the job"
false | false | "defers the job"
true | false | "drops the job"
end
with_them do
it_behaves_like params[:resulting_behavior]
end
end
end
context 'with worker opted for database health check' do
let(:health_signal_attrs) { { gitlab_schema: :gitlab_main, delay: 1.minute, tables: [:users] } }
around do |example|
with_sidekiq_server_middleware do |chain|
chain.add described_class
Sidekiq::Testing.inline! { example.run }
end
end
before do
TestWorker.defer_on_database_health_signal(*health_signal_attrs.values)
end
context 'without any stop signal from database health check' do
it 'runs the job normally' do
expect { |b| subject.call(TestWorker.new, job, queue, &b) }.to yield_control
end
end
context 'with stop signal from database health check' do
before do
stop_signal = instance_double("Gitlab::Database::HealthStatus::Signals::Stop", stop?: true)
allow(Gitlab::Database::HealthStatus).to receive(:evaluate).and_return([stop_signal])
end
it 'defers the job by set time' do
expect(TestWorker).to receive(:perform_in).with(health_signal_attrs[:delay], *job['args'])
TestWorker.perform_async(*job['args'])
end
end
end
end
end

View File

@ -31,6 +31,7 @@ RSpec.describe Gitlab::SidekiqMiddleware do
shared_examples "a middleware chain" do
before do
configurator.call(chain)
stub_feature_flags("drop_sidekiq_jobs_#{worker_class.name}": false) # not dropping the job
end
it "passes through the right middlewares", :aggregate_failures do
enabled_sidekiq_middlewares.each do |middleware|
@ -69,7 +70,7 @@ RSpec.describe Gitlab::SidekiqMiddleware do
::Gitlab::SidekiqMiddleware::WorkerContext::Server,
::Gitlab::SidekiqMiddleware::DuplicateJobs::Server,
::Gitlab::Database::LoadBalancing::SidekiqServerMiddleware,
::Gitlab::SidekiqMiddleware::DeferJobs
::Gitlab::SidekiqMiddleware::SkipJobs
]
end
@ -79,9 +80,7 @@ RSpec.describe Gitlab::SidekiqMiddleware do
described_class.server_configurator(
metrics: true,
arguments_logger: true,
# defer_jobs has to be false because this middleware defers jobs from a worker based on
# `worker` type feature flag which is enabled by default in test
defer_jobs: false
skip_jobs: false
).call(chain)
Sidekiq::Testing.inline! { example.run }
@ -114,7 +113,7 @@ RSpec.describe Gitlab::SidekiqMiddleware do
described_class.server_configurator(
metrics: false,
arguments_logger: false,
defer_jobs: false
skip_jobs: false
)
end
@ -122,7 +121,7 @@ RSpec.describe Gitlab::SidekiqMiddleware do
[
Gitlab::SidekiqMiddleware::ServerMetrics,
Gitlab::SidekiqMiddleware::ArgumentsLogger,
Gitlab::SidekiqMiddleware::DeferJobs
Gitlab::SidekiqMiddleware::SkipJobs
]
end

View File

@ -68,5 +68,31 @@ RSpec.describe Sidebars::Projects::Menus::DeploymentsMenu, feature_category: :na
it_behaves_like 'access rights checks'
end
describe 'Pages' do
let(:item_id) { :pages }
before do
allow(project).to receive(:pages_available?).and_return(pages_enabled)
end
describe 'when pages are enabled' do
let(:pages_enabled) { true }
it { is_expected.not_to be_nil }
describe 'when the user does not have access' do
let(:user) { nil }
it { is_expected.to be_nil }
end
end
describe 'when pages are not enabled' do
let(:pages_enabled) { false }
it { is_expected.to be_nil }
end
end
end
end

View File

@ -10,10 +10,6 @@ RSpec.describe Sidebars::Projects::Menus::SettingsMenu, feature_category: :navig
subject { described_class.new(context) }
before do
stub_feature_flags(show_pages_in_deployments_menu: false)
end
describe '#render?' do
it 'returns false when menu does not have any menu items' do
allow(subject).to receive(:has_renderable_items?).and_return(false)
@ -117,32 +113,6 @@ RSpec.describe Sidebars::Projects::Menus::SettingsMenu, feature_category: :navig
end
end
describe 'Pages' do
let(:item_id) { :pages }
before do
allow(project).to receive(:pages_available?).and_return(pages_enabled)
end
describe 'when pages are enabled' do
let(:pages_enabled) { true }
specify { is_expected.not_to be_nil }
describe 'when the user does not have access' do
let(:user) { nil }
specify { is_expected.to be_nil }
end
end
describe 'when pages are not enabled' do
let(:pages_enabled) { false }
specify { is_expected.to be_nil }
end
end
describe 'Merge requests' do
let(:item_id) { :merge_requests }

View File

@ -15,6 +15,7 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching, feature_categ
it { is_expected.to be_kind_of(ReactiveCaching) }
it { is_expected.to nullify_if_blank(:external_url) }
it { is_expected.to nullify_if_blank(:kubernetes_namespace) }
it { is_expected.to belong_to(:project).required }
it { is_expected.to belong_to(:merge_request).optional }
@ -36,6 +37,7 @@ RSpec.describe Environment, :use_clean_rails_memory_store_caching, feature_categ
it { is_expected.to validate_length_of(:slug).is_at_most(24) }
it { is_expected.to validate_length_of(:external_url).is_at_most(255) }
it { is_expected.to validate_length_of(:kubernetes_namespace).is_at_most(63) }
describe 'validation' do
it 'does not become invalid record when external_url is empty' do

View File

@ -134,7 +134,8 @@ RSpec.describe API::Internal::Kubernetes, feature_category: :deployment_manageme
k8s_api_proxy_requests_unique_users_via_ci_access: [10, 999, 777, 10],
k8s_api_proxy_requests_unique_agents_via_ci_access: [10, 999, 777, 10],
k8s_api_proxy_requests_unique_users_via_user_access: [10, 999, 777, 10],
k8s_api_proxy_requests_unique_agents_via_user_access: [10, 999, 777, 10]
k8s_api_proxy_requests_unique_agents_via_user_access: [10, 999, 777, 10],
flux_git_push_notified_unique_projects: [10, 999, 777, 10]
}
expected_counters = {
kubernetes_agent_gitops_sync: request_count * counters[:gitops_sync],

View File

@ -14,7 +14,7 @@ RSpec.describe Environments::CreateService, feature_category: :environment_manag
describe '#execute' do
subject { service.execute }
let(:params) { { name: 'production', external_url: 'https://gitlab.com', tier: :production } }
let(:params) { { name: 'production', external_url: 'https://gitlab.com', tier: :production, kubernetes_namespace: 'default' } }
it 'creates an environment' do
expect { subject }.to change { ::Environment.count }.by(1)
@ -27,6 +27,7 @@ RSpec.describe Environments::CreateService, feature_category: :environment_manag
expect(response.payload[:environment].name).to eq('production')
expect(response.payload[:environment].external_url).to eq('https://gitlab.com')
expect(response.payload[:environment].tier).to eq('production')
expect(response.payload[:environment].kubernetes_namespace).to eq('default')
end
context 'with a cluster agent' do

View File

@ -28,6 +28,21 @@ RSpec.describe Environments::UpdateService, feature_category: :environment_manag
expect(response.payload[:environment]).to eq(environment)
end
context 'when setting a kubernetes namespace to the environment' do
let(:params) { { kubernetes_namespace: 'default' } }
it 'updates the kubernetes namespace' do
expect { subject }.to change { environment.reload.kubernetes_namespace }.to('default')
end
it 'returns successful response' do
response = subject
expect(response).to be_success
expect(response.payload[:environment]).to eq(environment)
end
end
context 'when setting a cluster agent to the environment' do
let_it_be(:agent_management_project) { create(:project) }
let_it_be(:cluster_agent) { create(:cluster_agent, project: agent_management_project) }

View File

@ -436,7 +436,7 @@ RSpec.configure do |config|
Gitlab::SidekiqMiddleware.server_configurator(
metrics: false, # The metrics don't go anywhere in tests
arguments_logger: false, # We're not logging the regular messages for inline jobs
defer_jobs: false # We're not deferring jobs for inline tests
skip_jobs: false # We're not skipping jobs for inline tests
).call(chain)
chain.add DisableQueryLimit
chain.insert_after ::Gitlab::SidekiqMiddleware::RequestStoreMiddleware, IsolatedRequestStore

View File

@ -74,6 +74,13 @@ RSpec.shared_context 'structured_logger' do
)
end
let(:dropped_payload) do
end_payload.merge(
'message' => 'TestWorker JID-da883554ee4fe414012f5f42: dropped: 0.0 sec',
'job_status' => 'dropped'
)
end
let(:exception_payload) do
end_payload.merge(
'message' => 'TestWorker JID-da883554ee4fe414012f5f42: fail: 0.0 sec',

View File

@ -105,26 +105,10 @@ RSpec.describe 'projects/edit' do
end
describe 'pages menu entry callout' do
context 'with feature flag disabled' do
before do
stub_feature_flags(show_pages_in_deployments_menu: false)
end
it 'does show a callout' do
render
it 'does not show a callout' do
render
expect(rendered).not_to have_content('GitLab Pages has moved')
end
end
context 'with feature flag enabled' do
before do
stub_feature_flags(show_pages_in_deployments_menu: true)
end
it 'does show a callout' do
render
expect(rendered).to have_content('GitLab Pages has moved')
end
expect(rendered).to have_content(_('GitLab Pages has moved'))
end
end
end