Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-08-20 18:08:20 +00:00
parent 238494601c
commit fdcecabb65
130 changed files with 1084 additions and 634 deletions

View File

@ -127,8 +127,8 @@ rules:
- selector: TemplateLiteral[expressions.0.name=DOCS_URL] > TemplateElement[value.cooked=/\u002Fjh|\u002Fee/]
message: '`/ee` or `/jh` path found in docs url, use `DOCS_URL_IN_EE_DIR` in `jh_else_ce/lib/utils/url_utility`'
# This can be removed once GitLab is on Vue 3
- selector: MemberExpression[object.type='ThisExpression'][property.name='$delete']
message: "$delete is not supported in Vue 3"
- selector: MemberExpression[object.type='ThisExpression'][property.name=/(\$delete|\$set)/]
message: "Vue 2's set/delete methods are not available in Vue 3. Create/assign new objects with the desired properties instead."
no-restricted-properties:
- error
- object: window
@ -137,11 +137,19 @@ rules:
# This can be removed once GitLab is on Vue 3
- object: vm
property: $delete
message: '$delete is not supported in Vue 3'
message: "Vue 2's set/delete methods are not available in Vue 3. Create/assign new objects with the desired properties instead."
# This can be removed once GitLab is on Vue 3
- object: Vue
property: delete
message: 'delete is not supported in Vue 3'
message: "Vue 2's set/delete methods are not available in Vue 3. Create/assign new objects with the desired properties instead."
# This can be removed once GitLab is on Vue 3
- object: vm
property: $set
message: "Vue 2's set/delete methods are not available in Vue 3. Create/assign new objects with the desired properties instead."
# This can be removed once GitLab is on Vue 3
- object: Vue
property: set
message: "Vue 2's set/delete methods are not available in Vue 3. Create/assign new objects with the desired properties instead."
no-restricted-imports:
- error
- paths:
@ -208,14 +216,18 @@ overrides:
- selector: TemplateLiteral[expressions.0.name=DOCS_URL] > TemplateElement[value.cooked=/\u002Fjh|\u002Fee/]
message: '`/ee` or `/jh` path found in docs url, use `DOCS_URL_IN_EE_DIR` in `jh_else_ce/lib/utils/url_utility`'
# This can be removed once GitLab is on Vue 3
- selector: CallExpression[callee.property.name="$delete"]
message: "$delete is restricted from being used. $delete is not supported in Vue 3"
- selector: CallExpression[callee.property.name=/(\$delete|\$set)/]
message: "Vue 2's set/delete methods are not available in Vue 3. Create/assign new objects with the desired properties instead."
no-restricted-properties:
- error
# This can be removed once GitLab is on Vue 3
- object: Vue
property: delete
message: 'delete is not supported in Vue 3'
message: "Vue 2's set/delete methods are not available in Vue 3. Create/assign new objects with the desired properties instead."
# This can be removed once GitLab is on Vue 3
- object: Vue
property: set
message: "Vue 2's set/delete methods are not available in Vue 3. Create/assign new objects with the desired properties instead."
no-unsanitized/method: off
no-unsanitized/property: off
local-rules/require-valid-help-page-path: off

View File

@ -433,18 +433,20 @@ export default class MergeRequestTabs {
setCurrentAction(action) {
this.currentAction = action;
const pathname = location.pathname.replace(/\/*$/, '');
// Remove a trailing '/commits' '/diffs' '/pipelines'
let newState = location.pathname.replace(this.actionRegex, '');
let newStatePathname = pathname.replace(this.actionRegex, '');
// Append the new action if we're on a tab other than 'notes'
if (this.currentAction !== 'show' && this.currentAction !== 'new') {
newState += `/${this.currentAction}`;
newStatePathname += `/${this.currentAction}`;
}
// Ensure parameters and hash come along for the ride
newState += location.search + location.hash;
const newState = newStatePathname + location.search + location.hash;
if (window.location.pathname !== newState) {
if (pathname !== newStatePathname) {
window.history.pushState(
{
url: newState,

View File

@ -14,6 +14,7 @@ class Email < ApplicationRecord
scope :unconfirmed, -> { where(confirmed_at: nil) }
scope :unconfirmed_and_created_before, ->(created_cut_off) { unconfirmed.where('created_at < ?', created_cut_off) }
before_save :detumble_email!, if: ->(email) { email.email_changed? }
after_commit :update_invalid_gpg_signatures, if: -> { previous_changes.key?('confirmed_at') }
devise :confirmable
@ -49,4 +50,10 @@ class Email < ApplicationRecord
def primary_email_of_another_user?
User.where(email: email).where.not(id: user_id).exists?
end
def detumble_email!
return unless Feature.enabled?(:store_detumbled_email, user, type: :gitlab_com_derisk)
self.detumbled_email = ::Gitlab::Utils::Email.normalize_email(email)
end
end

View File

@ -4,7 +4,7 @@
.form-group
.col-sm-2.col-form-label
= f.label :create_chat_team do
%span.gl-display-flex
%span.gl-flex
= custom_icon('icon_mattermost')
%span.gl-ml-2= _('Mattermost')
.col-sm-12

View File

@ -4,8 +4,8 @@
.group-home-panel
.gl-flex.gl-justify-between.gl-flex-wrap.gl-flex-col.sm:gl-flex-row.gl-gap-3.gl-my-5
.home-panel-title-row.gl-display-flex
= render Pajamas::AvatarComponent.new(@group, alt: @group.name, size: 48, class: 'float-none gl-align-self-start gl-flex-shrink-0 gl-mr-3', avatar_options: { itemprop: 'logo' })
.home-panel-title-row.gl-flex
= render Pajamas::AvatarComponent.new(@group, alt: @group.name, size: 48, class: 'float-none gl-self-start gl-shrink-0 gl-mr-3', avatar_options: { itemprop: 'logo' })
%h1.home-panel-title.gl-heading-1.gl-flex.gl-items-center.gl-flex-wrap.gl-gap-3.gl-break-anywhere.gl-mb-0{ itemprop: 'name' }
= @group.name
%span.visibility-icon.gl-text-subtle.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@group) }
@ -20,12 +20,12 @@
.js-vue-notification-dropdown{ data: { disabled: emails_disabled.to_s, dropdown_items: notification_dropdown_items(@notification_setting).to_json, notification_level: @notification_setting.level, help_page_path: help_page_path('user/profile/notifications'), group_id: @group.id, container_class: 'gl-align-top' } }
- if can_create_subgroups
.sm:gl-w-auto.gl-w-full
= render Pajamas::ButtonComponent.new(href: new_group_path(parent_id: @group.id, anchor: 'create-group-pane'), button_options: { data: { testid: 'new-subgroup-button' }, class: 'gl-sm-w-auto gl-w-full'}) do
= render Pajamas::ButtonComponent.new(href: new_group_path(parent_id: @group.id, anchor: 'create-group-pane'), button_options: { data: { testid: 'new-subgroup-button' }, class: 'sm:gl-w-auto gl-w-full'}) do
= _("New subgroup")
- if can_create_projects
.sm:gl-w-auto.gl-w-full
= render Pajamas::ButtonComponent.new(href: new_project_path(namespace_id: @group.id), variant: :confirm, button_options: { data: { testid: 'new-project-button' }, class: 'gl-sm-w-auto gl-w-full' }) do
= render Pajamas::ButtonComponent.new(href: new_project_path(namespace_id: @group.id), variant: :confirm, button_options: { data: { testid: 'new-project-button' }, class: 'sm:gl-w-auto gl-w-full' }) do
= _('New project')
= render 'groups/more_actions_dropdown', source: @group

View File

@ -13,10 +13,10 @@
.row
.form-group.col-sm-4
= f.label :setup_for_company, _('Who will be using this group?')
.gl-display-flex.gl-flex-direction-column.gl-lg-flex-direction-row
.gl-flex-grow-1.gl-display-flex.gl-align-items-center
.gl-flex.gl-flex-col.lg:gl-flex-row
.gl-grow.gl-flex.gl-items-center
= f.gitlab_ui_radio_component :setup_for_company, true, _('My company or team')
.gl-flex-grow-1.gl-display-flex.gl-align-items-center
.gl-grow.gl-flex.gl-items-center
= f.gitlab_ui_radio_component :setup_for_company, false, _('Just me')
.row

View File

@ -3,7 +3,7 @@
.row.gl-mt-3
.col-lg-12
.gl-display-flex.gl-flex-wrap.gl-justify-content-space-between
.gl-flex.gl-flex-wrap.gl-justify-between
- if can_admin_group_member?(@group)
%h4
= _('Group members')
@ -13,12 +13,12 @@
- if current_appearance&.member_guidelines?
.gl-w-full.order-md-1
= brand_member_guidelines
.gl-display-flex.gl-flex-wrap.gl-align-items-center.gl-gap-3.gl-md-w-auto.gl-w-full
.js-invite-group-trigger{ data: { classes: 'gl-md-w-auto gl-w-full', display_text: _('Invite a group') } }
.gl-flex.gl-flex-wrap.gl-items-center.gl-gap-3.md:gl-w-auto.gl-w-full
.js-invite-group-trigger{ data: { classes: 'md:gl-w-auto gl-w-full', display_text: _('Invite a group') } }
- if can_admin_service_accounts?(@group)
= render_if_exists 'groups/group_members/create_service_account'
.js-invite-members-trigger{ data: { variant: 'confirm',
classes: 'gl-md-w-auto gl-w-full',
classes: 'md:gl-w-auto gl-w-full',
trigger_source: 'group_members_page',
display_text: _('Invite members') } }
= render 'groups/invite_groups_modal', group: @group, reload_page_on_submit: true

View File

@ -3,7 +3,7 @@
- page_title _("Edit"), @label.name, _("Labels")
- show_lock_on_merge = @group.supports_lock_on_merge?
%h1.page-title.gl-font-size-h-display
%h1.page-title.gl-text-size-h-display
= _('Edit label')
= render 'shared/labels/form', url: group_label_path(@group, @label), back_path: @previous_labels_path, show_lock_on_merge: show_lock_on_merge

View File

@ -2,7 +2,7 @@
- breadcrumb_title _("New label")
- page_title _("New Label")
%h1.page-title.gl-font-size-h-display
%h1.page-title.gl-text-size-h-display
= _('New Label')
= render 'shared/labels/form', url: group_labels_path, back_path: @previous_labels_path

View File

@ -3,7 +3,7 @@
- render "header_title"
%h1.page-title.gl-font-size-h-display
%h1.page-title.gl-text-size-h-display
= _('Edit milestone')
= render "form"

View File

@ -2,7 +2,7 @@
- breadcrumb_title _("New milestone")
- page_title _("Milestones"), @milestone.name, _("Milestones")
%h1.page-title.gl-font-size-h-display
%h1.page-title.gl-text-size-h-display
= _("New Milestone")
.gl-mt-3

View File

@ -14,9 +14,9 @@
- c.with_body do
%ul.content-list
- @projects.each do |project|
%li.project-row.gl-align-items-center{ class: 'gl-display-flex!' }
= render Pajamas::AvatarComponent.new(project, alt: project.name, size: 48, class: 'gl-flex-shrink-0 gl-mr-5')
.gl-min-w-0.gl-flex-grow-1
%li.project-row.gl-items-center{ class: '!gl-flex' }
= render Pajamas::AvatarComponent.new(project, alt: project.name, size: 48, class: 'gl-shrink-0 gl-mr-5')
.gl-min-w-0.gl-grow
.title.gl-mr-5
= link_to project_path(project), class: 'js-prefetch-document' do
%span.project-full-name
@ -34,9 +34,9 @@
= render 'shared/projects/badges', project: project, css_class: 'gl-mr-3'
.stats.gl-text-secondary.gl-flex-shrink-0.gl-hidden.sm:gl-flex.gl-gap-3
.stats.gl-text-secondary.gl-shrink-0.gl-hidden.sm:gl-flex.gl-gap-3
= gl_badge_tag storage_counter(project.statistics&.storage_size)
.controls.gl-flex-shrink-0.gl-ml-5
.controls.gl-shrink-0.gl-ml-5
= render Pajamas::ButtonComponent.new(href: project_project_members_path(project),
variant: :link,
button_options: { class: 'gl-mr-2' }) do

View File

@ -6,7 +6,7 @@
- if show_invite_banner?(@group)
= content_for :group_invite_members_banner do
.container-fluid.container-limited{ class: "gl-pb-2! gl-pt-6! #{@content_class}" }
.container-fluid.container-limited{ class: "!gl-pb-2 !gl-pt-6 #{@content_class}" }
.js-group-invite-members-banner{ data: { svg_path: image_path('illustrations/add-user-sm.svg'),
track_label: 'invite_members_banner',
invite_members_path: group_group_members_path(@group),

View File

@ -38,7 +38,7 @@
.card-header
= _('Quick help')
%ul.content-list
%li= link_to _('See our website for help'), support_url, { class: 'gl-text-blue-600!' }
%li= link_to _('See our website for help'), support_url, { class: '!gl-text-blue-600' }
%li
%button.btn-blank.btn-link.gl-button.js-trigger-search-bar{ type: 'button' }
= _('Use the search bar on the top of this page')
@ -46,5 +46,5 @@
%button.btn-blank.btn-link.gl-button.js-trigger-shortcut{ type: 'button' }
= _('Use shortcuts')
- unless Gitlab::CurrentSettings.help_page_hide_commercial_content?
%li= link_to _('Get a support subscription'), "#{ApplicationHelper.promo_url}/pricing/", { class: 'gl-text-blue-600!' }
%li= link_to _('Compare GitLab editions'), "#{ApplicationHelper.promo_url}/features/#compare", { class: 'gl-text-blue-600!' }
%li= link_to _('Get a support subscription'), "#{ApplicationHelper.promo_url}/pricing/", { class: '!gl-text-blue-600' }
%li= link_to _('Compare GitLab editions'), "#{ApplicationHelper.promo_url}/features/#compare", { class: '!gl-text-blue-600' }

View File

@ -1,5 +1,5 @@
- page_title _('Instance Configuration')
.md.gl-font-lg.gl-mt-3
.md.gl-text-lg.gl-mt-3
%h1= _('Instance Configuration')
%p

View File

@ -1,5 +1,5 @@
- page_title @path.split("/").reverse.map(&:humanize)
- @content_class = "limit-container-width" unless fluid_layout
.md.gl-font-lg.gl-mt-3
.md.gl-text-lg.gl-mt-3
= markdown @markdown

View File

@ -1,8 +1,8 @@
- page_title _('Bitbucket import')
- header_title _('Projects'), root_path
%h1.page-title.gl-font-size-h-display.gl-flex.gl-items-center
.gl-flex.gl-items-center.gl-justify-content-center
%h1.page-title.gl-text-size-h-display.gl-flex.gl-items-center
.gl-flex.gl-items-center.gl-justify-center
= sprite_icon('bitbucket', css_class: 'gl-mr-3', size: 48)
= _('Import projects from Bitbucket')

View File

@ -2,8 +2,8 @@
- header_title _("New project"), new_project_path
- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project')
%h1.page-title.gl-font-size-h-display.gl-flex.gl-items-center
.gl-flex.gl-items-center.gl-justify-content-center
%h1.page-title.gl-text-size-h-display.gl-flex.gl-items-center
.gl-flex.gl-items-center.gl-justify-center
= sprite_icon('bitbucket', css_class: 'gl-mr-3', size: 48)
= _('Import repositories from Bitbucket Server')
%hr

View File

@ -1,7 +1,7 @@
- page_title _('Bitbucket Server import')
%h1.page-title.gl-font-size-h-display.gl-flex.gl-items-center
.gl-flex.gl-items-center.gl-justify-content-center
%h1.page-title.gl-text-size-h-display.gl-flex.gl-items-center
.gl-flex.gl-items-center.gl-justify-center
= sprite_icon('bitbucket', css_class: 'gl-mr-3', size: 48)
= _('Import projects from Bitbucket Server')

View File

@ -2,8 +2,8 @@
- header_title _("New project"), new_project_path
- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project')
%h1.page-title.gl-font-size-h-display.gl-flex.gl-items-center
.gl-flex.gl-items-center.gl-justify-content-center
%h1.page-title.gl-text-size-h-display.gl-flex.gl-items-center
.gl-flex.gl-items-center.gl-justify-center
= sprite_icon('bug', css_class: 'gl-mr-3', size: 48)
= _('Import projects from FogBugz')
%hr

View File

@ -2,8 +2,8 @@
- header_title _("New project"), new_project_path
- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project')
%h1.page-title.gl-font-size-h-display.gl-flex
.gl-flex.gl-items-center.gl-justify-content-center
%h1.page-title.gl-text-size-h-display.gl-flex
.gl-flex.gl-items-center.gl-justify-center
= sprite_icon('bug', css_class: 'gl-mr-2')
= _('Import projects from FogBugz')
%hr

View File

@ -1,6 +1,6 @@
- page_title _("FogBugz import")
%h1.page-title.gl-font-size-h-display.gl-flex.gl-items-center
.gl-flex.gl-items-center.gl-justify-content-center
%h1.page-title.gl-text-size-h-display.gl-flex.gl-items-center
.gl-flex.gl-items-center.gl-justify-center
= sprite_icon('bug', css_class: 'gl-mr-3', size: 48)
= _('Import projects from FogBugz')

View File

@ -2,8 +2,8 @@
- header_title _("New project"), new_project_path
- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project')
%h1.page-title.gl-font-size-h-display.gl-flex.gl-items-center
.gl-flex.gl-items-center.gl-justify-content-center
%h1.page-title.gl-text-size-h-display.gl-flex.gl-items-center
.gl-flex.gl-items-center.gl-justify-center
= sprite_icon('gitea', css_class: 'gl-mr-3', size: 48)
= _('Import projects from Gitea')
%hr

View File

@ -1,6 +1,6 @@
- page_title _("Gitea import")
%h1.page-title.gl-font-size-h-display.gl-flex.gl-items-center
.gl-flex.gl-items-center.gl-justify-content-center
%h1.page-title.gl-text-size-h-display.gl-flex.gl-items-center
.gl-flex.gl-items-center.gl-justify-center
= sprite_icon('gitea', css_class: 'gl-mr-3', size: 48)
= _('Import projects from Gitea')

View File

@ -4,7 +4,7 @@
- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project')
.gl-border-solid.gl-border-gray-100.gl-border-0.gl-border-b-1
%h1.gl-font-size-h1.gl-my-0.gl-py-4.gl-display-flex.gl-align-items-center.gl-gap-3
%h1.gl-text-size-h1.gl-my-0.gl-py-4.gl-flex.gl-items-center.gl-gap-3
= sprite_icon('github', size: 24)
%span= title
@ -46,7 +46,7 @@
- docs_link_tag_pair = tag_pair(docs_link, :link_start, :link_end)
= safe_format(s_('GithubImport|%{link_start}Learn more%{link_end}.'), docs_link_tag_pair)
.form-actions.gl-display-flex.gl-justify-content-end
.form-actions.gl-flex.gl-justify-end
= render Pajamas::ButtonComponent.new(href: new_project_path) do
= _('Cancel')
= render Pajamas::ButtonComponent.new(variant: :confirm, type: :submit, button_options: { class: 'gl-ml-3', data: { testid: 'authenticate-button' } }) do

View File

@ -2,7 +2,7 @@
- page_title title
.gl-border-solid.gl-border-gray-100.gl-border-0.gl-border-b-1
%h1.gl-font-size-h1.gl-my-0.gl-py-4.gl-display-flex.gl-align-items-center.gl-gap-3
%h1.gl-text-size-h1.gl-my-0.gl-py-4.gl-flex.gl-items-center.gl-gap-3
= sprite_icon('github', size: 24)
%span= _('Import repositories from GitHub')

View File

@ -1,5 +1,5 @@
- page_title _("GitLab.com import")
%h1.page-title.gl-font-size-h-display
%h1.page-title.gl-text-size-h-display
= sprite_icon('heart', css_class: 'gl-align-middle')
= _('Import projects from GitLab.com')

View File

@ -2,8 +2,8 @@
- header_title _("New project"), new_project_path
- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project')
%h1.page-title.gl-font-size-h-display.gl-flex.gl-items-center
.gl-flex.gl-items-center.gl-justify-content-center
%h1.page-title.gl-text-size-h-display.gl-flex.gl-items-center
.gl-flex.gl-items-center.gl-justify-center
= sprite_icon('tanuki', css_class: 'gl-mr-3', size: 48)
= _('Import an exported GitLab project')
%hr

View File

@ -3,7 +3,7 @@
- add_to_breadcrumbs s_('ProjectsNew|Import project'), new_project_path(anchor: 'import_project')
%h1.page-title.gl-font-size-h-display
%h1.page-title.gl-text-size-h-display
= _('Manifest file import')
= render 'import/shared/errors'

View File

@ -1,6 +1,6 @@
- page_title _("Manifest import")
%h1.page-title.gl-font-size-h-display
%h1.page-title.gl-text-size-h-display
= _('Manifest file import')
= render 'import/githubish_status', provider: 'manifest'

View File

@ -2,6 +2,6 @@
- text_only = local_assigns.fetch(:text_only, false)
- if text_only
%span.has-tooltip.gl-leading-normal.gl-font-sm{ title: tooltip_title }= _('Imported')
%span.has-tooltip.gl-leading-normal.gl-text-sm{ title: tooltip_title }= _('Imported')
- else
= render Pajamas::BadgeComponent.new(_('Imported'), title: tooltip_title, class: 'has-tooltip')

View File

@ -18,7 +18,7 @@
.input-group-text.border-0
#{user_url(current_user.username)}/
= hidden_field_tag :namespace_id, current_user.namespace_id
.gl-align-self-center.gl-pl-5 /
.gl-self-center.gl-pl-5 /
.form-group.col-12.col-sm-6.project-path
= label_tag :path, _('Project slug'), class: 'label-bold'
= text_field_tag :path, @path, placeholder: "my-awesome-project", class: "js-path-name form-control gl-form-input", required: true, aria: { required: true }

View File

@ -1,8 +1,8 @@
- page_title _('Invitation declined')
.col-md-7.gl-display-flex.gl-flex-direction-column.gl-mx-auto.gl-w-full.gl-sm-w-auto
.gl-align-self-center.gl-mb-4.gl-mt-7.gl-sm-mt-0= sprite_icon('check-circle', size: 48, css_class: 'gl-text-green-400')
%h2.gl-font-size-h2= _('You successfully declined the invitation')
.col-md-7.gl-flex.gl-flex-col.gl-mx-auto.gl-w-full.sm:gl-w-auto
.gl-self-center.gl-mb-4.gl-mt-7.sm:gl-mt-0= sprite_icon('check-circle', size: 48, css_class: 'gl-text-green-400')
%h2.gl-text-size-h2= _('You successfully declined the invitation')
%p
= html_escape(_('We will notify %{inviter} that you declined their invitation to join GitLab. You will stop receiving reminders.')) % { inviter: sanitize_name(@member.created_by.name) }
%p

View File

@ -1,5 +1,5 @@
- page_title _("Invitation")
%h1.page-title.gl-font-size-h-display= _("Invitation")
%h1.page-title.gl-text-size-h-display= _("Invitation")
- if current_user_matches_invite?
- if member?

View File

@ -8,15 +8,15 @@
= header_message
= render "layouts/init_client_detection_flags"
= yield :sessions_broadcast
.gl-h-full.gl-display-flex.gl-flex-wrap
.container.gl-align-self-center
.gl-h-full.gl-flex.gl-flex-wrap
.container.gl-self-center
.content
= render "layouts/flash"
- if custom_text.present?
.row.gl-mt-5.gl-gap-y-5
.col-md.order-12.sm-bg-gray
.col-sm-12
%h1.gl-mb-5.gl-font-size-h2
%h1.gl-mb-5.gl-text-size-h2
= brand_title
#js-custom-sign-in-description= custom_text
.col-md.order-md-12
@ -28,9 +28,9 @@
.gl-my-5
.col-sm-12.gl-text-center
= brand_image
%h1.mb-3.gl-font-size-h2
%h1.mb-3.gl-text-size-h2
= brand_title
.gl-w-full.gl-sm-w-half.gl-ml-auto.gl-mr-auto.bar
.gl-w-full.gl-ml-auto.gl-mr-auto.bar{ class: 'sm:gl-w-1/2' }
= yield
= render 'devise/shared/footer'

View File

@ -9,8 +9,8 @@
= header_message
= render "layouts/init_client_detection_flags"
= render "layouts/header/empty"
.gl-h-full.gl-display-flex.gl-flex-wrap
.container.gl-align-self-center
.gl-h-full.gl-flex.gl-flex-wrap
.container.gl-self-center
.content
= render "layouts/flash"
= yield

View File

@ -5,7 +5,7 @@
= render 'peek/bar'
= header_message
.gl--flex-full.gl-h-full
.gl--flex-full.gl-flex-direction-column.gl-w-full
.gl--flex-full.gl-flex-col.gl-w-full
.alert-wrapper
= render 'shared/outdated_browser'
= render "layouts/broadcast"

View File

@ -1,8 +1,8 @@
%header.header-logged-out{ data: { testid: 'navbar' } }
%a.gl-sr-only.gl-accessibility{ href: "#content-body" } Skip to content
.container-fluid
%nav.header-logged-out-nav.gl-display-flex.gl-gap-3.gl-justify-content-space-between{ 'aria-label': s_('LoggedOutMarketingHeader|Explore GitLab') }
.gl-display-flex.gl-align-items-center.gl-gap-1
%nav.header-logged-out-nav.gl-flex.gl-gap-3.gl-justify-between{ 'aria-label': s_('LoggedOutMarketingHeader|Explore GitLab') }
.gl-flex.gl-items-center.gl-gap-1
%span.gl-sr-only GitLab
= link_to root_path, title: _('Homepage'), id: 'logo', class: 'header-logged-out-logo has-tooltip', aria: { label: _('Homepage') }, **tracking_attrs('main_navigation', 'click_gitlab_logo_link', 'navigation_top') do
= brand_header_logo
@ -10,7 +10,7 @@
= gl_badge_tag({ variant: :success }, { href: Gitlab::Saas.canary_toggle_com_url, data: { testid: 'canary_badge_link' }, target: :_blank, rel: 'noopener noreferrer', class: 'canary-badge' }) do
= s_('GitLab Next|Next')
%ul.gl-list-none.gl-p-0.gl-m-0.gl-display-flex.gl-gap-3.gl-align-items-center.gl-flex-grow-1
%ul.gl-list-none.gl-p-0.gl-m-0.gl-flex.gl-gap-3.gl-items-center.gl-grow
- if Gitlab.com?
%li.header-logged-out-nav-item.header-logged-out-dropdown.md:gl-hidden
%button.header-logged-out-toggle{ type: "button", data: { toggle: "dropdown" } }
@ -43,7 +43,7 @@
= link_to _("Explore"), explore_root_path, class: ''
- if header_link?(:sign_in)
%ul.gl-list-none.gl-p-0.gl-m-0.gl-display-flex.gl-gap-3.gl-align-items-center.gl-justify-content-end
%ul.gl-list-none.gl-p-0.gl-m-0.gl-flex.gl-gap-3.gl-items-center.gl-justify-end
%li.header-logged-out-nav-item
= link_to _('Sign in'), new_session_path(:user, redirect_to_referer: 'yes')
- if allow_signup?

View File

@ -10,8 +10,8 @@
= render 'peek/bar'
= render 'layouts/published_experiments'
= render "layouts/header/empty"
.layout-page.gl-h-full.borderless.gl-display-flex.gl-flex-wrap
.content-wrapper.gl-pt-6{ class: 'gl-md-pt-11!' }
.layout-page.gl-h-full.borderless.gl-flex.gl-flex-wrap
.content-wrapper.gl-pt-6{ class: 'md:!gl-pt-11' }
%div{ class: container_class }
%main#content-body.content
= render "layouts/flash" unless @hide_flash

View File

@ -1,5 +1,5 @@
%div{ class: 'top-bar-fixed container-fluid', data: { testid: 'top-bar' } }
.top-bar-container.gl-display-flex.gl-align-items-center.gl-gap-2
.top-bar-container.gl-flex.gl-items-center.gl-gap-2
= render Pajamas::ButtonComponent.new(icon: 'sidebar', category: :tertiary, button_options: { class: 'js-super-sidebar-toggle-expand super-sidebar-toggle -gl-ml-3', aria: { controls: 'super-sidebar', expanded: 'false', label: _('Primary navigation sidebar') } })
= render "layouts/nav/breadcrumbs/breadcrumbs"
= render "layouts/nav/work_items/feedback_badge"

View File

@ -1,5 +1,5 @@
- page_title _("Activity")
%h1.page-title.gl-font-size-h-display
%h1.page-title.gl-text-size-h-display
= _("Activity")
#js-organizations-activity{ data: { app_data: organization_activity_app_data(@organization) } }

View File

@ -2,7 +2,7 @@
%label.label-bold.gl-mb-0
= s_('Profiles|Connected Accounts')
%p.gl-text-secondary= s_('Profiles|Select a service to sign in with.')
.gl-display-flex.gl-flex-wrap.gl-gap-3
.gl-flex.gl-flex-wrap.gl-gap-3
- providers.each do |provider|
- unlink_allowed = unlink_provider_allowed?(provider)
- link_allowed = link_provider_allowed?(provider)

View File

@ -8,7 +8,7 @@
%h4.gl-my-0
= page_title
%h5.gl-font-lg.gl-mt-0
%h5.gl-text-lg.gl-mt-0
= sprintf(_('Active chat names (%{count})'), { count: @chat_names.size })
- if @chat_names.present?

View File

@ -17,7 +17,7 @@
%p.gl-mb-0
= s_("SlackIntegration|You don't have to reauthorize this application if the permission scope changes in future releases.")
- c.with_footer do
.gl-display-flex
.gl-flex
= form_tag profile_chat_names_path, method: :post do
= hidden_field_tag :token, @chat_name_token.token
= render Pajamas::ButtonComponent.new(type: :submit, variant: :danger, button_options: { data: { testid: 'authorize-button' } }) do

View File

@ -1,6 +1,6 @@
- page_title _('Emails')
- profile_message = _('Used for avatar detection. You can change it in your %{openingTag}profile settings%{closingTag}.') % { openingTag: "<a href='#{user_settings_profile_path}' class='gl-text-blue-500!'>".html_safe, closingTag: '</a>'.html_safe}
- notification_message = _('Used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set.') % { openingTag: "<a href='#{profile_notifications_path}' class='gl-text-blue-500!'>".html_safe, closingTag: '</a>'.html_safe}
- profile_message = _('Used for avatar detection. You can change it in your %{openingTag}profile settings%{closingTag}.') % { openingTag: "<a href='#{user_settings_profile_path}' class='!gl-text-blue-500'>".html_safe, closingTag: '</a>'.html_safe}
- notification_message = _('Used for account notifications if a %{openingTag}group-specific email address%{closingTag} is not set.') % { openingTag: "<a href='#{profile_notifications_path}' class='!gl-text-blue-500'>".html_safe, closingTag: '</a>'.html_safe}
- public_email_message = _('Your public email will be displayed on your public profile.')
- commit_email_message = _('Used for web based operations, such as edits and merges.')
- @force_desktop_expanded_sidebar = true
@ -47,7 +47,7 @@
= s_('Profiles|Default notification email')
.gl-text-subtle.gl-text-sm= notification_message.html_safe
- @emails.reject(&:user_primary_email?).each do |email|
%li{ class: 'gl-px-5!', data: { testid: 'email-row-content' } }
%li{ class: '!gl-px-5', data: { testid: 'email-row-content' } }
.gl-flex.gl-justify-between.gl-flex-wrap.gl-gap-3
- unless email.confirmed?
= render Pajamas::AlertComponent.new(dismissible: false, variant: :warning, alert_options: { class: 'gl-w-full' }) do |c|

View File

@ -29,7 +29,7 @@
- else
.gl-relative
- if local_assigns[:protected_from_deletion]
%span.gl-absolute.gl-display-inline-block.gl-w-full.gl-h-full{ data: { container: 'body', toggle: 'popover', placement: local_assigns[:placemet], html: 'true', triggers: 'hover', content: local_assigns[:popover_content] } }
%span.gl-absolute.gl-inline-block.gl-w-full.gl-h-full{ data: { container: 'body', toggle: 'popover', placement: local_assigns[:placemet], html: 'true', triggers: 'hover', content: local_assigns[:popover_content] } }
= render Pajamas::ButtonComponent.new(size: :small,
variant: :danger,
href: [protected_branch_entity, protected_branch, { update_section: 'js-protected-branches-settings' }],

View File

@ -1,3 +1,3 @@
.gl-w-full.gl-flex-grow-1
.gl-w-full.gl-grow
= render partial: 'search/results_status'
= render partial: 'search/results_list'

View File

@ -1,4 +1,4 @@
.search-results-status.sm:gl-flex.gl-items-start.gl-justify-content-space-between.gl-my-4{ class: ('lg:gl-hidden' if @search_objects.to_a.empty?) }
.search-results-status.sm:gl-flex.gl-items-start.gl-justify-between.gl-my-4{ class: ('lg:gl-hidden' if @search_objects.to_a.empty?) }
- unless @search_objects.to_a.empty?
%div
- unless @search_service_presenter.without_count?
@ -8,7 +8,7 @@
- link_to_project = link_to(@project.full_name, @project, class: 'search-wrap-f-md-down')
- if @scope == 'blobs'
%span= _("in")
.gl-display-inline-block
.gl-inline-block
#js-blob-ref-switcher{ data: { "project-id" => @project.id, "ref" => repository_ref(@project), "field-name": "repository_ref" } }
%span= safe_format(s_('SearchCodeResults|of %{link_to_project}'), link_to_project: link_to_project)
- else
@ -16,8 +16,8 @@
- elsif @group
- link_to_group = link_to(@group.name, @group, class: 'ml-md-1')
= safe_format(_("in group %{link_to_group}"), link_to_group: link_to_group)
.gl-flex.gl-gap-3.gl-mt-3.gl-sm-mt-0
= render Pajamas::ButtonComponent.new(category: 'primary', icon: 'filter', button_options: {id: 'js-open-mobile-filters', class: 'lg:gl-hidden gl-flex-grow-1 gl-md-flex-grow-0'}) do
.gl-flex.gl-gap-3.gl-mt-3.sm:gl-mt-0
= render Pajamas::ButtonComponent.new(category: 'primary', icon: 'filter', button_options: {id: 'js-open-mobile-filters', class: 'lg:gl-hidden gl-grow md:gl-grow-0'}) do
= s_('GlobalSearch|Filters')
- if @search_service_presenter.show_sort_dropdown? && !@search_objects.to_a.empty?
#js-search-sort{ data: { "search-sort-options" => search_sort_options.to_json }, class: "gl-flex-grow-1 gl-md-flex-grow-0" }
#js-search-sort{ data: { "search-sort-options" => search_sort_options.to_json }, class: "gl-grow md:gl-grow-0" }

View File

@ -13,6 +13,6 @@
- else
.file-content.code
.nothing-here-block
.gl-text-gray-600.gl-font-sm
.gl-text-gray-600.gl-text-sm
- max_file_size_indexed = Gitlab::CurrentSettings.elasticsearch_indexed_file_size_limit_kb.kilobytes
= _('The file could not be displayed because it is empty or larger than the maximum file size indexed (%{size}).') % { size: number_to_human_size(max_file_size_indexed) }

View File

@ -7,9 +7,9 @@
- blob_highlight = blob.present.highlight_and_trim(trim_length: 1024, ellipsis_svg: sprite_icon('ellipsis_h', size: 12, css_class: "gl-text-gray-700"))
- blob_highlight.lines.each_with_index do |line, index|
- i = index + offset
.line_holder.code-search-line.gl-display-flex
.line_holder.code-search-line.gl-flex
.line-numbers
.gl-display-flex
.gl-flex
%span.diff-line-num.gl-pl-3
%a.has-tooltip{ href: "#{blame_link}#L#{i}",
id: "blame-L#{i}",
@ -20,7 +20,7 @@
title: _('View blame') }
= sprite_icon('git')
%span.diff-line-num.flex-grow-1.gl-pr-3
%a{ href: "#{blob_link}#L#{i}", id: "blob-L#{i}", 'data-line-number' => i, class: 'gl-display-flex! gl-align-items-center gl-justify-content-end' }
%a{ href: "#{blob_link}#L#{i}", id: "blob-L#{i}", 'data-line-number' => i, class: '!gl-flex gl-items-center gl-justify-end' }
= i
%pre.code.highlight.flex-grow-1
%code

View File

@ -1,33 +1,33 @@
- position = local_assigns.fetch(:position, nil)
.search-result-row.row.gl-display-flex.gl-sm-flex-direction-row.gl-flex-direction-column.gl-mt-5{ class: 'gl-pb-5! gl-mb-0!' }
.search-result-row.row.gl-flex.sm:gl-flex-row.gl-flex-col.gl-mt-5{ class: '!gl-pb-5 !gl-mb-0' }
.col-sm-9
%span.gl-display-flex.gl-align-items-center
%span.gl-flex.gl-items-center
= gl_badge_tag issuable_state_text(issuable), variant: issuable_state_to_badge_class(issuable)
= sprite_icon('eye-slash', css_class: 'gl-text-secondary gl-ml-2') if issuable.respond_to?(:confidential?) && issuable.confidential?
= link_to issuable_path(issuable), data: { event_tracking: 'click_search_result', event_label: @scope, event_value: position, event_property: @search_term }, class: 'gl-w-full' do
%span.term.str-truncated.gl-font-bold.gl-ml-2= simple_search_highlight_and_truncate(issuable.title, @search_term)
.gl-text-secondary.gl-mb-3.gl-mt-2.gl-font-sm
.gl-text-secondary.gl-mb-3.gl-mt-2.gl-text-sm
= issuable_project_reference(issuable)
&middot;
= sprintf(s_('created %{issuable_created} by %{author}'), { issuable_created: time_ago_with_tooltip(issuable.created_at, placement: 'bottom'), author: link_to_member(issuable.author, avatar: false) }).html_safe
- if (target_branch = issuable_visible_target_branch(issuable))
%span.project-ref-path.has-tooltip.gl-inline-block.gl-text-truncate.gl-max-w-26.gl-align-bottom{ title: _('Target branch: %{target_branch}') % {target_branch: target_branch} }
%span.project-ref-path.has-tooltip.gl-inline-block.gl-truncate.gl-max-w-26.gl-align-bottom{ title: _('Target branch: %{target_branch}') % {target_branch: target_branch} }
&nbsp;
= link_to project_ref_path(issuable.project, target_branch), class: 'ref-name gl-text-secondary!' do
= link_to project_ref_path(issuable.project, target_branch), class: 'ref-name !gl-text-secondary' do
= sprite_icon('branch', size: 12, css_class: 'fork-sprite')
= target_branch
.description.term.gl-px-0.gl-font-sm
.description.term.gl-px-0.gl-text-sm
= highlight_and_truncate_issuable(issuable, @search_term, @search_highlight)
- if issuable.labels.any?
.gl-mt-3
- presented_labels_sorted_by_title(issuable.labels, issuable.project).each do |label|
= link_to_label(label)
.col-sm-3.gl-mt-3.gl-sm-mt-0.gl-text-right
.col-sm-3.gl-mt-3.sm:gl-mt-0.gl-text-right
- if issuable.respond_to?(:upvotes_count) && issuable.upvotes_count > 0
%li.gl-list-none
%span.has-tooltip{ title: _('Upvotes') }
= sprite_icon('thumb-up', css_class: "gl-align-middle")
= issuable.upvotes_count
%span.gl-text-secondary.gl-font-sm= sprintf(s_('updated %{time_ago}'), { time_ago: time_ago_with_tooltip(issuable.updated_at, placement: 'bottom') }).html_safe
%span.gl-text-secondary.gl-text-sm= sprintf(s_('updated %{time_ago}'), { time_ago: time_ago_with_tooltip(issuable.updated_at, placement: 'bottom') }).html_safe

View File

@ -3,7 +3,7 @@
- position = index + 1
.search-result-row
= link_to project_milestone_path(milestone.project, milestone), class: 'gl-font-bold gl-text-black-normal', data: { event_tracking: 'click_search_result', event_label: @scope, event_value: position, event_property: @search_term } do
= link_to project_milestone_path(milestone.project, milestone), class: 'gl-font-bold gl-text-default', data: { event_tracking: 'click_search_result', event_label: @scope, event_value: position, event_property: @search_term } do
%span.term.str-truncated= simple_search_highlight_and_truncate(milestone.title, @search_term)
- if milestone.project_milestone?

View File

@ -7,9 +7,9 @@
.search-result-row
.note-search-caption.gl-max-w-full
.gl-font-sm.gl-text-secondary.gl-float-right= time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note-created-ago')
.gl-display-inline-block.gl-text-truncate.search-max-w-inherit.gl-align-bottom
.gl-font-bold= link_to_member(note.author, avatar: true, extra_class: 'gl-text-black-normal')
.gl-text-sm.gl-text-secondary.gl-float-right= time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note-created-ago')
.gl-inline-block.gl-truncate.search-max-w-inherit.gl-align-bottom
.gl-font-bold= link_to_member(note.author, avatar: true, extra_class: 'gl-text-default')
.gl-text-secondary
= _("Commented on %{link_to_project}").html_safe % { link_to_project: link_to(project.full_name, project) }
&middot;

View File

@ -6,11 +6,11 @@
%div
%div{ class: '!gl-inline-flex' }
= render Pajamas::AvatarComponent.new(user, size: 32, alt: '')
.gl-ml-3{ class: 'gl-text-left!' }
= link_to user_path(user), class: 'gl-text-body', data: { event_tracking: 'click_search_result', event_label: @scope, event_value: position, event_property: @search_term } do
.gl-display-inline-block.gl-font-bold= simple_search_highlight_and_truncate(user.name, @search_term)
.gl-ml-3{ class: '!gl-text-left' }
= link_to user_path(user), class: 'gl-text-primary', data: { event_tracking: 'click_search_result', event_label: @scope, event_value: position, event_property: @search_term } do
.gl-inline-block.gl-font-bold= simple_search_highlight_and_truncate(user.name, @search_term)
= user_status(user)
%div{ class: 'gl-text-left!' }= simple_search_highlight_and_truncate(user.to_reference, @search_term)
%div{ class: '!gl-text-left' }= simple_search_highlight_and_truncate(user.to_reference, @search_term)
%td.gl-text-right{ data: { label: _('Activity') } }
%div
%span.gl-font-bold= _('User created:')

View File

@ -2,8 +2,8 @@
- wiki_blob = local_assigns.fetch(:result, nil)
- position = index + 1
%div{ class: 'search-result-row gl-pb-3! gl-mt-5 gl-mb-0!' }
%span.gl-display-flex.gl-align-items-center
%div{ class: 'search-result-row !gl-pb-3 gl-mt-5 !gl-mb-0' }
%span.gl-flex.gl-items-center
= link_to wiki_blob_link(wiki_blob), data: { event_tracking: 'click_search_result', event_label: @scope, event_value: position, event_property: @search_term }, class: 'gl-w-full' do
%span.term.str-truncated.gl-font-bold= ::Wiki.canonicalize_filename(wiki_blob.path)
.description.term.col-sm-10.gl-px-0

View File

@ -6,7 +6,7 @@
- noteable_url = show_project_path ? url_for([@sent_notification.project, noteable]) : breadcrumb_title_link
- page_title _('Unsubscribe'), noteable_text, noteable_type.pluralize, project_path
%h1.page-title.gl-font-size-h-display
%h1.page-title.gl-text-size-h-display
= _("Unsubscribe from %{type}") % { type: noteable_type }
%p

View File

@ -2,7 +2,7 @@
- include_private = local_assigns.fetch(:include_private, false)
- params[:scope] ||= []
= gl_tabs_nav({ class: 'js-snippets-nav-tabs gl-border-b-0 gl-overflow-x-auto gl-flex-grow-1 gl-flex-nowrap' }) do
= gl_tabs_nav({ class: 'js-snippets-nav-tabs gl-border-b-0 gl-overflow-x-auto gl-grow gl-flex-nowrap' }) do
= gl_tab_link_to subject_snippets_path(subject), { item_active: params[:scope].empty? } do
= _('All')
= gl_tab_counter_badge(include_private ? counts[:total] : counts[:are_public_or_internal])

View File

@ -3,6 +3,6 @@
- content_for :prefetch_asset_tags do
- webpack_preload_asset_tag('monaco')
%h1.page-title.gl-font-size-h-display
%h1.page-title.gl-text-size-h-display
= _("Edit snippet")
= render 'shared/snippets/form', url: gitlab_snippet_path(@snippet)

View File

@ -1,7 +1,7 @@
- @force_fluid_layout = true
- page_title _('Time tracking report')
.page-title-holder.gl-display-flex.gl-flex-align-items-center
%h1.page-title.gl-font-size-h-display= _('Time tracking report')
.page-title-holder.gl-flex.gl-flex-align-items-center
%h1.page-title.gl-text-size-h-display= _('Time tracking report')
#js-timelogs-app{ data: { limit_to_hours: Gitlab::CurrentSettings.time_tracking_limit_to_hours.to_s } }

View File

@ -2,17 +2,17 @@
%td{ data: { label: s_('Profiles|Key') } }
%div{ class: '!gl-flex !gl-pl-0' }
= sprite_icon('key', css_class: "settings-list-icon gl-hidden sm:gl-inline gl-mr-2")
.gl-display-flex.gl-flex-direction-column.gl-text-truncate
%p.gl-text-truncate.gl-m-0
.gl-flex.gl-flex-col.gl-truncate
%p.gl-truncate.gl-m-0
%code= key.fingerprint
- if key.subkeys.present?
.gl-mt-3{ class: '!gl-text-left' }
%span.gl-font-sm
%span.gl-text-sm
= _('Subkeys:')
%ul.subkeys-list
- key.subkeys.each do |subkey|
%li
%p.gl-text-truncate.gl-m-0
%p.gl-truncate.gl-m-0
%code= subkey.fingerprint
%td{ data: { label: _('Status') } }

View File

@ -1,13 +1,13 @@
- page_title _('Update password')
.gl-sm-w-half.gl-ml-auto.gl-mr-auto
.gl-ml-auto.gl-mr-auto{ class: 'sm:gl-w-1/2' }
%h1.gl-heading-1= _('Update password for %{current_name}') % { current_name: current_user.name }
%p.gl-text-secondary
= _("To continue, please update your password. After you update, you'll be directed to sign in again.")
.info-well
.well-segment
.gl-display-flex.gl-align-items-center
.gl-flex.gl-items-center
= render Pajamas::AvatarComponent.new(current_user, size: 24, avatar_options: { data: { qa_selector: 'user_avatar_content' }, title: current_user.username })
.gl-pl-4.gl-break-all
%span= _('Signed in as %{username}') % { username: '@' + current_user.username }

View File

@ -31,7 +31,7 @@
= link_to avatar_icon_for_user(@user, 400), target: '_blank', rel: 'noopener noreferrer' do
= render Pajamas::AvatarComponent.new(@user, size: 96, alt: "", class: 'gl-float-left gl-mr-5')
%h5.gl-mt-0= s_("Profiles|Upload new avatar")
.gl-display-flex.gl-align-items-center.gl-my-3
.gl-flex.gl-items-center.gl-my-3
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-choose-user-avatar-button' }) do
= s_("Profiles|Choose file...")
%span.gl-ml-3.js-avatar-filename= s_("Profiles|No file chosen.")

View File

@ -6,13 +6,13 @@
= key.title
%td{ data: { label: s_('Profiles|Key'), testid: 'key' } }
.gl-align-items-center{ class: 'gl-display-flex! gl-pl-0!' }
.gl-items-center{ class: '!gl-flex !gl-pl-0' }
- if key.valid? && !key.expired?
= sprite_icon('key', css_class: icon_classes)
- else
%span.gl-display-inline-block.has-tooltip{ title: ssh_key_expiration_tooltip(key) }
%span.gl-inline-block.has-tooltip{ title: ssh_key_expiration_tooltip(key) }
= sprite_icon('warning-solid', css_class: icon_classes)
%span.gl-text-truncate.gl-sm-ml-3
%span.gl-truncate.sm:gl-ml-3
= key.fingerprint
%td{ data: { label: s_('Profiles|Usage type'), testid: 'usage-type' } }

View File

@ -2,7 +2,7 @@
.profile-readme-wrapper.gl-relative.gl-w-full.gl-pt-5
.profile-readme.read-more-container.gl-relative.justify-content-center.gl-border.gl-rounded-base.gl-overflow-hidden{ data: { 'read-more-height': 400 } }
.read-more-content.gl-py-5.gl-px-6
.gl-display-flex
.gl-flex
= render Pajamas::BreadcrumbComponent.new(class: 'gl-mb-4') do |c|
- c.with_item(text: @user.username, href: project_path(@user.user_project))
- c.with_item(text: @user.user_readme.path, href: @user.user_project.readme_url)
@ -11,16 +11,16 @@
.gl-ml-auto
= link_to _('Edit file'), edit_blob_path(@user.user_project, @user.user_project.default_branch, @user.user_readme.path)
= render 'projects/blob/viewer', viewer: @user.user_readme.rich_viewer, load_async: false
.js-read-more-trigger.read-more-trigger.gl-h-8.gl-absolute.gl-z-2.gl-bg-default.gl-border-t.gl-border-t-default.gl-px-6.gl-rounded-bottom-base.gl-cursor-pointer
= render Pajamas::ButtonComponent.new(variant: :link, button_text_classes: 'gl-display-flex gl-align-items-center gl-gap-1', button_options: { class: 'gl-mt-4 -gl-ml-1', 'aria-label': _("Expand Readme") }) do
.js-read-more-trigger.read-more-trigger.gl-h-8.gl-absolute.gl-z-2.gl-bg-default.gl-border-t.gl-border-t-default.gl-px-6.gl-rounded-b-base.gl-cursor-pointer
= render Pajamas::ButtonComponent.new(variant: :link, button_text_classes: 'gl-flex gl-items-center gl-gap-1', button_options: { class: 'gl-mt-4 -gl-ml-1', 'aria-label': _("Expand Readme") }) do
= sprite_icon('chevron-down', size: 14)
= _("Read more")
- if can?(current_user, :read_cross_project)
.gl-align-self-start.gl-overflow-hidden
.gl-self-start.gl-overflow-hidden
.activities-block
.gl-display-flex.gl-align-items-baseline
%h2.gl-heading-3.gl-flex-grow-1{ class: 'gl-mt-5! gl-mb-3!' }
.gl-flex.gl-items-baseline
%h2.gl-heading-3.gl-grow{ class: '!gl-mt-5 !gl-mb-3' }
= s_('UserProfile|Activity')
= link_to s_('UserProfile|View all'), user_activity_path, class: "hide js-view-all"
@ -37,8 +37,8 @@
- if @user.personal_projects.any?
.projects-block.gl-w-full
.gl-display-flex.gl-align-items-baseline
%h2.gl-heading-3.gl-flex-grow-1{ class: 'gl-mt-5! gl-mb-3!' }
.gl-flex.gl-items-baseline
%h2.gl-heading-3.gl-grow{ class: '!gl-mt-5 !gl-mb-3' }
= s_('UserProfile|Personal projects')
= link_to s_('UserProfile|View all'), user_projects_path, class: "hide js-view-all"
.overview-content-list{ data: { href: user_projects_path } }

View File

@ -1,23 +1,23 @@
.user-profile-sidebar
.profile-header.gl-pb-5.gl-pt-3.gl-overflow-y-auto.gl-sm-pr-4
.profile-header.gl-pb-5.gl-pt-3.gl-overflow-y-auto.sm:gl-pr-4
.gl-align-top.gl-text-left.gl-max-w-80.gl-wrap-anywhere
.user-info
- if @user.confirmed?
.gl-flex.gl-gap-4.gl-flex-direction-column
.gl-flex.gl-gap-4.gl-flex-col
- if @user.pronouns.present? || @user.pronunciation.present? || @user.bio.present?
%div
%h2.gl-font-base.gl-mb-2.gl-mt-4= s_('UserProfile|About')
.gl-flex.gl-gap-2.gl-flex-direction-column
%h2.gl-text-base.gl-mb-2.gl-mt-4= s_('UserProfile|About')
.gl-flex.gl-gap-2.gl-flex-col
- if @user.pronouns.present? || @user.pronunciation.present?
.gl-mb-2
- if @user.pronunciation.present?
%p.gl-m-0
= s_("UserProfile|Pronounced as:")
%span.gl-font-sm.gl-text-secondary.gl-inline-flex= @user.pronunciation
%span.gl-text-sm.gl-text-secondary.gl-inline-flex= @user.pronunciation
- if @user.pronouns.present?
%p.gl-m-0
= s_("UserProfile|Pronouns:")
%span.gl-font-sm.gl-text-secondary.gl-inline-flex= @user.pronouns
%span.gl-text-sm.gl-text-secondary.gl-inline-flex= @user.pronouns
- if @user.bio.present?
%p.profile-user-bio.gl-mb-0
= @user.bio
@ -27,7 +27,7 @@
- user_local_time = local_time(@user.timezone)
%div{ itemprop: 'address', itemscope: true, itemtype: 'https://schema.org/PostalAddress' }
%h2.gl-font-base.gl-mb-2.gl-mt-4= s_('UserProfile|Info')
%h2.gl-text-base.gl-mb-2.gl-mt-4= s_('UserProfile|Info')
- if work_information(@user).present?
.gl-flex.gl-gap-2.gl-mb-2
= sprite_icon('work', css_class: 'gl-fill-icon-subtle gl-mt-1 flex-shrink-0')
@ -49,7 +49,7 @@
- if has_contact_info?(@user)
.gl-text-gray-900
%h2.gl-font-base.gl-mb-2.gl-mt-4= s_('UserProfile|Contact')
%h2.gl-text-base.gl-mb-2.gl-mt-4= s_('UserProfile|Contact')
- if @user.website_url.present?
.gl-flex.gl-gap-2.gl-mb-2
= sprite_icon('earth', css_class: 'gl-fill-icon-subtle gl-mt-1 flex-shrink-0')

View File

@ -2,4 +2,4 @@
- if verified_gpg_keys.any?
= render Pajamas::ButtonComponent.new(href: user_gpg_keys_path,
icon: 'key',
button_options: { class: 'gl-flex-grow-1 gl-mx-1 has-tooltip', title: n_('View public GPG key', 'View public GPG keys', verified_gpg_keys.length), data: { toggle: 'tooltip', placement: 'bottom', container: 'body' }})
button_options: { class: 'gl-grow gl-mx-1 has-tooltip', title: n_('View public GPG key', 'View public GPG keys', verified_gpg_keys.length), data: { toggle: 'tooltip', placement: 'bottom', container: 'body' }})

View File

@ -6,7 +6,7 @@
- @events.sort_by(&:created_at).each do |event|
%li
%span.light.js-localtime{ :data => { :datetime => event.created_at.utc.strftime('%Y-%m-%dT%H:%M:%SZ'), :toggle => 'tooltip', :placement => 'top' } }
= sprite_icon('clock', css_class: 'gl-vertical-align-text-bottom')
= sprite_icon('clock', css_class: 'gl-align-text-bottom')
= event.created_at.to_time.in_time_zone(local_timezone_instance(@user.timezone)).strftime('%-I:%M%P')
- if event.visible_to_user?(current_user)
- if event.push_action?

View File

@ -14,9 +14,9 @@
= auto_discovery_link_tag(:atom, user_url(@user, format: :atom), title: "#{@user.name} activity")
%div{ class: container_class }
.user-profile-header.gl-display-flex.gl-justify-content-space-between.gl-flex-direction-column.gl-md-flex-direction-row-reverse.gl-my-5{ 'data-testid': 'user-profile-header' }
.user-profile-header.gl-flex.gl-justify-between.gl-flex-col.md:gl-flex-row-reverse.gl-my-5{ 'data-testid': 'user-profile-header' }
%div
.cover-controls.gl-display-flex.gl-gap-3.gl-mb-4.gl-md-justify-content-end.gl-md-flex-direction-row-reverse
.cover-controls.gl-flex.gl-gap-3.gl-mb-4.md:gl-justify-end.md:gl-flex-row-reverse
.js-user-profile-actions{ data: user_profile_actions_data(@user) }
= render 'users/follow_user'
-# The following edit button is mutually exclusive to the follow user button, they won't be shown together
@ -26,20 +26,20 @@
= s_("UserProfile|Edit profile")
= render 'users/view_gpg_keys'
= render 'users/view_user_in_admin_area'
.gl-display-flex.gl-flex-direction-row.gl-align-items-center.gl-gap-x-5.gl-mt-2.gl-sm-mt-0
.gl-flex.gl-flex-row.gl-items-center.gl-gap-x-5.gl-mt-2.sm:gl-mt-0
.user-image.gl-relative.gl-md-py-3
= link_to avatar_icon_for_user(@user, 400, current_user: current_user), target: '_blank', rel: 'noopener noreferrer', title: s_('UserProfile|View large avatar') do
= render Pajamas::AvatarComponent.new(@user, alt: s_('UserProfile|User profile picture'), size: 96, avatar_options: { itemprop: "image" })
- if @user.status&.busy?
= render Pajamas::BadgeComponent.new(s_('UserProfile|Busy'), variant: 'warning', class: 'gl-absolute gl-display-flex gl-justify-content-center gl-align-items-center gl-left-1/2 gl-bg-gray-50 gl-border gl-border-white -gl-translate-x-1/2 gl-top-full -gl-mt-3')
= render Pajamas::BadgeComponent.new(s_('UserProfile|Busy'), variant: 'warning', class: 'gl-absolute gl-flex gl-justify-center gl-items-center gl-left-1/2 gl-bg-gray-50 gl-border gl-border-white -gl-translate-x-1/2 gl-top-full -gl-mt-3')
%div
%h1.gl-heading-1.gl-leading-1.gl-mr-2{ class: 'gl-my-0!', itemprop: 'name' }
%h1.gl-heading-1.gl-leading-1.gl-mr-2{ class: '!gl-my-0', itemprop: 'name' }
= user_display_name(@user)
.gl-font-size-h2.gl-text-gray-500.gl-font-normal.gl-my-0
.gl-text-size-h2.gl-text-gray-500.gl-font-normal.gl-my-0
= @user.to_reference
- if !@user.blocked? && @user.confirmed? && @user.status&.customized?
.gl-my-2.cover-status.gl-font-sm.gl-pt-2.gl-display-flex.gl-flex-direction-column
.gl-inline-flex.gl-gap-3.gl-align-items-baseline
.gl-my-2.cover-status.gl-text-sm.gl-pt-2.gl-flex.gl-flex-col
.gl-inline-flex.gl-gap-3.gl-items-baseline
= emoji_icon(@user.status.emoji)
= markdown_field(@user.status, :message)
.user-profile{ class: @user.blocked? ? '' : 'user-profile-with-sidebar' }

View File

@ -1,5 +1,5 @@
- page_title _("Unsubscribe"), _("Admin Notifications")
%h1.page-title.gl-font-size-h-display Unsubscribe from Admin notifications
%h1.page-title.gl-text-size-h-display Unsubscribe from Admin notifications
= form_tag unsubscribe_path(Base64.urlsafe_encode64(@email)) do
%p

View File

@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/433324
milestone: '16.7'
type: development
group: group::ide
default_enabled: false
default_enabled: true

View File

@ -0,0 +1,9 @@
---
name: store_detumbled_email
feature_issue_url: https://gitlab.com/gitlab-org/modelops/anti-abuse/team-tasks/-/work_items/827
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/161663
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/478304
milestone: '17.4'
group: group::anti-abuse
type: gitlab_com_derisk
default_enabled: false

View File

@ -412,6 +412,9 @@ security_scans:
- table: p_ci_builds
column: build_id
on_delete: async_delete
- table: projects
column: project_id
on_delete: async_delete
security_trainings:
- table: projects
column: project_id

View File

@ -0,0 +1,8 @@
# frozen_string_literal: true
helper.all_changed_files.each do |filename|
next unless filename.end_with?('.rb')
next if filename.start_with?('spec/', 'ee/spec/', 'jh/spec/', 'qa/')
cookie_setting.add_suggestions_for(filename)
end

View File

@ -0,0 +1,11 @@
# frozen_string_literal: true
require_relative '../../tooling/danger/cookie_setting'
module Danger
class CookieSetting < ::Danger::Plugin
def add_suggestions_for(filename)
Tooling::Danger::CookieSetting.new(filename, context: self).suggest
end
end
end

View File

@ -9,3 +9,13 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/14784
milestone: '12.2'
gitlab_schema: gitlab_ci
sharding_key_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/463243
desired_sharding_key:
project_id:
references: projects
backfill_via:
parent:
foreign_key: job_id
table: p_ci_builds
sharding_key: project_id
belongs_to: job
foreign_key_name: fk_rails_fbf3b34792_p

View File

@ -8,4 +8,5 @@ description: TODO
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/c6ae290cea4b88ecaa9cfe0bc9d88e8fd32070c1
milestone: '9.0'
gitlab_schema: gitlab_ci
sharding_key_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/458486
sharding_key:
project_id: projects

View File

@ -12,4 +12,5 @@ description: Routing table for ci_builds
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/120873
milestone: '16.1'
gitlab_schema: gitlab_ci
sharding_key_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/458488
sharding_key:
project_id: projects

View File

@ -10,3 +10,13 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/117319
milestone: '16.1'
gitlab_schema: gitlab_ci
sharding_key_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/463246
desired_sharding_key:
project_id:
references: projects
backfill_via:
parent:
foreign_key: job_id
table: p_ci_builds
sharding_key: project_id
belongs_to: job
foreign_key_name: fk_rails_d4d0c0fa0f

View File

@ -9,3 +9,13 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/141270
milestone: '16.9'
gitlab_schema: gitlab_ci
sharding_key_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/463244
desired_sharding_key:
project_id:
references: projects
backfill_via:
parent:
foreign_key: pipeline_id
table: ci_pipelines
sharding_key: project_id
belongs_to: pipeline
foreign_key_name: fk_f29c5f4380_p

View File

@ -7,5 +7,5 @@ feature_categories:
description: Stores information about the security scans that are a part of Ci::Build
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/23669
milestone: '12.8'
gitlab_schema: gitlab_main
gitlab_schema: gitlab_sec
sharding_key_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/454948

View File

@ -5,7 +5,7 @@ class QueuePurgeSecurityScansWithEmptyFindingData < Gitlab::Database::Migration[
disable_ddl_transaction!
restrict_gitlab_migration gitlab_schema: :gitlab_main
restrict_gitlab_migration gitlab_schema: :gitlab_sec
MIGRATION = "PurgeSecurityScansWithEmptyFindingData"
DELAY_INTERVAL = 2.minutes
@ -27,28 +27,36 @@ class QueuePurgeSecurityScansWithEmptyFindingData < Gitlab::Database::Migration[
end
def up
return if Gitlab.com? || !Gitlab.ee?
# temporary until security_findings table is migrated
# https://gitlab.com/gitlab-org/gitlab/-/issues/477986'
Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.with_suppressed do
break if Gitlab.com? || !Gitlab.ee?
first_succeeded_scan = SecurityScan.succeeded.first
first_succeeded_scan = SecurityScan.succeeded.first
return unless first_succeeded_scan
break unless first_succeeded_scan
first_finding = first_succeeded_scan.findings.first
first_finding = first_succeeded_scan.findings.first
return if first_finding&.finding_data.present?
break if first_finding&.finding_data.present?
queue_batched_background_migration(
MIGRATION,
:security_scans,
:id,
job_interval: DELAY_INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE,
batch_min_value: first_succeeded_scan.id
)
queue_batched_background_migration(
MIGRATION,
:security_scans,
:id,
job_interval: DELAY_INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE,
batch_min_value: first_succeeded_scan.id
)
end
end
def down
delete_batched_background_migration(MIGRATION, :security_scans, :id, [])
# temporary until security_findings table is migrated
# https://gitlab.com/gitlab-org/gitlab/-/issues/477986'
Gitlab::Database::QueryAnalyzers::RestrictAllowedSchemas.with_suppressed do
delete_batched_background_migration(MIGRATION, :security_scans, :id, [])
end
end
end

View File

@ -4,7 +4,7 @@ class FinalizePurgeSecurityScansWithEmptyFindingData < Gitlab::Database::Migrati
disable_ddl_transaction!
milestone '16.11'
restrict_gitlab_migration gitlab_schema: :gitlab_main
restrict_gitlab_migration gitlab_schema: :gitlab_sec
def up
return if Gitlab.com? || !Gitlab.ee?

View File

@ -0,0 +1,21 @@
# frozen_string_literal: true
class RemoveProjectsSecurityScansProjectIdFk < Gitlab::Database::Migration[2.2]
milestone '17.3'
disable_ddl_transaction!
FOREIGN_KEY_NAME = "fk_dbc89265b9"
def up
with_lock_retries do
remove_foreign_key_if_exists(:security_scans, :projects,
name: FOREIGN_KEY_NAME, reverse_lock_order: true)
end
end
def down
add_concurrent_foreign_key(:security_scans, :projects,
name: FOREIGN_KEY_NAME, column: :project_id,
target_column: :id, on_delete: :cascade)
end
end

View File

@ -0,0 +1 @@
587b0beecb4c39ddf190303e6294b0e420562e89e480ef31b94c855aa4db1695

View File

@ -33903,9 +33903,6 @@ ALTER TABLE ONLY web_hooks
ALTER TABLE ONLY work_item_dates_sources
ADD CONSTRAINT fk_dbbe8917ee FOREIGN KEY (due_date_sourcing_work_item_id) REFERENCES issues(id) ON DELETE SET NULL;
ALTER TABLE ONLY security_scans
ADD CONSTRAINT fk_dbc89265b9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY boards_epic_board_positions
ADD CONSTRAINT fk_dc62428d81 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE;

View File

@ -211,8 +211,7 @@ configure this:
echo some-password-here
```
Note that in production, you should avoid storing the password on
disk and use a secure mechanism for retrieving a password, such as
Avoid storing the password on disk, and use a secure mechanism for retrieving a password, such as
Vault. For example, the script might look like:
```shell

View File

@ -50,7 +50,7 @@ specifically the [Before you start](index.md#before-you-start) and [Deciding whi
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Provide your own Redis instances](#provide-your-own-redis-instances) and [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- Redis is primarily single threaded and doesn't significantly benefit from an increase in CPU cores. For this size of architecture it's strongly recommended having separate Cache and Persistent instances as specified to achieve optimum performance.
3. Recommended to be run with a reputable third-party load balancer or service (LB PaaS) which can provide HA capabilities.
Also note that sizing depends on selected Load Balancer as well as additional factors such as Network Bandwidth. Refer to [Load Balancers](index.md#load-balancers) for more information.
The sizing depends on selected Load Balancer and additional factors such as Network Bandwidth. Refer to [Load Balancers](index.md#load-balancers) for more information.
4. Should be run on reputable Cloud Provider or Self Managed solutions. See [Configure the object storage](#configure-the-object-storage) for more information.
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management.
Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
@ -170,12 +170,12 @@ including CI and other workloads.
If you have metrics to suggest that you have regularly higher throughput against the above endpoint targets, [large monorepos](index.md#large-monorepos)
or notable [additional workloads](index.md#additional-workloads) these can notably impact the performance environment and [further adjustments may be required](index.md#scaling-an-environment).
If this applies to you, we strongly recommended referring to the linked documentation as well as reaching out to your [Customer Success Manager](https://handbook.gitlab.com/job-families/sales/customer-success-management/) or our [Support team](https://about.gitlab.com/support/) for further guidance.
If this applies to you, we strongly recommended referring to the linked documentation and reaching out to your [Customer Success Manager](https://handbook.gitlab.com/job-families/sales/customer-success-management/) or our [Support team](https://about.gitlab.com/support/) for further guidance.
Testing is done regularly via our [GitLab Performance Tool (GPT)](https://gitlab.com/gitlab-org/quality/performance) and its dataset, which is available for anyone to use.
Testing is done regularly by using the [GitLab Performance Tool (GPT)](https://gitlab.com/gitlab-org/quality/performance) and its dataset, which is available for anyone to use.
The results of this testing are [available publicly on the GPT wiki](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest). For more information on our testing strategy [refer to this section of the documentation](index.md#validation-and-test-results).
The load balancers used for testing were HAProxy for Linux package environments or equivalent Cloud Provider services via NGINX Ingress for Cloud Native Hybrids. Note that these selections do not represent a specific requirement or recommendation as most [reputable load balancers are expected to work](#configure-the-external-load-balancer).
The load balancers used for testing were HAProxy for Linux package environments or equivalent Cloud Provider services with NGINX Ingress for Cloud Native Hybrids. These selections do not represent a specific requirement or recommendation as most [reputable load balancers are expected to work](#configure-the-external-load-balancer).
## Set up components
@ -521,7 +521,7 @@ A reputable provider or solution should be used for this. [Google Cloud SQL](htt
If you use a third party external service:
1. Note that the HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. These components would no longer be required when using a third party external service.
1. The HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. These components would no longer be required when using a third party external service.
1. Set up PostgreSQL according to the
[database requirements document](../../install/requirements.md#database).
1. Set up a `gitlab` username with a password of your choice. The `gitlab` user
@ -542,7 +542,7 @@ replication and failover requires:
- An [internal load balancer](#configure-the-internal-load-balancer) (TCP) to balance requests between the PgBouncer nodes.
- [Database Load Balancing](../postgresql/database_load_balancing.md) enabled.
A local PgBouncer service to be configured on each PostgreSQL node. Note that this is separate from the main PgBouncer cluster that tracks the primary.
A local PgBouncer service to be configured on each PostgreSQL node. This is separate from the main PgBouncer cluster that tracks the primary.
The following IPs will be used as an example:
@ -2099,7 +2099,7 @@ the [HTTPS documentation](https://docs.gitlab.com/omnibus/settings/ssl/index.htm
sudo gitlab-rake gitlab:db:configure
```
Note that this requires the Rails node to be configured to connect to the primary database
This operation requires configuring the Rails node to connect to the primary database
directly, [bypassing PgBouncer](../postgresql/pgbouncer.md#procedure-for-bypassing-pgbouncer).
After migrations have completed, you must configure the node to pass through PgBouncer again.
@ -2299,7 +2299,7 @@ services where applicable):
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Provide your own Redis instances](#provide-your-own-redis-instances) and [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
- Redis is primarily single threaded and doesn't significantly benefit from an increase in CPU cores. For this size of architecture it's strongly recommended having separate Cache and Persistent instances as specified to achieve optimum performance.
3. Recommended to be run with a reputable third-party load balancer or service (LB PaaS) which can provide HA capabilities.
Also note that sizing depends on selected Load Balancer as well as additional factors such as Network Bandwidth. Refer to [Load Balancers](index.md#load-balancers) for more information.
Also, the sizing depends on selected Load Balancer and additional factors such as Network Bandwidth. Refer to [Load Balancers](index.md#load-balancers) for more information.
4. Should be run on reputable Cloud Provider or Self Managed solutions. See [Configure the object storage](#configure-the-object-storage) for more information.
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management.
Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
@ -2402,7 +2402,7 @@ For further information on Webservice resource usage, see the Charts documentati
It's also recommended deploying the NGINX controller pods across the Webservice nodes as a DaemonSet. This is to allow the controllers to scale dynamically with the Webservice pods they serve as well as take advantage of the higher network bandwidth larger machine types typically have.
Note that this isn't a strict requirement. The NGINX controller pods can be deployed as desired as long as they have enough resources to handle the web traffic.
This isn't a strict requirement. The NGINX controller pods can be deployed as desired as long as they have enough resources to handle the web traffic.
#### Sidekiq

View File

@ -50,7 +50,7 @@ specifically the [Before you start](index.md#before-you-start) and [Deciding whi
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Provide your own Redis instances](#provide-your-own-redis-instances) for more information.
- Redis is primarily single threaded and doesn't significantly benefit from an increase in CPU cores. For this size of architecture it's strongly recommended having separate Cache and Persistent instances as specified to achieve optimum performance.
3. Recommended to be run with a reputable third-party load balancer or service (LB PaaS) which can provide HA capabilities.
Also note that sizing depends on selected Load Balancer as well as additional factors such as Network Bandwidth. Refer to [Load Balancers](index.md#load-balancers) for more information.
Also, the sizing depends on selected Load Balancer and additional factors such as Network Bandwidth. Refer to [Load Balancers](index.md#load-balancers) for more information.
4. Should be run on reputable Cloud Provider or Self Managed solutions. See [Configure the object storage](#configure-the-object-storage) for more information.
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management.
Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
@ -170,12 +170,12 @@ including CI and other workloads.
If you have metrics to suggest that you have regularly higher throughput against the above endpoint targets, [large monorepos](index.md#large-monorepos)
or notable [additional workloads](index.md#additional-workloads) these can notably impact the performance environment and [further adjustments may be required](index.md#scaling-an-environment).
If this applies to you, we strongly recommended referring to the linked documentation as well as reaching out to your [Customer Success Manager](https://handbook.gitlab.com/job-families/sales/customer-success-management/) or our [Support team](https://about.gitlab.com/support/) for further guidance.
If this applies to you, we strongly recommended referring to the linked documentation and reaching out to your [Customer Success Manager](https://handbook.gitlab.com/job-families/sales/customer-success-management/) or our [Support team](https://about.gitlab.com/support/) for further guidance.
Testing is done regularly via our [GitLab Performance Tool (GPT)](https://gitlab.com/gitlab-org/quality/performance) and its dataset, which is available for anyone to use.
Testing is done regularly by using the [GitLab Performance Tool (GPT)](https://gitlab.com/gitlab-org/quality/performance) and its dataset, which is available for anyone to use.
The results of this testing are [available publicly on the GPT wiki](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest). For more information on our testing strategy [refer to this section of the documentation](index.md#validation-and-test-results).
The load balancers used for testing were HAProxy for Linux package environments or equivalent Cloud Provider services via NGINX Ingress for Cloud Native Hybrids. Note that these selections do not represent a specific requirement or recommendation as most [reputable load balancers are expected to work](#configure-the-external-load-balancer).
The load balancers used for testing were HAProxy for Linux package environments or equivalent Cloud Provider services with NGINX Ingress for Cloud Native Hybrids. These selections do not represent a specific requirement or recommendation as most [reputable load balancers are expected to work](#configure-the-external-load-balancer).
## Set up components
@ -525,7 +525,7 @@ A reputable provider or solution should be used for this. [Google Cloud SQL](htt
If you use a third party external service:
1. Note that the HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. These components would no longer be required when using a third party external service.
1. The HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. These components would no longer be required when using a third party external service.
1. Set up PostgreSQL according to the
[database requirements document](../../install/requirements.md#database).
1. Set up a `gitlab` username with a password of your choice. The `gitlab` user
@ -546,9 +546,9 @@ replication and failover requires:
- An [internal load balancer](#configure-the-internal-load-balancer) (TCP) to balance requests between the PgBouncer nodes.
- [Database Load Balancing](../postgresql/database_load_balancing.md) enabled.
A local PgBouncer service to be configured on each PostgreSQL node. Note that this is separate from the main PgBouncer cluster that tracks the primary.
A local PgBouncer service to be configured on each PostgreSQL node. This is separate from the main PgBouncer cluster that tracks the primary.
The following IPs will be used as an example:
The following IPs are used as an example:
- `10.6.0.21`: PostgreSQL primary
- `10.6.0.22`: PostgreSQL secondary 1
@ -2107,7 +2107,7 @@ the [HTTPS documentation](https://docs.gitlab.com/omnibus/settings/ssl/index.htm
sudo gitlab-rake gitlab:db:configure
```
Note that this requires the Rails node to be configured to connect to the primary database
This operation requires configuring the Rails node to connect to the primary database
directly, [bypassing PgBouncer](../postgresql/pgbouncer.md#procedure-for-bypassing-pgbouncer).
After migrations have completed, you must configure the node to pass through PgBouncer again.
@ -2407,9 +2407,9 @@ For further information on Webservice resource usage, see the Charts documentati
##### NGINX
It's also recommended deploying the NGINX controller pods across the Webservice nodes as a DaemonSet. This is to allow the controllers to scale dynamically with the Webservice pods they serve as well as take advantage of the higher network bandwidth larger machine types typically have.
It's also recommended deploying the NGINX controller pods across the Webservice nodes as a DaemonSet. This is to allow the controllers to scale dynamically with the Webservice pods they serve and take advantage of the higher network bandwidth larger machine types typically have.
Note that this isn't a strict requirement. The NGINX controller pods can be deployed as desired as long as they have enough resources to handle the web traffic.
This isn't a strict requirement. The NGINX controller pods can be deployed as desired as long as they have enough resources to handle the web traffic.
#### Sidekiq

View File

@ -40,7 +40,7 @@ For a full list of reference architectures, see
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Provide your own PostgreSQL instance](#provide-your-own-postgresql-instance) and [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Provide your own Redis instance](#provide-your-own-redis-instance) and [Recommended cloud providers and services](index.md#recommended-cloud-providers-and-services) for more information.
3. Recommended to be run with a reputable third-party load balancer or service (LB PaaS).
Also note that sizing depends on selected Load Balancer as well as additional factors such as Network Bandwidth. Refer to [Load Balancers](index.md#load-balancers) for more information.
Sizing depends on selected Load Balancer and additional factors such as Network Bandwidth. See [Load Balancers](index.md#load-balancers) for more information.
4. Should be run on reputable Cloud Provider or Self Managed solutions. See [Configure the object storage](#configure-the-object-storage) for more information.
5. Gitaly specifications are based on the use of normal-sized repositories in good health.
However, if you have large monorepos (larger than several gigabytes) this can **significantly** impact Git and Gitaly performance and an increase of specifications will likely be required.
@ -113,12 +113,12 @@ including CI and other workloads.
If you have metrics to suggest that you have regularly higher throughput against the above endpoint targets, [large monorepos](index.md#large-monorepos)
or notable [additional workloads](index.md#additional-workloads) these can notably impact the performance environment and [further adjustments may be required](index.md#scaling-an-environment).
If this applies to you, we strongly recommended referring to the linked documentation as well as reaching out to your [Customer Success Manager](https://handbook.gitlab.com/job-families/sales/customer-success-management/) or our [Support team](https://about.gitlab.com/support/) for further guidance.
If this applies to you, we strongly recommended referring to the linked documentation and reaching out to your [Customer Success Manager](https://handbook.gitlab.com/job-families/sales/customer-success-management/) or our [Support team](https://about.gitlab.com/support/) for further guidance.
Testing is done regularly via our [GitLab Performance Tool (GPT)](https://gitlab.com/gitlab-org/quality/performance) and its dataset, which is available for anyone to use.
Testing is done regularly by using our [GitLab Performance Tool (GPT)](https://gitlab.com/gitlab-org/quality/performance) and its dataset, which is available for anyone to use.
The results of this testing are [available publicly on the GPT wiki](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest). For more information on our testing strategy [refer to this section of the documentation](index.md#validation-and-test-results).
The load balancers used for testing were HAProxy for Linux package environments or equivalent Cloud Provider services via NGINX Ingress for Cloud Native Hybrids. Note that these selections do not represent a specific requirement or recommendation as most [reputable load balancers are expected to work](#configure-the-external-load-balancer).
The load balancers used for testing were HAProxy for Linux package environments or equivalent Cloud Provider services with NGINX Ingress for Cloud Native Hybrids. These selections do not represent a specific requirement or recommendation as most [reputable load balancers are expected to work](#configure-the-external-load-balancer).
## Set up components
@ -272,7 +272,7 @@ A reputable provider or solution should be used for this. [Google Cloud SQL](htt
If you use a third party external service:
1. Note that the HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. The HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. Set up PostgreSQL according to the
[database requirements document](../../install/requirements.md#database).
1. Set up a `gitlab` username with a password of your choice. The `gitlab` user
@ -332,7 +332,7 @@ If you use a third party external service:
1. [Reconfigure GitLab](../restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect.
1. Note the PostgreSQL node's IP address or hostname, port, and
plain text password. These will be necessary when configuring the
plain text password. These details are necessary when configuring the
[GitLab application server](#configure-gitlab-rails) later.
Advanced [configuration options](https://docs.gitlab.com/omnibus/settings/database.html)
@ -544,11 +544,11 @@ To configure the Gitaly server, on the server node you want to use for Gitaly:
### Gitaly TLS support
Gitaly supports TLS encryption. To be able to communicate
with a Gitaly instance that listens for secure connections you will need to use `tls://` URL
Gitaly supports TLS encryption. To communicate
with a Gitaly instance that listens for secure connections, you must use `tls://` URL
scheme in the `gitaly_address` of the corresponding storage entry in the GitLab configuration.
You will need to bring your own certificates as this isn't provided automatically.
You must bring your own certificates as this isn't provided automatically.
The certificate, or its certificate authority, must be installed on all Gitaly
nodes (including the Gitaly node using the certificate) and on all client nodes
that communicate with it following the procedure described in
@ -914,7 +914,7 @@ the [HTTPS documentation](https://docs.gitlab.com/omnibus/settings/ssl/index.htm
sudo gitlab-rake gitlab:db:configure
```
Note that this requires the Rails node to be configured to connect to the primary database
This operation requires configuring the Rails node to connect to the primary database
directly, [bypassing PgBouncer](../postgresql/pgbouncer.md#procedure-for-bypassing-pgbouncer).
After migrations have completed, you must configure the node to pass through PgBouncer again.
@ -1123,7 +1123,7 @@ the overall makeup as desired as long as the minimum CPU and Memory requirements
[Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine) and [Amazon Elastic Kubernetes Service (EKS)](https://aws.amazon.com/eks/). Other Kubernetes services may also work, but your mileage may vary.
- GCP and AWS examples of how to reach the Target Node Pool Total are given for convenience. These sizes are used in performance testing but following the example is not required. Different node pool designs can be used as desired as long as the targets are met, and all pods can deploy.
- The [Webservice](#webservice) and [Sidekiq](#sidekiq) target node pool totals are given for GitLab components only. Additional resources are required for the chosen Kubernetes provider's system processes. The given examples take this into account.
- The [Supporting](#supporting) target node pool total is given generally to accommodate several resources for supporting the GitLab deployment as well as any additional deployments you may wish to make depending on your requirements. Similar to the other node pools, the chosen Kubernetes provider's system processes also require resources. The given examples take this into account.
- The [Supporting](#supporting) target node pool total is given generally to accommodate several resources for supporting the GitLab deployment and any additional deployments you may wish to make depending on your requirements. Similar to the other node pools, the chosen Kubernetes provider's system processes also require resources. The given examples take this into account.
- In production deployments, it's not required to assign pods to specific nodes. However, it is recommended to have several nodes in each pool spread across different availability zones to align with resilient cloud architecture practices.
- Enabling autoscaling, such as Cluster Autoscaler, for efficiency reasons is encouraged, but it's generally recommended targeting a floor of 75% for Webservice and Sidekiq pods to ensure ongoing performance.
@ -1197,16 +1197,16 @@ Each Webservice pod (Puma and Workhorse) is recommended to be run with the follo
- 5 GB memory (request)
- 7 GB memory (limit)
For 40 RPS or 2,000 users we recommend a total Puma worker count of around 12 so in turn it's recommended to run at
For 40 RPS or 2,000 users, we recommend a total Puma worker count of around 12 so in turn it's recommended to run at
least 3 Webservice pods.
For further information on Webservice resource usage, see the Charts documentation on [Webservice resources](https://docs.gitlab.com/charts/charts/gitlab/webservice/#resources).
##### NGINX
It's also recommended deploying the NGINX controller pods across the Webservice nodes as a DaemonSet. This is to allow the controllers to scale dynamically with the Webservice pods they serve as well as take advantage of the higher network bandwidth larger machine types typically have.
It's also recommended deploying the NGINX controller pods across the Webservice nodes as a DaemonSet. This allows the controllers to scale dynamically with the Webservice pods they serve, and takes advantage of the higher network bandwidth larger machine types typically have.
Note that this isn't a strict requirement. The NGINX controller pods can be deployed as desired as long as they have enough resources to handle the web traffic.
This isn't a strict requirement. The NGINX controller pods can be deployed as desired as long as they have enough resources to handle the web traffic.
#### Sidekiq

View File

@ -48,7 +48,7 @@ For a full list of reference architectures, see
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Provide your own PostgreSQL instance](#provide-your-own-postgresql-instance) for more information.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Provide your own Redis instance](#provide-your-own-redis-instance) for more information.
3. Recommended to be run with a reputable third-party load balancer or service (LB PaaS) which can provide HA capabilities.
Also note that sizing depends on selected Load Balancer as well as additional factors such as Network Bandwidth. Refer to [Load Balancers](index.md#load-balancers) for more information.
Sizing depends on selected Load Balancer and additional factors such as Network Bandwidth. Refer to [Load Balancers](index.md#load-balancers) for more information.
4. Should be run on reputable Cloud Provider or Self Managed solutions. See [Configure the object storage](#configure-the-object-storage) for more information.
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management.
Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
@ -165,12 +165,12 @@ including CI and other workloads.
If you have metrics to suggest that you have regularly higher throughput against the above endpoint targets, [large monorepos](index.md#large-monorepos)
or notable [additional workloads](index.md#additional-workloads) these can notably impact the performance environment and [further adjustments may be required](index.md#scaling-an-environment).
If this applies to you, we strongly recommended referring to the linked documentation as well as reaching out to your [Customer Success Manager](https://handbook.gitlab.com/job-families/sales/customer-success-management/) or our [Support team](https://about.gitlab.com/support/) for further guidance.
If this applies to you, we strongly recommended referring to the linked documentation and reaching out to your [Customer Success Manager](https://handbook.gitlab.com/job-families/sales/customer-success-management/) or our [Support team](https://about.gitlab.com/support/) for further guidance.
Testing is done regularly via our [GitLab Performance Tool (GPT)](https://gitlab.com/gitlab-org/quality/performance) and its dataset, which is available for anyone to use.
Testing is done regularly by using our [GitLab Performance Tool (GPT)](https://gitlab.com/gitlab-org/quality/performance) and its dataset, which is available for anyone to use.
The results of this testing are [available publicly on the GPT wiki](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest). For more information on our testing strategy [refer to this section of the documentation](index.md#validation-and-test-results).
The load balancers used for testing were HAProxy for Linux package environments or equivalent Cloud Provider services via NGINX Ingress for Cloud Native Hybrids. Note that these selections do not represent a specific requirement or recommendation as most [reputable load balancers are expected to work](#configure-the-external-load-balancer).
The load balancers used for testing were HAProxy for Linux package environments or equivalent Cloud Provider services with NGINX Ingress for Cloud Native Hybrids. These selections do not represent a specific requirement or recommendation as most [reputable load balancers are expected to work](#configure-the-external-load-balancer).
## Set up components
@ -511,7 +511,7 @@ A reputable provider or solution should be used for this. [Google Cloud SQL](htt
If you use a third party external service:
1. Note that the HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. The HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. Set up PostgreSQL according to the
[database requirements document](../../install/requirements.md#database).
1. Set up a `gitlab` username with a password of your choice. The `gitlab` user
@ -532,7 +532,7 @@ replication and failover requires:
- An [internal load balancer](#configure-the-internal-load-balancer) (TCP) to balance requests between the PgBouncer nodes.
- [Database Load Balancing](../postgresql/database_load_balancing.md) enabled.
A local PgBouncer service to be configured on each PostgreSQL node. Note that this is separate from the main PgBouncer cluster that tracks the primary.
A local PgBouncer service to be configured on each PostgreSQL node. This is separate from the main PgBouncer cluster that tracks the primary.
The following IPs are used as an example:
@ -1965,7 +1965,7 @@ the [HTTPS documentation](https://docs.gitlab.com/omnibus/settings/ssl/index.htm
gitlab-rake gitlab:db:configure
```
Note that this requires the Rails node to be configured to connect to the primary database
This operation requires configuring the Rails node to connect to the primary database
directly, [bypassing PgBouncer](../postgresql/pgbouncer.md#procedure-for-bypassing-pgbouncer).
After migrations have completed, you must configure the node to pass through PgBouncer again.
@ -2197,7 +2197,7 @@ services where applicable):
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Provide your own PostgreSQL instance](#provide-your-own-postgresql-instance) for more information.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Provide your own Redis instance](#provide-your-own-redis-instance) for more information.
3. Recommended to be run with a reputable third-party load balancer or service (LB PaaS) which can provide HA capabilities.
Also note that sizing depends on selected Load Balancer as well as additional factors such as Network Bandwidth. Refer to [Load Balancers](index.md#load-balancers) for more information.
Sizing depends on selected Load Balancer and additional factors such as Network Bandwidth. Refer to [Load Balancers](index.md#load-balancers) for more information.
4. Should be run on reputable Cloud Provider or Self Managed solutions. See [Configure the object storage](#configure-the-object-storage) for more information.
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management.
Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
@ -2295,9 +2295,9 @@ For further information on Webservice resource usage, see the Charts documentati
##### NGINX
It's also recommended deploying the NGINX controller pods across the Webservice nodes as a DaemonSet. This is to allow the controllers to scale dynamically with the Webservice pods they serve as well as take advantage of the higher network bandwidth larger machine types typically have.
It's also recommended deploying the NGINX controller pods across the Webservice nodes as a DaemonSet. This allows the controllers to scale dynamically with the Webservice pods they serve, and takes advantage of the higher network bandwidth larger machine types typically have.
Note that this isn't a strict requirement. The NGINX controller pods can be deployed as desired as long as they have enough resources to handle the web traffic.
This isn't a strict requirement. The NGINX controller pods can be deployed as desired as long as they have enough resources to handle the web traffic.
#### Sidekiq

View File

@ -169,12 +169,12 @@ including CI and other workloads.
If you have metrics to suggest that you have regularly higher throughput against the above endpoint targets, [large monorepos](index.md#large-monorepos)
or notable [additional workloads](index.md#additional-workloads) these can notably impact the performance environment and [further adjustments may be required](index.md#scaling-an-environment).
If this applies to you, we strongly recommended referring to the linked documentation as well as reaching out to your [Customer Success Manager](https://handbook.gitlab.com/job-families/sales/customer-success-management/) or our [Support team](https://about.gitlab.com/support/) for further guidance.
If this applies to you, we strongly recommended referring to the linked documentation and reaching out to your [Customer Success Manager](https://handbook.gitlab.com/job-families/sales/customer-success-management/) or our [Support team](https://about.gitlab.com/support/) for further guidance.
Testing is done regularly via our [GitLab Performance Tool (GPT)](https://gitlab.com/gitlab-org/quality/performance) and its dataset, which is available for anyone to use.
Testing is done regularly by using the [GitLab Performance Tool (GPT)](https://gitlab.com/gitlab-org/quality/performance) and its dataset, which is available for anyone to use.
The results of this testing are [available publicly on the GPT wiki](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest). For more information on our testing strategy [refer to this section of the documentation](index.md#validation-and-test-results).
The load balancers used for testing were HAProxy for Linux package environments or equivalent Cloud Provider services via NGINX Ingress for Cloud Native Hybrids. Note that these selections do not represent a specific requirement or recommendation as most [reputable load balancers are expected to work](#configure-the-external-load-balancer).
The load balancers used for testing were HAProxy for Linux package environments or equivalent Cloud Provider services with NGINX Ingress for Cloud Native Hybrids. These selections do not represent a specific requirement or recommendation as most [reputable load balancers are expected to work](#configure-the-external-load-balancer).
## Set up components
@ -529,7 +529,7 @@ A reputable provider or solution should be used for this. [Google Cloud SQL](htt
If you use a third party external service:
1. Note that the HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. The HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. Set up PostgreSQL according to the
[database requirements document](../../install/requirements.md#database).
1. Set up a `gitlab` username with a password of your choice. The `gitlab` user
@ -550,7 +550,7 @@ replication and failover requires:
- An [internal load balancer](#configure-the-internal-load-balancer) (TCP) to balance requests between the PgBouncer nodes.
- [Database Load Balancing](../postgresql/database_load_balancing.md) enabled.
A local PgBouncer service to be configured on each PostgreSQL node. Note that this is separate from the main PgBouncer cluster that tracks the primary.
A local PgBouncer service to be configured on each PostgreSQL node. This is separate from the main PgBouncer cluster that tracks the primary.
The following IPs will be used as an example:
@ -2121,7 +2121,7 @@ the [HTTPS documentation](https://docs.gitlab.com/omnibus/settings/ssl/index.htm
sudo gitlab-rake gitlab:db:configure
```
Note that this requires the Rails node to be configured to connect to the primary database
This operation requires configuring the Rails node to connect to the primary database
directly, [bypassing PgBouncer](../postgresql/pgbouncer.md#procedure-for-bypassing-pgbouncer).
After migrations have completed, you must configure the node to pass through PgBouncer again.
@ -2421,9 +2421,9 @@ For further information on Webservice resource usage, see the Charts documentati
##### NGINX
It's also recommended deploying the NGINX controller pods across the Webservice nodes as a DaemonSet. This is to allow the controllers to scale dynamically with the Webservice pods they serve as well as take advantage of the higher network bandwidth larger machine types typically have.
It's also recommended deploying the NGINX controller pods across the Webservice nodes as a DaemonSet. This is to allow the controllers to scale dynamically with the Webservice pods they serve and take advantage of the higher network bandwidth larger machine types typically have.
Note that this isn't a strict requirement. The NGINX controller pods can be deployed as desired as long as they have enough resources to handle the web traffic.
This isn't a strict requirement. The NGINX controller pods can be deployed as desired as long as they have enough resources to handle the web traffic.
#### Sidekiq

View File

@ -48,7 +48,7 @@ specifically the [Before you start](index.md#before-you-start) and [Deciding whi
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Provide your own PostgreSQL instance](#provide-your-own-postgresql-instance) for more information.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Provide your own Redis instance](#provide-your-own-redis-instance) for more information.
3. Recommended to be run with a reputable third-party load balancer or service (LB PaaS) which can provide HA capabilities.
Also note that sizing depends on selected Load Balancer as well as additional factors such as Network Bandwidth. Refer to [Load Balancers](index.md#load-balancers) for more information.
Also, the sizing depends on selected Load Balancer and additional factors such as Network Bandwidth. Refer to [Load Balancers](index.md#load-balancers) for more information.
4. Should be run on reputable Cloud Provider or Self Managed solutions. See [Configure the object storage](#configure-the-object-storage) for more information.
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management.
Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
@ -165,12 +165,12 @@ including CI and other workloads.
If you have metrics to suggest that you have regularly higher throughput against the above endpoint targets, [large monorepos](index.md#large-monorepos)
or notable [additional workloads](index.md#additional-workloads) these can notably impact the performance environment and [further adjustments may be required](index.md#scaling-an-environment).
If this applies to you, we strongly recommended referring to the linked documentation as well as reaching out to your [Customer Success Manager](https://handbook.gitlab.com/job-families/sales/customer-success-management/) or our [Support team](https://about.gitlab.com/support/) for further guidance.
If this applies to you, we strongly recommended referring to the linked documentation and reaching out to your [Customer Success Manager](https://handbook.gitlab.com/job-families/sales/customer-success-management/) or our [Support team](https://about.gitlab.com/support/) for further guidance.
Testing is done regularly via our [GitLab Performance Tool (GPT)](https://gitlab.com/gitlab-org/quality/performance) and its dataset, which is available for anyone to use.
Testing is done regularly by using the [GitLab Performance Tool (GPT)](https://gitlab.com/gitlab-org/quality/performance) and its dataset, which is available for anyone to use.
The results of this testing are [available publicly on the GPT wiki](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest). For more information on our testing strategy [refer to this section of the documentation](index.md#validation-and-test-results).
The load balancers used for testing were HAProxy for Linux package environments or equivalent Cloud Provider services via NGINX Ingress for Cloud Native Hybrids. Note that these selections do not represent a specific requirement or recommendation as most [reputable load balancers are expected to work](#configure-the-external-load-balancer).
The load balancers used for testing were HAProxy for Linux package environments or equivalent Cloud Provider services with NGINX Ingress for Cloud Native Hybrids. These selections do not represent a specific requirement or recommendation as most [reputable load balancers are expected to work](#configure-the-external-load-balancer).
## Set up components
@ -511,7 +511,7 @@ A reputable provider or solution should be used for this. [Google Cloud SQL](htt
If you use a third party external service:
1. Note that the HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. The HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. Set up PostgreSQL according to the
[database requirements document](../../install/requirements.md#database).
1. Set up a `gitlab` username with a password of your choice. The `gitlab` user
@ -532,7 +532,7 @@ replication and failover requires:
- An [internal load balancer](#configure-the-internal-load-balancer) (TCP) to balance requests between the PgBouncer nodes.
- [Database Load Balancing](../postgresql/database_load_balancing.md) enabled.
A local PgBouncer service to be configured on each PostgreSQL node. Note that this is separate from the main PgBouncer cluster that tracks the primary.
A local PgBouncer service to be configured on each PostgreSQL node. This is separate from the main PgBouncer cluster that tracks the primary.
The following IPs are used as an example:
@ -1965,7 +1965,7 @@ the [HTTPS documentation](https://docs.gitlab.com/omnibus/settings/ssl/index.htm
gitlab-rake gitlab:db:configure
```
Note that this requires the Rails node to be configured to connect to the primary database
This operation requires configuring the Rails node to connect to the primary database
directly, [bypassing PgBouncer](../postgresql/pgbouncer.md#procedure-for-bypassing-pgbouncer).
After migrations have completed, you must configure the node to pass through PgBouncer again.
@ -2170,7 +2170,7 @@ services where applicable):
1. Can be optionally run on reputable third-party external PaaS PostgreSQL solutions. See [Provide your own PostgreSQL instance](#provide-your-own-postgresql-instance) for more information.
2. Can be optionally run on reputable third-party external PaaS Redis solutions. See [Provide your own Redis instance](#provide-your-own-redis-instance) for more information.
3. Recommended to be run with a reputable third-party load balancer or service (LB PaaS).
Also note that sizing depends on selected Load Balancer as well as additional factors such as Network Bandwidth. Refer to [Load Balancers](index.md#load-balancers) for more information.
Also, the sizing depends on selected Load Balancer and additional factors such as Network Bandwidth. Refer to [Load Balancers](index.md#load-balancers) for more information.
4. Should be run on reputable Cloud Provider or Self Managed solutions. See [Configure the object storage](#configure-the-object-storage) for more information.
5. Gitaly Cluster provides the benefits of fault tolerance, but comes with additional complexity of setup and management.
Review the existing [technical limitations and considerations before deploying Gitaly Cluster](../gitaly/index.md#before-deploying-gitaly-cluster). If you want sharded Gitaly, use the same specs listed above for `Gitaly`.
@ -2268,9 +2268,9 @@ For further information on Webservice resource usage, see the Charts documentati
##### NGINX
It's also recommended deploying the NGINX controller pods across the Webservice nodes as a DaemonSet. This is to allow the controllers to scale dynamically with the Webservice pods they serve as well as take advantage of the higher network bandwidth larger machine types typically have.
It's also recommended deploying the NGINX controller pods across the Webservice nodes as a DaemonSet. It allows the controllers to scale dynamically with the Webservice pods they serve and take advantage of the higher network bandwidth larger machine types typically have.
Note that this isn't a strict requirement. The NGINX controller pods can be deployed as desired as long as they have enough resources to handle the web traffic.
This isn't a strict requirement. The NGINX controller pods can be deployed as desired as long as they have enough resources to handle the web traffic.
#### Sidekiq

View File

@ -216,11 +216,11 @@ CPU targets being the lowest common denominator to ensure the widest range of co
- The [`n1` series](https://cloud.google.com/compute/docs/general-purpose-machines#n1_machines) for GCP.
- The [`m5` series](https://aws.amazon.com/ec2/instance-types/) for AWS.
Depending on other requirements such as memory or network bandwidth as well as cloud provider availability, different machine types are used accordingly throughout the architectures, but it is expected that the target CPUs above should perform well.
Depending on other requirements such as memory or network bandwidth and cloud provider availability, different machine types are used accordingly throughout the architectures, but it is expected that the target CPUs above should perform well.
If you want, you can select a newer machine type series and have improved performance as a result.
Additionally, ARM CPUs are supported for Linux package environments as well as for any [Cloud Provider services](#cloud-provider-services) where applicable.
Additionally, ARM CPUs are supported for Linux package environments and for any [Cloud Provider services](#cloud-provider-services) where applicable.
NOTE:
Any "burstable" instance types are not recommended due to inconsistent performance.
@ -251,10 +251,10 @@ See [Recommended cloud providers and services](index.md#recommended-cloud-provid
The reference architectures were tested with repositories of varying sizes that follow best practices.
**However, [large monorepos](../../user/project/repository/monorepos/index.md) (several gigabytes or more) can significantly impact the performance of Git and in turn the environment itself.**
Their presence, as well as how they are used, can put a significant strain on the entire system from Gitaly through to the underlying infrastructure.
Their presence, and how they are used, can put a significant strain on the entire system from Gitaly through to the underlying infrastructure.
WARNING:
If this applies to you, we strongly recommended referring to the linked documentation as well as reaching out to your [Customer Success Manager](https://handbook.gitlab.com/job-families/sales/customer-success-management/) or our [Support team](https://about.gitlab.com/support/) for further guidance.
If this applies to you, we strongly recommended referring to the linked documentation and reaching out to your [Customer Success Manager](https://handbook.gitlab.com/job-families/sales/customer-success-management/) or our [Support team](https://about.gitlab.com/support/) for further guidance.
As such, large monorepos come with notable cost. If you have such a repository we strongly recommend
the following guidance is followed to ensure the best chance of good performance and to keep costs in check:
@ -415,7 +415,7 @@ Additionally, the following cloud provider services are recommended for use as p
If you choose to use a third party external service:
1. Note that the HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. The HA Linux package PostgreSQL setup encompasses PostgreSQL, PgBouncer and Consul. All of these components would no longer be required when using a third party external service.
1. The number of nodes required to achieve HA may differ depending on the service compared to the Linux package and doesn't need to match accordingly.
1. It's recommended in general to enable Read Replicas for [Database Load Balancing](../postgresql/database_load_balancing.md) if possible, matching the node counts for the standard Linux package deployment. This recommendation is especially so for larger environments (over 200 RPS / 10k users).
1. Ensure that if a pooler is offered as part of the service that it can handle the total load without bottlenecking.
@ -433,7 +433,7 @@ Several database cloud provider services are known not to support the above or h
### Recommendation notes for the Redis services
[When selecting to use an external Redis service](../redis/replication_and_failover_external.md#redis-as-a-managed-service-in-a-cloud-provider), it should run a standard, performant, and supported version. Note that this specifically must not be run in [Cluster mode](../../install/requirements.md#redis) as this is unsupported by GitLab.
[When selecting to use an external Redis service](../redis/replication_and_failover_external.md#redis-as-a-managed-service-in-a-cloud-provider), it should run a standard, performant, and supported version. This specifically must not be run in [Cluster mode](../../install/requirements.md#redis) as this is unsupported by GitLab.
Redis is primarily single threaded. For environments targeting up to 200 RPS / 10,000 users or higher, separate out the instances as specified into Cache and Persistent data to achieve optimum performance at this scale.
@ -498,7 +498,7 @@ remain compliant.
### Why we perform the tests
The Quality Department has a focus on measuring and improving the performance
of GitLab, as well as creating and validating reference architectures that
of GitLab, and creating and validating reference architectures that
self-managed customers can rely on as performant configurations.
For more information, see our [handbook page](https://handbook.gitlab.com/handbook/engineering/infrastructure/test-platform/performance-and-scalability/).
@ -513,7 +513,7 @@ Testing occurs against all reference architectures and cloud providers in an aut
Network latency on the test environments between components on all Cloud Providers were measured at <5 ms. This is shared as an observation and not as an implicit recommendation.
We aim to have a "test smart" approach where architectures tested have a good range that can also apply to others. Testing focuses on a 10k Linux package
installation on GCP as the testing has shown this is a good bellwether for the other architectures and cloud providers as well as Cloud Native Hybrids.
installation on GCP as the testing has shown this is a good bellwether for the other architectures and cloud providers and Cloud Native Hybrids.
The Standard Reference Architectures are designed to be platform-agnostic, with everything being run on VMs through [the Linux package](https://docs.gitlab.com/omnibus/). While testing occurs primarily on GCP, ad-hoc testing has shown that they perform similarly on hardware with equivalent specs on other Cloud Providers or if run on premises (bare-metal).
@ -635,9 +635,9 @@ table.test-coverage th {
## Cost calculator templates
As a starting point, the following table lists initial compute calculator cost templates for the different reference architectures across GCP, AWS, and Azure via each cloud provider's official calculator.
As a starting point, the following table lists initial compute calculator cost templates for the different reference architectures across GCP, AWS, and Azure by using each cloud provider's official calculator.
However, please be aware of the following caveats:
However, be aware of the following caveats:
- These are only rough estimate compute templates for the Linux package architectures.
- They do not take into account dynamic elements such as disk, network or object storage - Which can notably impact costs.
@ -710,7 +710,7 @@ To get an accurate estimate of costs for your specific environment you must take
Maintaining a Reference Architecture environment is generally the same as any other GitLab environment is generally covered in other sections of this documentation.
In this section you'll find links to documentation for relevant areas as well as any specific Reference Architecture notes.
In this section you'll find links to documentation for relevant areas and any specific Reference Architecture notes.
### Scaling an environment
@ -719,7 +719,7 @@ The Reference Architectures have been designed as a starting point and are elast
NOTE:
If you're seeing a component continuously exhausting it's given resources it's strongly recommended for you to reach out to our [Support team](https://about.gitlab.com/support/) before performing any scaling. This is especially so if you're planning to scale any component significantly.
For most components vertical and horizontal scaling can be applied as normal. However, before doing so though please be aware of the below caveats:
For most components vertical and horizontal scaling can be applied as usual. However, before doing so, be aware of the below caveats:
- When scaling Puma or Sidekiq vertically the amount of workers will need to be adjusted to use the additional specs. Puma will be scaled automatically on the next reconfigure but Sidekiq will need [its configuration changed beforehand](../sidekiq/extra_sidekiq_processes.md#start-multiple-processes).
- Redis and PgBouncer are primarily single threaded. If these components are seeing CPU exhaustion they may need to be scaled out horizontally.
@ -739,13 +739,13 @@ The following components can impact others when they have been significantly sca
- Puma and Sidekiq - Notable scale ups of either Puma or Sidekiq workers will result in higher concurrent connections to the internal load balancer, PostgreSQL (via PgBouncer if present), Gitaly (via Praefect if present) and Redis respectively.
- Redis is primarily single threaded and in some cases may need to be split up into different instances (Cache / Persistent) if the increased throughput causes CPU exhaustion if a combined cluster is currently being used.
- PgBouncer is also single threaded but note that a scale out will result in a new pool being added that in turn will increase total connections to Postgres. It's strongly recommended to only do this if you have experience in managing Postgres connections and to seek assistance if in doubt.
- PgBouncer is also single threaded but a scale out might result in a new pool being added that in turn might increase the total connections to Postgres. It's strongly recommended to only do this if you have experience in managing Postgres connections and to seek assistance if in doubt.
- Gitaly Cluster / PostgreSQL - A notable scale out of additional nodes can have a detrimental effect on the HA system and performance due to increased replication calls to the primary node.
#### Scaling from a non-HA to an HA architecture
While in most cases vertical scaling is only required to increase an environment's resources, if you are moving to an HA environment
additional steps will be required for the following components to switch over to their HA forms respectively by following the given
additional steps are required for the following components to switch over to their HA forms respectively by following the given
documentation for each as follows
- [Redis to multi-node Redis w/ Redis Sentinel](../redis/replication_and_failover.md#switching-from-an-existing-single-machine-installation)
@ -764,9 +764,9 @@ You should upgrade a Reference Architecture in the same order as you created it.
### Monitoring
There are numerous options available to monitor your infrastructure, as well as [GitLab itself](../monitoring/index.md), and you should refer to your selected monitoring solution's documentation for more information.
There are numerous options available to monitor your infrastructure, and [GitLab itself](../monitoring/index.md), and you should refer to your selected monitoring solution's documentation for more information.
Of note, the GitLab application is bundled with [Prometheus as well as various Prometheus compatible exporters](../monitoring/prometheus/index.md) that could be hooked into your solution.
Of note, the GitLab application is bundled with [Prometheus and various Prometheus compatible exporters](../monitoring/prometheus/index.md) that could be hooked into your solution.
## Update history
@ -790,7 +790,7 @@ You can find a full history of changes [on the GitLab project](https://gitlab.co
**2023:**
- [2023-12-12](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/139557): Updated notes on Load Balancers to be more reflective that any reputable offering is expected to work.
- [2023-11-03](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/133457): Expanded details on what each Reference Architecture is designed for, the testing methodology used as well as added details on how to scale environments.
- [2023-11-03](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/133457): Expanded details on what each Reference Architecture is designed for, the testing methodology used and added details on how to scale environments.
- [2023-11-03](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/134518): Added expanded notes on disk types, object storage and monitoring.
- [2023-10-25](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/134518): Adjusted Sidekiq configuration example to use Linux Package role.
- [2023-10-15](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/133835): Adjusted the Sidekiq recommendations to include a separate node for 2k and tweaks to instance type and counts for 3k and 5k.
@ -802,7 +802,7 @@ You can find a full history of changes [on the GitLab project](https://gitlab.co
- [2023-08-30](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/130470): Expanded section on Geo under the Decision Tree.
- [2023-08-08](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/128529): Switch config example to use the Sidekiq role for Linux package.
- [2023-08-03](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/128374): Fixed an AWS Machine type typo for the 50k architecture.
- [2023-11-03](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/133457): Expand details on what each Reference Architecture is designed for, the testing methodology used as well as added details on how to scale environments.
- [2023-11-03](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/133457): Expand details on what each Reference Architecture is designed for, the testing methodology used and added details on how to scale environments.
- [2023-11-03](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/134518): Add expanded notes on disk types, object storage and monitoring.
- [2023-10-25](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/134518): Adjust Sidekiq configuration example to use Linux Package role.
- [2023-10-15](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/133835): Adjust the Sidekiq recommendations to include a separate node for 2k and tweaks to instance type and counts for 3k and 5k.
@ -846,7 +846,7 @@ You can find a full history of changes [on the GitLab project](https://gitlab.co
- [2022-09-22](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/98263): Add explicit step to enable Incremental Logging when only Object Storage is being used.
- [2022-09-22](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/98184): Expand guidance on recommended cloud providers and services.
- [2022-09-09](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/97245): Expand Object Storage guidance and updated that NFS support for Git data ends with `15.6`.
- [2022-08-24](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96150): Add clearer note that Gitaly Cluster is not supported in Kubernetes.
- [2022-08-24](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96150): Add a clearer note that Gitaly Cluster is not supported in Kubernetes.
- [2022-08-24](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/96021): Add section on supported CPUs and types.
- [2022-08-18](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95713): Update architecture tables to be clearer for Object Storage support.
- [2022-08-17](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95185): Increase Cloud Native Hybrid pool specs for 2k architecture to ensure enough resources present for pods. Also increased Sidekiq worker count.
@ -862,7 +862,7 @@ You can find a full history of changes [on the GitLab project](https://gitlab.co
- [2022-04-08](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/84389): Add cost estimates for AWS and Azure.
- [2022-04-06](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/84483): Update configuration examples for most components to be correctly included for Prometheus monitoring auto discovery.
- [2022-03-30](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81538): Expand validation and testing result's section with more clearly language and more detail.
- [2022-03-21](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83019): Add note that additional specs may be needed for Gitaly in some scenarios.
- [2022-03-21](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/83019): Add a note that additional specs may be needed for Gitaly in some scenarios.
- [2022-03-04](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82087): Add guidance for preventing the GitLab KAS service running on nodes where not required.
- [2022-03-01](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81814): Fix a typo for Praefect TLS port in configuration examples.
- [2022-02-22](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/81247): Add guidance to enable the Gitaly Pack-objects cache.
@ -883,7 +883,7 @@ You can find a full history of changes [on the GitLab project](https://gitlab.co
- [2021-11-24](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/74612): Add recommendations for Database Load Balancing.
- [2021-11-04](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73634): Add more detail about testing targets used for the architectures.
- [2021-10-13](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/72052): Add guidance around optionally enabling Incremental Logging via Redis.
- [2021-10-07](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71784): Update Sidekiq config to include required `external_url` setting.
- [2021-10-07](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71784): Update Sidekiq configuration to include required `external_url` setting.
- [2021-10-02](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71576): Expand guidance around Gitaly Cluster and Gitaly Sharded.
- [2021-09-29](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70625): Add note on what Cloud Native Hybrid architecture to use with small user counts.
- [2021-09-27](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/70602): Change guidance to now co-locate Redis Sentinel beside Redis on the same node.

View File

@ -0,0 +1,208 @@
---
stage: Govern
group: Authentication
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
---
# Group service accounts
DETAILS:
**Tier:** Premium, Ultimate
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
Interact with [service accounts](../user/profile/service_accounts.md) by using the REST API.
## List service account users
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/416729) in GitLab 17.1.
Prerequisites:
- You must be an administrator of the self-managed instance, or have the Owner role for the group.
Lists all service account users that are provisioned by group.
This function takes pagination parameters `page` and `per_page` to restrict the list of users.
```plaintext
GET /groups/:id/service_accounts
```
Parameters:
| Attribute | Type | Required | Description |
|:-------------|:---------|:-----------|:----------------------------------------------------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the target group](rest/index.md#namespaced-path-encoding). |
| `order_by` | string | no | Orders list of users by `username` or `id`. Default is `id`. |
| `sort` | string | no | Specifies sorting by `asc` or `desc`. Default is `desc`. |
Example request:
```shell
curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/345/service_accounts"
```
Example response:
```json
[
{
"id": 57,
"username": "service_account_group_345_<random_hash>",
"name": "Service account user"
},
{
"id": 58,
"username": "service_account_group_346_<random_hash>",
"name": "Service account user"
}
]
```
## Create a service account user
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/407775) in GitLab 16.1.
> - Ability to specify a username or name was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/144841) in GitLab 16.10.
Creates a service account user.
This API endpoint works on top-level groups only. It does not work on subgroups.
```plaintext
POST /groups/:id/service_accounts
```
Supported attributes:
| Attribute | Type | Required | Description |
|:---------------------------|:---------------|:--------------------------|:-------------------------------------------------------------------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the target group](rest/index.md#namespaced-path-encoding). |
| `name` | string | no | The name of the user. If not specified, the default `Service account user` name is used. |
| `username` | string | no | The username of the user. If not specified, it's automatically generated. |
Example request:
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/345/service_accounts"
```
Example response:
```json
{
"id": 57,
"username": "service_account_group_345_6018816a18e515214e0c34c2b33523fc",
"name": "Service account user"
}
```
## Delete a service account user
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/416729) in GitLab 17.1.
Deletes a service account user.
This API endpoint works on top-level groups only. It does not work on subgroups.
```plaintext
DELETE /groups/:id/service_accounts/:user_id
```
Parameters:
| Attribute | Type | Required | Description |
|:---------------------------|:---------------|:--------------------------|:-------------------------------------------------------------------------------|
| `id` | integer/string | yes | The ID or [URL-encoded path of the target group](rest/index.md#namespaced-path-encoding). |
| `user_id` | integer | yes | The ID of a service account user. |
| `hard_delete` | boolean | no | If true, contributions that would usually be [moved to a Ghost User](../user/profile/account/delete_account.md#associated-records) are instead deleted, as well as groups owned solely by this service account user. |
Example request:
```shell
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/345/service_accounts/181"
```
## Create a personal access token for a service account user
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/406781) in GitLab 16.1.
This API endpoint works on top-level groups only. It does not work on subgroups.
```plaintext
POST /groups/:id/service_accounts/:user_id/personal_access_tokens
```
Parameters:
| Attribute | Type | Required | Description |
| --------- | --------------- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the target group](rest/index.md#namespaced-path-encoding). |
| `user_id` | integer | yes | The ID of a service account user. |
| `name` | string | yes | The name of the personal access token. |
| `scopes` | array | yes | Array of scopes of the personal access token. See [personal access token scopes](../user/profile/personal_access_tokens.md#personal-access-token-scopes) for possible values. |
| `expires_at` | date | no | The personal access token expiry date. When left blank, the token follows the [standard rule of expiry for personal access tokens](../user/profile/personal_access_tokens.md#when-personal-access-tokens-expire). |
Example request:
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/35/service_accounts/71/personal_access_tokens" --data "scopes[]=api,read_user,read_repository" --data "name=service_accounts_token"
```
Example response:
```json
{
"id":6,
"name":"service_accounts_token",
"revoked":false,
"created_at":"2023-06-13T07:47:13.900Z",
"scopes":["api"],
"user_id":71,
"last_used_at":null,
"active":true,
"expires_at":"2024-06-12",
"token":"<token_value>"
}
```
## Rotate a personal access token for a service account user
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/406781) in GitLab 16.1.
This API endpoint works on top-level groups only. It does not work on subgroups.
```plaintext
POST /groups/:id/service_accounts/:user_id/personal_access_tokens/:token_id/rotate
```
Parameters:
| Attribute | Type | Required | Description |
| --------- | --------------- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the target group](rest/index.md#namespaced-path-encoding). |
| `user_id` | integer | yes | The ID of the service account user. |
| `token_id` | integer | yes | The ID of the token. |
Example request:
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/35/service_accounts/71/personal_access_tokens/6/rotate"
```
Example response:
```json
{
"id":7,
"name":"service_accounts_token",
"revoked":false,
"created_at":"2023-06-13T07:54:49.962Z",
"scopes":["api"],
"user_id":71,
"last_used_at":null,
"active":true,
"expires_at":"2023-06-20",
"token":"<token_value>"
}
```

View File

@ -1610,186 +1610,6 @@ Example response:
]
```
## Service Accounts
DETAILS:
**Tier:** Premium, Ultimate
**Offering:** GitLab.com, Self-managed, GitLab Dedicated
### List Service Account Users
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/416729) in GitLab 17.1.
Prerequisites:
- You must be an administrator of the self-managed instance, or have the Owner role for the group.
Lists all service account users that are provisioned by group.
This function takes pagination parameters `page` and `per_page` to restrict the list of users.
```plaintext
GET /groups/:id/service_accounts
```
Example request:
```shell
curl --request GET --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/345/service_accounts"
```
Supported attributes:
| Attribute | Type | Required | Description |
|:-------------|:---------|:-----------|:----------------------------------------------------------------|
| `order_by` | string | no | Orders list of users by `username` or `id`. Default is `id`. |
| `sort` | string | no | Specifies sorting by `asc` or `desc`. Default is `desc`. |
Example response:
```json
[
{
"id": 57,
"username": "service_account_group_345_<random_hash>",
"name": "Service account user"
},
{
"id": 58,
"username": "service_account_group_345_<random_hash>",
"name": "Service account user"
}
]
```
### Create Service Account User
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/407775) in GitLab 16.1.
> - Ability to specify a username or name was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/144841) in GitLab 16.10.
Creates a service account user. You can specify username and name. If you do not specify these attributes, the default name is `Service account user` and the username is automatically generated.
This API endpoint works on top-level groups only. It does not work on subgroups.
```plaintext
POST /groups/:id/service_accounts
```
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/345/service_accounts"
```
Supported attributes:
| Attribute | Type | Required | Description |
|:---------------------------|:---------------|:--------------------------|:-------------------------------------------------------------------------------|
| `name` | string | no | Name of the user |
| `username` | string | no | Username of the user |
Example response:
```json
{
"id": 57,
"username": "service_account_group_345_6018816a18e515214e0c34c2b33523fc",
"name": "Service account user"
}
```
### Delete Service Account User
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/416729) in GitLab 17.1.
Deletes a service account user. You specify the ID of the service account user to be deleted.
This API endpoint works on top-level groups only. It does not work on subgroups.
```plaintext
DELETE /groups/:id/service_accounts/:user_id
```
Example request:
```shell
curl --request DELETE --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/345/service_accounts/181"
```
Supported attributes:
| Attribute | Type | Required | Description |
|:---------------------------|:---------------|:--------------------------|:-------------------------------------------------------------------------------|
| `id` | integer | yes | ID of a service account user. |
| `hard_delete` | boolean | no | If true, contributions that would usually be [moved to a Ghost User](../user/profile/account/delete_account.md#associated-records) are deleted instead, as well as groups owned solely by this service account user. |
### Create personal access token for Service Account User
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/406781) in GitLab 16.1.
```plaintext
POST /groups/:id/service_accounts/:user_id/personal_access_tokens
```
This API endpoint works on top-level groups only. It does not work on subgroups.
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/35/service_accounts/71/personal_access_tokens" --data "scopes[]=api,read_user,read_repository" --data "name=service_accounts_token"
```
Example response:
```json
{
"id":6,
"name":"service_accounts_token",
"revoked":false,
"created_at":"2023-06-13T07:47:13.900Z",
"scopes":["api"],
"user_id":71,
"last_used_at":null,
"active":true,
"expires_at":"2024-06-12",
"token":"<token_value>"
}
```
| Attribute | Type | Required | Description |
| --------- | --------------- | -------- | ----------- |
| `name` | string | yes | Name of the personal access token |
| `scopes` | array | yes | Array of scopes of the personal access token. See [personal access token scopes](../user/profile/personal_access_tokens.md#personal-access-token-scopes) for possible values. |
| `expires_at` | date | no | Personal access token expiry date. When left blank, the token follows the [standard rule of expiry for personal access tokens](../user/profile/personal_access_tokens.md#when-personal-access-tokens-expire). |
### Rotate a personal access token for Service Account User
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/406781) in GitLab 16.1.
```plaintext
POST /groups/:id/service_accounts/:user_id/personal_access_tokens/:token_id/rotate
```
This API endpoint works on top-level groups only. It does not work on subgroups.
```shell
curl --request POST --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/groups/35/service_accounts/71/personal_access_tokens/6/rotate"
```
Example response:
```json
{
"id":7,
"name":"service_accounts_token",
"revoked":false,
"created_at":"2023-06-13T07:54:49.962Z",
"scopes":["api"],
"user_id":71,
"last_used_at":null,
"active":true,
"expires_at":"2023-06-20",
"token":"<token_value>"
}
```
## Markdown uploads
Markdown uploads are files uploaded to a group that can be referenced in Markdown text in an epic or wiki page.

View File

@ -85,7 +85,7 @@ and [Container Registry](../../../user/packages/container_registry/index.md).
Now you have a containerized application image that can be pulled from AWS. Next, you define the
spec of how this application image is used in AWS.
Note that the `production_ecs` job fails because ECS Cluster is not connected yet. You'll fix this
The `production_ecs` job fails because ECS Cluster is not connected yet. You can fix this
later.
### Create an ECS task definition
@ -164,7 +164,7 @@ is a daemon to create an application container based on the [ECS task definition
![An active service running.](img/service-running.png)
Note that AWS's console UI changes from time to time. If you can't find a relevant component in the
The AWS's console UI changes from time to time. If you can't find a relevant component in the
instructions, select the closest one.
### View the demo application

View File

@ -876,8 +876,8 @@ Git operations over HTTP use the stateless "smart" protocol described in the
[Git documentation](https://git-scm.com/docs/http-protocol), but responsibility
for handling these operations is split across several GitLab components.
Here is a sequence diagram for `git fetch`. Note that all requests pass through
NGINX as well as any other HTTP load balancers, but are not transformed in any
Here is a sequence diagram for `git fetch`. All requests pass through
NGINX and any other HTTP load balancers, but are not transformed in any
way by them. All paths are presented relative to a `/namespace/project.git` URL.
```mermaid
@ -927,7 +927,7 @@ To the SSH server, all connections are authenticated as the `git` user; GitLab
users are differentiated by the SSH key presented by the client.
Here is a sequence diagram for `git fetch`, assuming [Fast SSH key lookup](../administration/operations/fast_ssh_key_lookup.md)
is enabled. Note that `AuthorizedKeysCommand` is an executable provided by
is enabled. `AuthorizedKeysCommand` is an executable provided by
[GitLab Shell](#gitlab-shell):
```mermaid

View File

@ -663,7 +663,7 @@ WARNING:
circling back with the author about that. Otherwise, if the MR only has a few commits, we'll
be respecting the author's setting by not squashing them.
- Go to the merge request's **Pipelines** tab, and select **Run pipeline**. Then, on the **Overview** tab, enable **Auto-merge**.
Note that:
Consider the following information:
- If **[the default branch is broken](https://handbook.gitlab.com/handbook/engineering/workflow/#broken-master),
do not merge the merge request** except for
[very specific cases](https://handbook.gitlab.com/handbook/engineering/workflow/#criteria-for-merging-during-broken-master).

View File

@ -0,0 +1,26 @@
---
stage: none
group: unassigned
info: Any user with at least the Maintainer role can merge updates to this content. For details, see https://docs.gitlab.com/ee/development/development_processes.html#development-guidelines-review.
---
# Cookies
In general, there is usually a better place to store data for users than in cookies. For backend development PostgreSQL, Redis, and [session storage](session.md) are available. For frontend development, cookies may be more secure than `localStorage`, `IndexedDB` or other options.
In general do not put sensitive information such as user IDs, potentially user-identifying information, tokens, or other secrets into cookies. See our [Secure Coding Guidelines](secure_coding_guidelines.md) for more information.
## Cookies on Rails
Ruby on Rails has cookie setting and retrieval [built-in to ActionController](https://guides.rubyonrails.org/action_controller_overview.html#cookies). Rails uses a cookie to track the user's session ID, which allows access to session storage. [Devise also sets a cookie](https://github.com/heartcombo/devise/blob/main/lib/devise/strategies/rememberable.rb) when users select the **Remember Me** checkbox when signing in, which allows a user to re-authenticate after closing and re-opening a browser.
You can [set cookies with options](https://api.rubyonrails.org/v7.1.3.4/classes/ActionDispatch/Cookies.html) such as `:path` , `:expires`, `:domain` , and `:httponly` . Do not change from the defaults for these options unless it is required for the functionality you are implementing.
WARNING:
[Cookies set by GitLab are unset by default when users log out](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/controllers/sessions_controller.rb#L104). If you set a cookie with the `:domain` option, that cookie must be unset using the same `:domain` parameter. Otherwise the browser will not actually clear the cookie, and we risk persisting potentially-sensitive data which should have been cleared.
## Cookies in Frontend Code
Some of our frontend code sets cookies for persisting data during a session, such as dismissing alerts or sidebar position preferences. We use the [`setCookie` and `getCookie` helpers from `common_utils`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app/assets/javascripts/lib/utils/common_utils.js#L697) to apply reasonable defaults to these cookies.
Be aware that, after 2021, browsers have started [aggressively purging cookies](https://clearcode.cc/blog/browsers-first-third-party-cookies/) and `localStorage` data set by JavaScript scripts in an effort to fight tracking scripts. If cookies seem to be unset every day or every few days, it is possible the data is getting purged, and you might want to preserve the data server-side rather than in browser-local storage.

View File

@ -104,27 +104,57 @@ The new connection should be working now.
## Access the GDK database with Visual Studio Code
Use these instructions for exploring the GitLab database while developing with the GDK:
Create a database connection using the PostgreSQL extension in Visual Studio Code to access and
explore the GDK database.
1. Install or open [Visual Studio Code](https://code.visualstudio.com/download).
1. Install the [PostgreSQL VS Code Extension](https://marketplace.visualstudio.com/items?itemName=ckolkman.vscode-postgres).
1. In Visual Studio Code select **PostgreSQL Explorer** in the left toolbar.
1. In the top bar of the new window, select `+` to **Add Database Connection**, and follow the prompts to fill in the details:
1. **Hostname**: the path to the PostgreSQL folder in your GDK directory (for example `/dev/gitlab-development-kit/postgresql`).
1. **PostgreSQL user to authenticate as**: usually your local username, unless otherwise specified during PostgreSQL installation.
1. **Password of the PostgreSQL user**: the password you set when installing PostgreSQL.
1. **Port number to connect to**: `5432` (default).
1. **Use an SSL connection?** This depends on your installation. Options are:
- **Use Secure Connection**
- **Standard Connection** (default)
1. **Optional. The database to connect to**: `gitlabhq_development`.
1. **The display name for the database connection**: `gitlabhq_development`.
Prerequisites:
Your database connection should now be displayed in the PostgreSQL Explorer pane and
you can explore the `gitlabhq_development` database. If you cannot connect, ensure
that GDK is running. For further instructions on how to use the PostgreSQL Explorer
Extension for Visual Studio Code, read the [usage section](https://marketplace.visualstudio.com/items?itemName=ckolkman.vscode-postgres#usage)
of the extension documentation.
- [Visual Studio (VS) Code](https://code.visualstudio.com/download).
- [PostgreSQL](https://marketplace.visualstudio.com/items?itemName=ckolkman.vscode-postgres) VS Code extension.
To create a database connection:
1. In the activity bar, select the **PostgreSQL Explorer** icon.
1. From the opened pane, select **+** to add a new database connection:
1. Enter the **hostname** of the database. Use the path to the PostgreSQL folder in your GDK directory.
- Example: `/dev/gitlab-development-kit/postgresql`
1. Enter a **PostgreSQL user to authenticate as**.
Use your local username unless otherwise specified during PostgreSQL installation.
To verify your PostgreSQL username:
1. Ensure you are in the `gitlab` directory.
1. Access the PostgreSQL database. Run `rails db`. The output should look like:
```shell
psql (14.9)
Type "help" for help.
gitlabhq_development=#
```
1. In the returned PostgreSQL prompt, run `\conninfo` to display the connected user and
the port used to establish the connection. For example:
```shell
You are connected to database "gitlabhq_development" as user "root" on host "localhost" (address "127.0.0.1") at port "5432".
```
1. When prompted to enter the **password of the PostgreSQL user**, enter the password you set or leave the field blank.
- As you are logged in to the same machine that the Postgres server is running on, a password is not required.
1. Enter**Port number to connect to**. The default port number is`5432`.
1. In the **use an SSL connection?** field, select the appropriate connection for your
installation. The options are:
- **Use Secure Connection**
- **Standard Connection** (default)
1. In the optional **database to connect to** field, enter `gitlabhq_development`.
1. In the **display name for the database connection** field, enter `gitlabhq_development`.
Your `gitlabhq_development` database connection is now displayed in the **PostgreSQL Explorer** pane.
Use the arrows to expand and explore the contents of the GDK database.
If you cannot connect, first ensure that GDK is running and try again. For further instructions on how
to use the PostgreSQL Explorer extension for VS Code, see
the [usage section](https://marketplace.visualstudio.com/items?itemName=ckolkman.vscode-postgres#usage)
of the extension's documentation.
## FAQ

Some files were not shown because too many files have changed in this diff Show More