diff options
73 files changed, 904 insertions, 391 deletions
diff --git a/GITALY_SERVER_VERSION b/GITALY_SERVER_VERSION index 117ac1eafa6..43783a08440 100644 --- a/GITALY_SERVER_VERSION +++ b/GITALY_SERVER_VERSION @@ -1 +1 @@ -e6affcb248bd2254076d25f5904428e48559acaf +829d1e19bdccd6fd6e23684571d7bc483d2afa37 diff --git a/app/assets/javascripts/comment_templates/components/form.vue b/app/assets/javascripts/comment_templates/components/form.vue index 334c67ca339..0dadec7a5c5 100644 --- a/app/assets/javascripts/comment_templates/components/form.vue +++ b/app/assets/javascripts/comment_templates/components/form.vue @@ -5,6 +5,7 @@ import MarkdownField from '~/vue_shared/components/markdown/field.vue'; import { helpPagePath } from '~/helpers/help_page_helper'; import { logError } from '~/lib/logger'; import { __ } from '~/locale'; +import { InternalEvents } from '~/tracking'; import createSavedReplyMutation from '../queries/create_saved_reply.mutation.graphql'; import updateSavedReplyMutation from '../queries/update_saved_reply.mutation.graphql'; @@ -17,6 +18,7 @@ export default { GlAlert, MarkdownField, }, + mixins: [InternalEvents.mixin()], props: { id: { type: String, @@ -91,6 +93,7 @@ export default { this.$emit('saved'); this.updateCommentTemplate = { name: '', content: '' }; this.showValidation = false; + this.track_event('i_code_review_saved_replies_create'); } }, }) diff --git a/app/assets/javascripts/deploy_freeze/components/deploy_freeze_modal.vue b/app/assets/javascripts/deploy_freeze/components/deploy_freeze_modal.vue index b13b0ede9f0..e1c47fde81d 100644 --- a/app/assets/javascripts/deploy_freeze/components/deploy_freeze_modal.vue +++ b/app/assets/javascripts/deploy_freeze/components/deploy_freeze_modal.vue @@ -24,10 +24,10 @@ export default { static: true, lazy: true, }, - translations: { + i18n: { cronPlaceholder: '* * * * *', cronSyntaxInstructions: __( - 'Define a custom deploy freeze pattern with %{cronSyntaxStart}cron syntax%{cronSyntaxEnd}', + 'Define a custom deploy freeze pattern with %{cronSyntaxStart}cron syntax%{cronSyntaxEnd}.', ), addTitle: __('Add deploy freeze'), editTitle: __('Edit deploy freeze'), @@ -81,9 +81,7 @@ export default { return Boolean(this.selectedId); }, modalTitle() { - return this.isEditing - ? this.$options.translations.editTitle - : this.$options.translations.addTitle; + return this.isEditing ? this.$options.i18n.editTitle : this.$options.i18n.addTitle; }, }, methods: { @@ -104,6 +102,13 @@ export default { this.addFreezePeriod(); } }, + focusFirstInput() { + if (this.$refs.freezeStartCron) { + setTimeout(() => { + this.$refs.freezeStartCron?.$el?.focus(); + }, 250); + } + }, }, }; </script> @@ -115,9 +120,10 @@ export default { :action-primary="addDeployFreezeButton" @primary="submit" @canceled="resetModalHandler" + @change="focusFirstInput" > <p> - <gl-sprintf :message="$options.translations.cronSyntaxInstructions"> + <gl-sprintf :message="$options.i18n.cronSyntaxInstructions"> <template #cronSyntax="{ content }"> <gl-link href="https://crontab.guru/" target="_blank">{{ content }}</gl-link> </template> @@ -132,11 +138,13 @@ export default { > <gl-form-input id="deploy-freeze-start" + ref="freezeStartCron" v-model="freezeStartCron" class="gl-font-monospace!" data-qa-selector="deploy_freeze_start_field" - :placeholder="$options.translations.cronPlaceholder" + :placeholder="$options.i18n.cronPlaceholder" :state="freezeStartCronState" + autofocus trim /> </gl-form-group> @@ -152,7 +160,7 @@ export default { v-model="freezeEndCron" class="gl-font-monospace!" data-qa-selector="deploy_freeze_end_field" - :placeholder="$options.translations.cronPlaceholder" + :placeholder="$options.i18n.cronPlaceholder" :state="freezeEndCronState" trim /> diff --git a/app/assets/javascripts/deploy_freeze/components/deploy_freeze_table.vue b/app/assets/javascripts/deploy_freeze/components/deploy_freeze_table.vue index 77767456f76..24ea8f01c20 100644 --- a/app/assets/javascripts/deploy_freeze/components/deploy_freeze_table.vue +++ b/app/assets/javascripts/deploy_freeze/components/deploy_freeze_table.vue @@ -1,39 +1,48 @@ <script> -import { GlTable, GlButton, GlModal, GlModalDirective, GlSprintf } from '@gitlab/ui'; +import { + GlCard, + GlTable, + GlButton, + GlIcon, + GlModal, + GlModalDirective, + GlSprintf, +} from '@gitlab/ui'; import { mapState, mapActions } from 'vuex'; -import { s__ } from '~/locale'; +import { __, s__ } from '~/locale'; export default { fields: [ { key: 'freezeStart', label: s__('DeployFreeze|Freeze start'), + tdClass: 'gl-vertical-align-middle!', }, { key: 'freezeEnd', label: s__('DeployFreeze|Freeze end'), + tdClass: 'gl-vertical-align-middle!', }, { key: 'cronTimezone', label: s__('DeployFreeze|Time zone'), + tdClass: 'gl-vertical-align-middle!', }, { - key: 'edit', - label: s__('DeployFreeze|Edit'), - }, - { - key: 'delete', - label: s__('DeployFreeze|Delete'), + key: 'actions', + label: __('Actions'), + thClass: 'gl-text-right', }, ], - translations: { + i18n: { + title: s__('DeployFreeze|Deploy freezes'), addDeployFreeze: s__('DeployFreeze|Add deploy freeze'), deleteDeployFreezeTitle: s__('DeployFreeze|Delete deploy freeze?'), deleteDeployFreezeMessage: s__( 'DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?', ), emptyStateText: s__( - 'DeployFreeze|No deploy freezes exist for this project. To add one, select %{strongStart}Add deploy freeze%{strongEnd}', + 'DeployFreeze|No deploy freezes exist for this project. To add one, select %{strongStart}Add deploy freeze%{strongEnd} above.', ), }, modal: { @@ -42,10 +51,16 @@ export default { text: s__('DeployFreeze|Delete freeze period'), attributes: { variant: 'danger', 'data-testid': 'modal-confirm' }, }, + actionSecondary: { + text: __('Cancel'), + attributes: { variant: 'default' }, + }, }, components: { + GlCard, GlTable, GlButton, + GlIcon, GlModal, GlSprintf, }, @@ -80,65 +95,78 @@ export default { </script> <template> - <div class="deploy-freeze-table"> + <gl-card + class="gl-new-card deploy-freeze-table" + header-class="gl-new-card-header" + body-class="gl-new-card-body gl-px-0" + > + <template #header> + <div class="gl-new-card-title-wrapper"> + <h3 class="gl-new-card-title">{{ $options.i18n.title }}</h3> + <span class="gl-new-card-count"> + <gl-icon name="deployments" class="gl-mr-2" /> + {{ freezePeriods.length }} + </span> + </div> + <div class="gl-new-card-actions"> + <gl-button v-gl-modal.deploy-freeze-modal size="small" data-testid="add-deploy-freeze">{{ + $options.i18n.addDeployFreeze + }}</gl-button> + </div> + </template> + <gl-table data-testid="deploy-freeze-table" :items="freezePeriods" :fields="$options.fields" show-empty - stacked="lg" + stacked="md" > <template #cell(cronTimezone)="{ item }"> {{ item.cronTimezone.formattedTimezone }} </template> - <template #cell(edit)="{ item }"> - <gl-button - v-gl-modal.deploy-freeze-modal - icon="pencil" - data-testid="edit-deploy-freeze" - :aria-label="__('Edit deploy freeze')" - @click="setFreezePeriod(item)" - /> - </template> - <template #cell(delete)="{ item }"> - <gl-button - v-gl-modal="$options.modal.id" - category="secondary" - variant="danger" - icon="remove" - :aria-label="$options.modal.actionPrimary.text" - :loading="item.isDeleting" - data-testid="delete-deploy-freeze" - @click="handleDeleteFreezePeriod(item)" - /> + <template #cell(actions)="{ item }"> + <div class="gl-display-flex gl-justify-content-end gl-mt-n2 gl-mb-n2"> + <gl-button + v-gl-modal.deploy-freeze-modal + icon="pencil" + data-testid="edit-deploy-freeze" + :aria-label="__('Edit deploy freeze')" + class="gl-mr-3" + @click="setFreezePeriod(item)" + /> + <gl-button + v-gl-modal="$options.modal.id" + category="secondary" + variant="danger" + icon="remove" + :aria-label="$options.modal.actionPrimary.text" + :loading="item.isDeleting" + data-testid="delete-deploy-freeze" + @click="handleDeleteFreezePeriod(item)" + /> + </div> </template> <template #empty> - <p data-testid="empty-freeze-periods" class="gl-text-center text-plain"> - <gl-sprintf :message="$options.translations.emptyStateText"> + <p data-testid="empty-freeze-periods" class="gl-text-secondary gl-text-center gl-mb-0"> + <gl-sprintf :message="$options.i18n.emptyStateText"> <template #strong="{ content }"> - <strong>{{ content }}</strong> + {{ content }} </template> </gl-sprintf> </p> </template> </gl-table> - <gl-button - v-gl-modal.deploy-freeze-modal - data-testid="add-deploy-freeze" - category="primary" - variant="confirm" - > - {{ $options.translations.addDeployFreeze }} - </gl-button> <gl-modal - :title="$options.translations.deleteDeployFreezeTitle" + :title="$options.i18n.deleteDeployFreezeTitle" :modal-id="$options.modal.id" :action-primary="$options.modal.actionPrimary" + :action-secondary="$options.modal.actionSecondary" static @primary="confirmDeleteFreezePeriod" > <template v-if="freezePeriodToDelete"> - <gl-sprintf :message="$options.translations.deleteDeployFreezeMessage"> + <gl-sprintf :message="$options.i18n.deleteDeployFreezeMessage"> <template #start> <code>{{ freezePeriodToDelete.freezeStart }}</code> </template> @@ -149,5 +177,5 @@ export default { </gl-sprintf> </template> </gl-modal> - </div> + </gl-card> </template> diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue index bb2ca838279..b58e2249829 100644 --- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue +++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/components/details_page/tags_list.vue @@ -6,6 +6,7 @@ import { fetchPolicies } from '~/lib/graphql'; import { joinPaths } from '~/lib/utils/url_utility'; import Tracking from '~/tracking'; import RegistryList from '~/packages_and_registries/shared/components/registry_list.vue'; +import PersistedPagination from '~/packages_and_registries/shared/components/persisted_pagination.vue'; import PersistedSearch from '~/packages_and_registries/shared/components/persisted_search.vue'; import TagsLoader from '~/packages_and_registries/shared/components/tags_loader.vue'; import { FILTERED_SEARCH_TERM } from '~/vue_shared/components/filtered_search_bar/constants'; @@ -27,6 +28,7 @@ import { import getContainerRepositoryTagsQuery from '../../graphql/queries/get_container_repository_tags.query.graphql'; import deleteContainerRepositoryTagsMutation from '../../graphql/mutations/delete_container_repository_tags.mutation.graphql'; import DeleteModal from '../delete_modal.vue'; +import { getPageParams, getNextPageParams, getPreviousPageParams } from '../../utils'; import TagsListRow from './tags_list_row.vue'; export default { @@ -37,6 +39,7 @@ export default { TagsListRow, TagsLoader, RegistryList, + PersistedPagination, PersistedSearch, }, mixins: [Tracking.mixin()], @@ -62,7 +65,7 @@ export default { required: false, }, }, - searchConfig: { NAME_SORT_FIELD }, + sortableFields: [NAME_SORT_FIELD], i18n: { REMOVE_TAGS_BUTTON_TITLE, TAGS_LIST_TITLE, @@ -87,7 +90,7 @@ export default { containerRepository: {}, filters: {}, itemsToBeDeleted: [], - mutationLoading: false, + isDeleteInProgress: false, sort: null, pageParams: {}, }; @@ -121,7 +124,7 @@ export default { return ( this.isImageLoading || this.$apollo.queries.containerRepository.loading || - this.mutationLoading || + this.isDeleteInProgress || !this.sort ); }, @@ -153,7 +156,7 @@ export default { async handleDeleteTag() { this.track('confirm_delete'); const { itemsToBeDeleted } = this; - this.mutationLoading = true; + this.isDeleteInProgress = true; try { const { data } = await this.$apollo.mutate({ mutation: deleteContainerRepositoryTagsMutation, @@ -180,24 +183,17 @@ export default { } catch (e) { this.$emit('delete', itemsToBeDeleted.length === 1 ? ALERT_DANGER_TAG : ALERT_DANGER_TAGS); } finally { - this.mutationLoading = false; + this.isDeleteInProgress = false; } }, fetchNextPage() { - this.pageParams = { - after: this.tagsPageInfo?.endCursor, - first: GRAPHQL_PAGE_SIZE, - }; + this.pageParams = getNextPageParams(this.tagsPageInfo?.endCursor); }, fetchPreviousPage() { - this.pageParams = { - first: null, - before: this.tagsPageInfo?.startCursor, - last: GRAPHQL_PAGE_SIZE, - }; + this.pageParams = getPreviousPageParams(this.tagsPageInfo?.startCursor); }, - handleSearchUpdate({ sort, filters }) { - this.pageParams = {}; + handleSearchUpdate({ sort, filters, pageInfo }) { + this.pageParams = getPageParams(pageInfo); this.sort = sort; const parsed = { @@ -224,10 +220,8 @@ export default { <div> <persisted-search class="gl-mb-5" - :sortable-fields="/* eslint-disable @gitlab/vue-no-new-non-primitive-in-template */ [ - $options.searchConfig.NAME_SORT_FIELD, - ] /* eslint-enable @gitlab/vue-no-new-non-primitive-in-template */" - :default-order="$options.searchConfig.NAME_SORT_FIELD.orderBy" + :sortable-fields="$options.sortableFields" + :default-order="$options.sortableFields[0].orderBy" default-sort="asc" @update="handleSearchUpdate" /> @@ -244,11 +238,8 @@ export default { <registry-list :hidden-delete="hideBulkDelete" :title="listTitle" - :pagination="tagsPageInfo" :items="tags" id-property="name" - @prev-page="fetchPreviousPage" - @next-page="fetchNextPage" @delete="deleteTags" > <template #default="{ selectItem, isSelected, item, first }"> @@ -272,5 +263,14 @@ export default { /> </template> </template> + + <div v-if="!isDeleteInProgress" class="gl-display-flex gl-justify-content-center"> + <persisted-pagination + class="gl-mt-3" + :pagination="tagsPageInfo" + @prev="fetchPreviousPage" + @next="fetchNextPage" + /> + </div> </div> </template> diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue index d44bdd1bba2..df87ee79111 100644 --- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue +++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue @@ -339,7 +339,7 @@ export default { </template> </template> - <div class="gl-display-flex gl-justify-content-center"> + <div v-if="!mutationLoading" class="gl-display-flex gl-justify-content-center"> <persisted-pagination class="gl-mt-3" :pagination="pageInfo" diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb index 4cc1ed092d2..55a60e21784 100644 --- a/app/controllers/projects/environments_controller.rb +++ b/app/controllers/projects/environments_controller.rb @@ -110,10 +110,13 @@ class Projects::EnvironmentsController < Projects::ApplicationController return render_404 unless @environment.available? stop_actions = @environment.stop_with_actions!(current_user) + job = stop_actions.first if stop_actions&.count == 1 action_or_env_url = - if stop_actions&.count == 1 - polymorphic_url([project, stop_actions.first]) + if job.instance_of?(::Ci::Build) + polymorphic_url([project, job]) + elsif job.instance_of?(::Ci::Bridge) + project_pipeline_url(project, job.pipeline_id) else project_environment_url(project, @environment) end diff --git a/app/helpers/mirror_helper.rb b/app/helpers/mirror_helper.rb index 06deaeb5e9e..158aa5e0944 100644 --- a/app/helpers/mirror_helper.rb +++ b/app/helpers/mirror_helper.rb @@ -15,6 +15,11 @@ module MirrorHelper html_escape(_('Git LFS objects will be synced if LFS is %{docs_link_start}enabled for the project%{docs_link_end}. Push mirrors will %{strong_open}not%{strong_close} sync LFS objects over SSH.')) % { docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe, strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe } end + + def mirrored_repositories_count + count = @project.mirror == true ? 1 : 0 + count + @project.remote_mirrors.to_a.count(&:enabled) + end end MirrorHelper.prepend_mod_with('MirrorHelper') diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 9f3832178aa..9824e88ca30 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -40,6 +40,7 @@ class ApplicationSetting < MainClusterwide::ApplicationRecord vertex_project ], remove_with: '16.3', remove_after: '2023-07-22' ignore_column :dashboard_notification_limit, remove_with: '16.5', remove_after: '2023-08-22' + ignore_column :database_apdex_settings, remove_with: '16.4', remove_after: '2023-08-22' INSTANCE_REVIEW_MIN_USERS = 50 GRAFANA_URL_ERROR_MESSAGE = 'Please check your Grafana URL setting in ' \ @@ -733,7 +734,7 @@ class ApplicationSetting < MainClusterwide::ApplicationRecord validates :inactive_projects_send_warning_email_after_months, numericality: { only_integer: true, greater_than: 0, less_than: :inactive_projects_delete_after_months } - validates :database_apdex_settings, json_schema: { filename: 'application_setting_database_apdex_settings' }, allow_nil: true + validates :prometheus_alert_db_indicators_settings, json_schema: { filename: 'application_setting_prometheus_alert_db_indicators_settings' }, allow_nil: true validates :namespace_aggregation_schedule_lease_duration_in_seconds, numericality: { only_integer: true, greater_than: 0 } diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb index ab63a4dbb47..995fabf0137 100644 --- a/app/models/merge_request.rb +++ b/app/models/merge_request.rb @@ -984,6 +984,18 @@ class MergeRequest < ApplicationRecord branch_merge_base_commit.try(:sha) end + def existing_mrs_targeting_same_branch + similar_mrs = target_project + .merge_requests + .where(source_branch: source_branch, target_branch: target_branch) + .where(source_project: source_project) + .opened + + similar_mrs = similar_mrs.id_not_in(id) if persisted? + + similar_mrs + end + def validate_branches return unless target_project && source_project @@ -995,25 +1007,24 @@ class MergeRequest < ApplicationRecord [:source_branch, :target_branch].each { |attr| validate_branch_name(attr) } if opened? - similar_mrs = target_project - .merge_requests - .where(source_branch: source_branch, target_branch: target_branch) - .where(source_project_id: source_project&.id) - .opened - - similar_mrs = similar_mrs.where.not(id: id) if persisted? - - conflict = similar_mrs.first + conflicting_mr = existing_mrs_targeting_same_branch.first - if conflict.present? + if conflicting_mr errors.add( :validate_branches, - "Another open merge request already exists for this source branch: #{conflict.to_reference}" + conflicting_mr_message(conflicting_mr) ) end end end + def conflicting_mr_message(conflicting_mr) + format( + _("Another open merge request already exists for this source branch: %{conflicting_mr_reference}"), + conflicting_mr_reference: conflicting_mr.to_reference + ) + end + def validate_branch_name(attr) return unless will_save_change_to_attribute?(attr) diff --git a/app/validators/json_schemas/application_setting_database_apdex_settings.json b/app/validators/json_schemas/application_setting_prometheus_alert_db_indicators_settings.json index 8b58dd44586..ccd18f3d678 100644 --- a/app/validators/json_schemas/application_setting_database_apdex_settings.json +++ b/app/validators/json_schemas/application_setting_prometheus_alert_db_indicators_settings.json @@ -1,5 +1,5 @@ { - "description": "Database Apdex Settings", + "description": "Prometheus Alert Based Db indicators Settings", "type": "object", "properties": { "prometheus_api_url": { diff --git a/app/views/projects/merge_requests/creations/new.html.haml b/app/views/projects/merge_requests/creations/new.html.haml index 726dc87105c..c7569dce266 100644 --- a/app/views/projects/merge_requests/creations/new.html.haml +++ b/app/views/projects/merge_requests/creations/new.html.haml @@ -5,7 +5,11 @@ - add_page_specific_style 'page_bundles/ci_status' - add_page_specific_style 'page_bundles/merge_request' -- if @merge_request.can_be_created && !params[:change_branches] +- conflicting_mr = @merge_request.existing_mrs_targeting_same_branch.first + +- if @merge_request.can_be_created && !params[:change_branches] && !conflicting_mr = render 'new_submit' - else + - if conflicting_mr + - flash[:alert] = @merge_request.conflicting_mr_message(conflicting_mr) = render 'new_compare' diff --git a/app/views/projects/mirrors/_mirror_repos.html.haml b/app/views/projects/mirrors/_mirror_repos.html.haml index 110bc8d82f8..a9a2ca6a494 100644 --- a/app/views/projects/mirrors/_mirror_repos.html.haml +++ b/app/views/projects/mirrors/_mirror_repos.html.haml @@ -12,28 +12,45 @@ = _('Set up your project to automatically push and/or pull changes to/from another repository. Branches, tags, and commits will be synced automatically.') = link_to _('How do I mirror repositories?'), help_page_path('user/project/repository/mirror/index.md'), target: '_blank', rel: 'noopener noreferrer' - .settings-content - - if mirror_settings_enabled - = gitlab_ui_form_for @project, url: project_mirror_path(@project), html: { class: 'gl-show-field-errors js-mirror-form', autocomplete: 'new-password', data: mirrors_form_data_attributes } do |f| - .panel.panel-default - .panel-body - %div= form_errors(@project) - - .form-group.has-feedback - = label_tag :url, _('Git repository URL'), class: 'label-light' - = text_field_tag :url, nil, class: 'form-control gl-form-input js-mirror-url js-repo-url', placeholder: _('Input the remote repository URL'), required: true, pattern: "(#{protocols}):\/\/.+", autocomplete: 'new-password', data: { qa_selector: 'mirror_repository_url_field' } - - = render 'projects/mirrors/instructions' - - = render 'projects/mirrors/mirror_repos_form', f: f - = render 'projects/mirrors/branch_filter' - - .panel-footer - = f.submit _('Mirror repository'), class: 'js-mirror-submit', name: :update_remote_mirror, pajamas_button: true, data: { qa_selector: 'mirror_repository_button' } - - else - = render Pajamas::AlertComponent.new(dismissible: false) do |c| - - c.with_body do - = _('Mirror settings are only available to GitLab administrators.') - - = render 'projects/mirrors/mirror_repos_list' + .settings-content + = render Pajamas::CardComponent.new(card_options: { class: 'gl-new-card js-toggle-container' }, header_options: { class: 'gl-new-card-header' }, body_options: { class: 'gl-new-card-body gl-px-0' }) do |c| + - c.with_header do + .gl-new-card-title-wrapper + %h5.gl-new-card-title + = _('Mirrored repositories') + .gl-new-card-count + = sprite_icon('earth', css_class: 'gl-mr-2') + %span.js-mirrored-repo-count + = mirrored_repositories_count + .gl-new-card-actions + = render Pajamas::ButtonComponent.new(size: :small, button_options: { class: "js-toggle-button js-toggle-content" }) do + = _('Add new') + - c.with_body do + - if mirror_settings_enabled + .gl-new-card-add-form.gl-m-3.gl-mb-4.gl-display-none.js-toggle-content + %h4.gl-mt-0 + = s_('Profiles|Add new mirror repository') + = gitlab_ui_form_for @project, url: project_mirror_path(@project), html: { class: 'gl-show-field-errors js-mirror-form', autocomplete: 'new-password', data: mirrors_form_data_attributes } do |f| + %div= form_errors(@project) + .form-group.has-feedback + = label_tag :url, _('Git repository URL'), class: 'label-light' + = text_field_tag :url, nil, class: 'form-control gl-form-input js-mirror-url js-repo-url', placeholder: _('Input the remote repository URL'), required: true, pattern: "(#{protocols}):\/\/.+", autocomplete: 'new-password', data: { qa_selector: 'mirror_repository_url_field' } + + = render 'projects/mirrors/instructions' + + = render 'projects/mirrors/mirror_repos_form', f: f + + = render 'projects/mirrors/branch_filter' + + = f.submit _('Mirror repository'), class: 'js-mirror-submit', name: :update_remote_mirror, pajamas_button: true, data: { qa_selector: 'mirror_repository_button' } + + = render Pajamas::ButtonComponent.new(button_options: { type: 'reset', class: 'gl-ml-2 js-toggle-button' }) do + = _('Cancel') + + - else + = render Pajamas::AlertComponent.new(dismissible: false) do |c| + - c.with_body do + = _('Mirror settings are only available to GitLab administrators.') + + = render 'projects/mirrors/mirror_repos_list' diff --git a/app/views/projects/mirrors/_mirror_repos_list.html.haml b/app/views/projects/mirrors/_mirror_repos_list.html.haml index 185d86245c5..0debd13709d 100644 --- a/app/views/projects/mirrors/_mirror_repos_list.html.haml +++ b/app/views/projects/mirrors/_mirror_repos_list.html.haml @@ -1,49 +1,41 @@ - mirror_settings_enabled = can?(current_user, :admin_remote_mirror, @project) -.panel.panel-default - .table-responsive - - if !@project.mirror? && @project.remote_mirrors.count == 0 - = render Pajamas::CardComponent.new(card_options: { class: 'gl-mt-5' }) do |c| - - c.with_header do - %strong - = _('Mirrored repositories') + ' (0)' - - c.with_body do - = _('There are currently no mirrored repositories.') - - else - %table.table.gl-table.gl-mt-5 - %thead - %tr - %th - = _('Mirrored repositories') - = render_if_exists 'projects/mirrors/mirrored_repositories_count' - %th= _('Direction') - %th= _('Last update attempt') - %th= _('Last successful update') - %th - %th - %tbody.js-mirrors-table-body - = render_if_exists 'projects/mirrors/table_pull_row' - - @project.remote_mirrors.each_with_index do |mirror, index| - - next if mirror.new_record? - %tr.rspec-mirrored-repository-row{ class: ('bg-secondary' if mirror.disabled?), data: { qa_selector: 'mirrored_repository_row_container' } } - %td{ data: { qa_selector: 'mirror_repository_url_content' } } - = mirror.safe_url || _('Invalid URL') - = render_if_exists 'projects/mirrors/mirror_branches_setting_badge', record: mirror - %td= _('Push') - %td - = mirror.last_update_started_at.present? ? time_ago_with_tooltip(mirror.last_update_started_at) : _('Never') - %td{ data: { qa_selector: 'mirror_last_update_at_content' } }= mirror.last_update_at.present? ? time_ago_with_tooltip(mirror.last_update_at) : _('Never') - %td - - if mirror.disabled? - = render 'projects/mirrors/disabled_mirror_badge' - - if mirror.last_error.present? - = gl_badge_tag _('Error'), { variant: :danger }, { data: { toggle: 'tooltip', html: 'true', qa_selector: 'mirror_error_badge_content' }, title: html_escape(mirror.last_error.try(:strip)) } - %td.gl-display-flex - - if mirror_settings_enabled - .btn-group.mirror-actions-group{ role: 'group' } - - if mirror.ssh_key_auth? - = clipboard_button(text: mirror.ssh_public_key, class: 'gl-button btn btn-default btn-icon', title: _('Copy SSH public key'), qa_selector: 'copy_public_key_button') - = render 'shared/remote_mirror_update_button', remote_mirror: mirror - = render Pajamas::ButtonComponent.new(variant: :danger, - icon: 'remove', - button_options: { class: 'js-delete-mirror rspec-delete-mirror', title: _('Remove'), data: { mirror_id: mirror.id, toggle: 'tooltip', container: 'body' } }) +.table-responsive.gl-mb-0 + - if !@project.mirror? && @project.remote_mirrors.count == 0 + .gl-new-card-empty.gl-px-5.gl-py-4= _('There are currently no mirrored repositories.') + - else + %table.table.b-table.gl-table.b-table-stacked-md + %thead.d-none.d-md-table-header-group + %tr + %th= _('Repository') + %th= _('Direction') + %th= _('Last update attempt') + %th= _('Last successful update') + %th + %th + %tbody.js-mirrors-table-body + = render_if_exists 'projects/mirrors/table_pull_row' + - @project.remote_mirrors.each_with_index do |mirror, index| + - next if mirror.new_record? + %tr.rspec-mirrored-repository-row{ class: ('bg-secondary' if mirror.disabled?), data: { qa_selector: 'mirrored_repository_row_container' } } + %td{ data: { qa_selector: 'mirror_repository_url_content' } } + = mirror.safe_url || _('Invalid URL') + = render_if_exists 'projects/mirrors/mirror_branches_setting_badge', record: mirror + %td= _('Push') + %td + = mirror.last_update_started_at.present? ? time_ago_with_tooltip(mirror.last_update_started_at) : _('Never') + %td{ data: { qa_selector: 'mirror_last_update_at_content' } }= mirror.last_update_at.present? ? time_ago_with_tooltip(mirror.last_update_at) : _('Never') + %td + - if mirror.disabled? + = render 'projects/mirrors/disabled_mirror_badge' + - if mirror.last_error.present? + = gl_badge_tag _('Error'), { variant: :danger }, { data: { toggle: 'tooltip', html: 'true', qa_selector: 'mirror_error_badge_content' }, title: html_escape(mirror.last_error.try(:strip)) } + %td + - if mirror_settings_enabled + .btn-group.mirror-actions-group{ role: 'group' } + - if mirror.ssh_key_auth? + = clipboard_button(text: mirror.ssh_public_key, class: 'gl-button btn btn-default btn-icon', title: _('Copy SSH public key'), qa_selector: 'copy_public_key_button') + = render 'shared/remote_mirror_update_button', remote_mirror: mirror + = render Pajamas::ButtonComponent.new(variant: :danger, + icon: 'remove', + button_options: { class: 'js-delete-mirror rspec-delete-mirror', title: _('Remove'), data: { mirror_id: mirror.id, toggle: 'tooltip', container: 'body' } }) diff --git a/app/views/projects/settings/ci_cd/show.html.haml b/app/views/projects/settings/ci_cd/show.html.haml index 703f057d9a5..19f5ae4e6b3 100644 --- a/app/views/projects/settings/ci_cd/show.html.haml +++ b/app/views/projects/settings/ci_cd/show.html.haml @@ -73,7 +73,7 @@ = _("Pipeline triggers") = render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do = expanded ? _('Collapse') : _('Expand') - %p + %p.gl-text-secondary = _("Trigger a pipeline for a branch or tag by generating a trigger token and using it with an API call. The token impersonates a user's project access and permissions.") = link_to _('Learn more.'), help_page_path('ci/triggers/index'), target: '_blank', rel: 'noopener noreferrer' .settings-content diff --git a/config/metrics/counts_28d/20210427102618_code_review_category_monthly_active_users.yml b/config/metrics/counts_28d/20210427102618_code_review_category_monthly_active_users.yml index 51a688a5806..b8c5169e93a 100644 --- a/config/metrics/counts_28d/20210427102618_code_review_category_monthly_active_users.yml +++ b/config/metrics/counts_28d/20210427102618_code_review_category_monthly_active_users.yml @@ -139,3 +139,4 @@ options: - 'i_code_review_merge_request_widget_security_reports_expand_success' - 'i_code_review_merge_request_widget_security_reports_expand_warning' - 'i_code_review_merge_request_widget_security_reports_expand_failed' + - 'i_code_review_saved_replies_create' diff --git a/config/metrics/counts_28d/20210427103119_code_review_group_monthly_active_users.yml b/config/metrics/counts_28d/20210427103119_code_review_group_monthly_active_users.yml index 9140ab4cc5f..3ec0903e363 100644 --- a/config/metrics/counts_28d/20210427103119_code_review_group_monthly_active_users.yml +++ b/config/metrics/counts_28d/20210427103119_code_review_group_monthly_active_users.yml @@ -144,3 +144,4 @@ options: - 'i_code_review_merge_request_widget_security_reports_expand_success' - 'i_code_review_merge_request_widget_security_reports_expand_warning' - 'i_code_review_merge_request_widget_security_reports_expand_failed' + - 'i_code_review_saved_replies_create' diff --git a/config/metrics/counts_28d/20230724140653_i_code_review_saved_replies_create_monthly.yml b/config/metrics/counts_28d/20230724140653_i_code_review_saved_replies_create_monthly.yml new file mode 100644 index 00000000000..ac891dcc18c --- /dev/null +++ b/config/metrics/counts_28d/20230724140653_i_code_review_saved_replies_create_monthly.yml @@ -0,0 +1,25 @@ +--- +key_path: redis_hll_counters.code_review.i_code_review_saved_replies_create_monthly +description: Monthly count of unique users who create a saved comment reply +product_section: dev +product_stage: create +product_group: code_review +value_type: number +status: active +milestone: "16.3" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/126884 +time_frame: 28d +data_source: redis_hll +data_category: optional +instrumentation_class: RedisHLLMetric +performance_indicator_type: [] +distribution: +- ce +- ee +tier: +- free +- premium +- ultimate +options: + events: + - i_code_review_saved_replies_create diff --git a/config/metrics/counts_7d/20210427103328_code_review_group_monthly_active_users.yml b/config/metrics/counts_7d/20210427103328_code_review_group_monthly_active_users.yml index 7e209470ac9..6a0a14bdc26 100644 --- a/config/metrics/counts_7d/20210427103328_code_review_group_monthly_active_users.yml +++ b/config/metrics/counts_7d/20210427103328_code_review_group_monthly_active_users.yml @@ -142,3 +142,4 @@ options: - 'i_code_review_merge_request_widget_security_reports_expand_success' - 'i_code_review_merge_request_widget_security_reports_expand_warning' - 'i_code_review_merge_request_widget_security_reports_expand_failed' + - 'i_code_review_saved_replies_create' diff --git a/config/metrics/counts_7d/20210427103407_code_review_category_monthly_active_users.yml b/config/metrics/counts_7d/20210427103407_code_review_category_monthly_active_users.yml index 343e0105bf7..18d69d8e2f7 100644 --- a/config/metrics/counts_7d/20210427103407_code_review_category_monthly_active_users.yml +++ b/config/metrics/counts_7d/20210427103407_code_review_category_monthly_active_users.yml @@ -137,3 +137,4 @@ options: - 'i_code_review_merge_request_widget_security_reports_expand_success' - 'i_code_review_merge_request_widget_security_reports_expand_warning' - 'i_code_review_merge_request_widget_security_reports_expand_failed' + - 'i_code_review_saved_replies_create' diff --git a/config/metrics/counts_7d/20230724140652_i_code_review_saved_replies_create_weekly.yml b/config/metrics/counts_7d/20230724140652_i_code_review_saved_replies_create_weekly.yml new file mode 100644 index 00000000000..565b9292c01 --- /dev/null +++ b/config/metrics/counts_7d/20230724140652_i_code_review_saved_replies_create_weekly.yml @@ -0,0 +1,25 @@ +--- +key_path: redis_hll_counters.code_review.i_code_review_saved_replies_create_weekly +description: Weekly count of unique users who create a saved comment reply +product_section: dev +product_stage: create +product_group: code_review +value_type: number +status: active +milestone: "16.3" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/126884 +time_frame: 7d +data_source: redis_hll +data_category: optional +instrumentation_class: RedisHLLMetric +performance_indicator_type: [] +distribution: +- ce +- ee +tier: +- free +- premium +- ultimate +options: + events: + - i_code_review_saved_replies_create diff --git a/config/metrics/counts_all/20230725200123_i_code_review_saved_replies_count_create.yml b/config/metrics/counts_all/20230725200123_i_code_review_saved_replies_count_create.yml new file mode 100644 index 00000000000..64cfcee0ef4 --- /dev/null +++ b/config/metrics/counts_all/20230725200123_i_code_review_saved_replies_count_create.yml @@ -0,0 +1,25 @@ +--- +key_path: counts.i_code_review_saved_replies_count_create +description: Total number of times a saved reply was created +product_section: dev +product_stage: create +product_group: code_review +value_type: number +status: active +milestone: "16.3" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/126884 +time_frame: all +data_source: redis +data_category: optional +instrumentation_class: RedisMetric +performance_indicator_type: [] +distribution: +- ce +- ee +tier: +- free +- premium +- ultimate +options: + event: create + prefix: i_code_review_saved_replies diff --git a/db/migrate/20230808123101_rename_application_settings_database_apdex_settings.rb b/db/migrate/20230808123101_rename_application_settings_database_apdex_settings.rb new file mode 100644 index 00000000000..ce7c54f00ef --- /dev/null +++ b/db/migrate/20230808123101_rename_application_settings_database_apdex_settings.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class RenameApplicationSettingsDatabaseApdexSettings < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + def up + rename_column_concurrently( + :application_settings, + :database_apdex_settings, + :prometheus_alert_db_indicators_settings + ) + end + + def down + undo_rename_column_concurrently( + :application_settings, + :database_apdex_settings, + :prometheus_alert_db_indicators_settings + ) + end +end diff --git a/db/post_migrate/20230808123136_cleanup_application_settings_database_apdex_settings_rename.rb b/db/post_migrate/20230808123136_cleanup_application_settings_database_apdex_settings_rename.rb new file mode 100644 index 00000000000..de1887677bf --- /dev/null +++ b/db/post_migrate/20230808123136_cleanup_application_settings_database_apdex_settings_rename.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class CleanupApplicationSettingsDatabaseApdexSettingsRename < Gitlab::Database::Migration[2.1] + disable_ddl_transaction! + + def up + cleanup_concurrent_column_rename( + :application_settings, + :database_apdex_settings, + :prometheus_alert_db_indicators_settings + ) + end + + def down + undo_cleanup_concurrent_column_rename( + :application_settings, + :database_apdex_settings, + :prometheus_alert_db_indicators_settings + ) + end +end diff --git a/db/schema_migrations/20230808123101 b/db/schema_migrations/20230808123101 new file mode 100644 index 00000000000..fc216bcd651 --- /dev/null +++ b/db/schema_migrations/20230808123101 @@ -0,0 +1 @@ +a6d1407e0b01cb6b87b84e05e8c054daa8a36265dc2fd3457f60efdd71813ce9
\ No newline at end of file diff --git a/db/schema_migrations/20230808123136 b/db/schema_migrations/20230808123136 new file mode 100644 index 00000000000..7ce93e8d1c3 --- /dev/null +++ b/db/schema_migrations/20230808123136 @@ -0,0 +1 @@ +184d082289e04f22a52787b617c712c684d97c4a9b4c5812798adf9b669299cd
\ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 5af92e124bd..8d694c00c6c 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -11847,7 +11847,6 @@ CREATE TABLE application_settings ( lock_memberships_to_saml boolean DEFAULT false NOT NULL, gitlab_dedicated_instance boolean DEFAULT false NOT NULL, update_runner_versions_enabled boolean DEFAULT true NOT NULL, - database_apdex_settings jsonb, encrypted_openai_api_key bytea, encrypted_openai_api_key_iv bytea, database_max_running_batched_background_migrations integer DEFAULT 2 NOT NULL, @@ -11885,6 +11884,7 @@ CREATE TABLE application_settings ( max_import_remote_file_size bigint DEFAULT 10240 NOT NULL, protected_paths_for_get_request text[] DEFAULT '{}'::text[] NOT NULL, max_decompressed_archive_size integer DEFAULT 25600 NOT NULL, + prometheus_alert_db_indicators_settings jsonb, CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)), CONSTRAINT app_settings_container_registry_pre_import_tags_rate_positive CHECK ((container_registry_pre_import_tags_rate >= (0)::numeric)), CONSTRAINT app_settings_dep_proxy_ttl_policies_worker_capacity_positive CHECK ((dependency_proxy_ttl_group_policy_worker_capacity >= 0)), diff --git a/doc/.vale/gitlab/SubstitutionWarning.yml b/doc/.vale/gitlab/SubstitutionWarning.yml index d9d4200e88b..c081ca5a4f7 100644 --- a/doc/.vale/gitlab/SubstitutionWarning.yml +++ b/doc/.vale/gitlab/SubstitutionWarning.yml @@ -31,6 +31,8 @@ swap: file name: "filename" filesystem: "file system" info: "information" + installation from source: self-compiled installation + installations from source: self-compiled installations it is recommended: "you should" logged in user: "authenticated user" logged-in user: "authenticated user" @@ -52,6 +54,8 @@ swap: signed in user: "authenticated user" signed-in user: "authenticated user" since: "because' or 'after" + source (?:install|installation): self-compiled installation + source (?:installs|installations): self-compiled installations sub-group: "subgroup" sub-groups: "subgroups" timezone: "time zone" diff --git a/doc/administration/backup_restore/backup_gitlab.md b/doc/administration/backup_restore/backup_gitlab.md index 5f396947341..011edc34ef0 100644 --- a/doc/administration/backup_restore/backup_gitlab.md +++ b/doc/administration/backup_restore/backup_gitlab.md @@ -950,8 +950,8 @@ Because file system performance may affect overall GitLab performance, Don't set the following configuration keys to the same path: -- `gitlab_rails['backup_path']` (`backup.path` for source installations). -- `gitlab_rails['backup_upload_connection'].local_root` (`backup.upload.connection.local_root` for source installations). +- `gitlab_rails['backup_path']` (`backup.path` for self-compiled installations). +- `gitlab_rails['backup_upload_connection'].local_root` (`backup.upload.connection.local_root` for self-compiled installations). The `backup_path` configuration key sets the local location of the backup file. The `upload` configuration key is intended for use when the backup file is uploaded to a separate server, perhaps for archival purposes. diff --git a/doc/administration/cicd.md b/doc/administration/cicd.md index a3d9a853aaf..6ee6dacb8f4 100644 --- a/doc/administration/cicd.md +++ b/doc/administration/cicd.md @@ -14,7 +14,7 @@ GitLab administrators can manage the GitLab CI/CD configuration for their instan GitLab CI/CD is enabled by default in all new projects on an instance. You can set CI/CD to be disabled by default in new projects by modifying the settings in: -- `gitlab.yml` for source installations. +- `gitlab.yml` for self-compiled installations. - `gitlab.rb` for Linux package installations. Existing projects that already had CI/CD enabled are unchanged. Also, this setting only changes diff --git a/doc/administration/gitaly/configure_gitaly.md b/doc/administration/gitaly/configure_gitaly.md index c7fa40014d0..2a91fa40a81 100644 --- a/doc/administration/gitaly/configure_gitaly.md +++ b/doc/administration/gitaly/configure_gitaly.md @@ -1453,7 +1453,7 @@ following keys (in this example, to disable the `hasDotgit` consistency check): } ``` -For source installs, edit the Gitaly configuration (`gitaly.toml`) to do the +For self-compiled installations, edit the Gitaly configuration (`gitaly.toml`) to do the equivalent: ```toml diff --git a/doc/administration/incoming_email.md b/doc/administration/incoming_email.md index 63553fc43d0..69635a1982f 100644 --- a/doc/administration/incoming_email.md +++ b/doc/administration/incoming_email.md @@ -312,7 +312,7 @@ gitlab_rails['incoming_email_delete_after_delivery'] = true gitlab_rails['incoming_email_expunge_deleted'] = true ``` -Example for source installs: +Example for self-compiled installations: ```yaml incoming_email: @@ -404,7 +404,7 @@ gitlab_rails['incoming_email_delete_after_delivery'] = true gitlab_rails['incoming_email_expunge_deleted'] = true ``` -Example for source installs: +Example for self-compiled installations: ```yaml incoming_email: @@ -490,7 +490,7 @@ gitlab_rails['incoming_email_ssl'] = true gitlab_rails['incoming_email_expunge_deleted'] = true ``` -Example for source installs: +Example for self-compiled installations: ```yaml incoming_email: @@ -558,7 +558,7 @@ gitlab_rails['incoming_email_ssl'] = true gitlab_rails['incoming_email_expunge_deleted'] = true ``` -Example for source installs: +Example for self-compiled installations: ```yaml incoming_email: @@ -646,7 +646,7 @@ gitlab_rails['incoming_email_ssl'] = true gitlab_rails['incoming_email_expunge_deleted'] = true ``` -This example for source installs assumes the mailbox `incoming@office365.example.com`: +This example for self-compiled installations assumes the mailbox `incoming@office365.example.com`: ```yaml incoming_email: @@ -707,7 +707,7 @@ gitlab_rails['incoming_email_ssl'] = true gitlab_rails['incoming_email_expunge_deleted'] = true ``` -This example for source installs assumes the catch-all mailbox `incoming@office365.example.com`: +This example for self-compiled installations assumes the catch-all mailbox `incoming@office365.example.com`: ```yaml incoming_email: @@ -767,7 +767,7 @@ gitlab_rails['incoming_email_ssl'] = true gitlab_rails['incoming_email_expunge_deleted'] = true ``` -This example for source installs assumes the dedicated email address `incoming@office365.example.com`: +This example for self-compiled installations assumes the dedicated email address `incoming@office365.example.com`: ```yaml incoming_email: @@ -865,7 +865,7 @@ gitlab_rails['incoming_email_inbox_options'] = { } ``` -The Microsoft Graph API is not yet supported in source installations. See [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/326169) for more details. +The Microsoft Graph API is not yet supported in self-compiled installations. See [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/326169) for more details. ### Use encrypted credentials diff --git a/doc/administration/merge_request_diffs.md b/doc/administration/merge_request_diffs.md index 00ea1e43600..2b45cd67ce4 100644 --- a/doc/administration/merge_request_diffs.md +++ b/doc/administration/merge_request_diffs.md @@ -108,7 +108,7 @@ In GitLab 13.2 and later, you should use the [consolidated object storage settings](object_storage.md#configure-a-single-storage-connection-for-all-object-types-consolidated-form). This section describes the earlier configuration format. -For source installations, these settings are nested under `external_diffs:` and +For self-compiled installations, these settings are nested under `external_diffs:` and then `object_store:`. On Linux package installations, they are prefixed by `external_diffs_object_store_`. diff --git a/doc/administration/operations/puma.md b/doc/administration/operations/puma.md index f471dcd44b0..f16f1ac46ae 100644 --- a/doc/administration/operations/puma.md +++ b/doc/administration/operations/puma.md @@ -395,7 +395,7 @@ gitlab_rails['env'] = { } ``` -For source installations, set the environment variable. +For self-compiled installations, set the environment variable. Refer to [Puma Worker timeout](../operations/puma.md#change-the-worker-timeout). [Reconfigure](../restart_gitlab.md#reconfigure-a-linux-package-installation) GitLab for the changes to take effect. diff --git a/doc/administration/packages/container_registry.md b/doc/administration/packages/container_registry.md index ad5006186d0..2c2e48b2292 100644 --- a/doc/administration/packages/container_registry.md +++ b/doc/administration/packages/container_registry.md @@ -1671,7 +1671,7 @@ For Linux package installations: :::TabTitle Self-compiled (source) -For source installations, locate your `registry` binary and temporarily replace it with the one +Locate your `registry` binary and temporarily replace it with the one obtained from `v3.0.0-gitlab`, as explained for Linux package installations. Make sure to start by backing up the original registry binary, and restore it after performing the [images upgrade](#images-upgrade) steps. diff --git a/doc/administration/postgresql/multiple_databases.md b/doc/administration/postgresql/multiple_databases.md index 5dcb080d707..2cdadf95ac1 100644 --- a/doc/administration/postgresql/multiple_databases.md +++ b/doc/administration/postgresql/multiple_databases.md @@ -41,7 +41,7 @@ databases. Some examples: To migrate existing data from the `main` database to the `ci` database, you can copy the database across. -### Existing source installation +### Existing self-compiled installation 1. Stop GitLab, except for PostgreSQL: diff --git a/doc/administration/raketasks/maintenance.md b/doc/administration/raketasks/maintenance.md index c2c6429ba8b..17720dc97ea 100644 --- a/doc/administration/raketasks/maintenance.md +++ b/doc/administration/raketasks/maintenance.md @@ -234,7 +234,7 @@ clear Redis' cache. To do this, run: Sometimes during version upgrades you might end up with some wrong CSS or missing some icons. In that case, try to precompile the assets again. -This Rake task only applies to source installations. [Read more](../../update/package/index.md#missing-asset-files) +This Rake task only applies to self-compiled installations. [Read more](../../update/package/index.md#missing-asset-files) about troubleshooting this problem when running the Linux package. The guidance for Linux package might be applicable for Kubernetes and Docker deployments of GitLab, though in general, container-based installations diff --git a/doc/administration/repository_storage_paths.md b/doc/administration/repository_storage_paths.md index 9967b623773..03c94480259 100644 --- a/doc/administration/repository_storage_paths.md +++ b/doc/administration/repository_storage_paths.md @@ -87,7 +87,7 @@ moving things between mount points, and problems can occur. Ideally, `/home/git` is the mount point, so things remain inside the same mount point. Linux package installations guarantee this because they don't specify the full repository path but instead -the parent path, but source installations do not. +the parent path, but self-compiled installations do not. ### Example configuration diff --git a/doc/administration/secure_files.md b/doc/administration/secure_files.md index 9005bcea319..60e2c2be602 100644 --- a/doc/administration/secure_files.md +++ b/doc/administration/secure_files.md @@ -100,7 +100,7 @@ Adding support is proposed in [issue 414673](https://gitlab.com/gitlab-org/gitla The following settings are: -- Nested under `ci_secure_files:` and then `object_store:` on source installations. +- Nested under `ci_secure_files:` and then `object_store:` on self-compiled installations. - Prefixed by `ci_secure_files_object_store_` on Linux package installations. | Setting | Description | Default | diff --git a/doc/administration/settings/user_and_ip_rate_limits.md b/doc/administration/settings/user_and_ip_rate_limits.md index 44bd08a8824..822ba4dd03e 100644 --- a/doc/administration/settings/user_and_ip_rate_limits.md +++ b/doc/administration/settings/user_and_ip_rate_limits.md @@ -143,7 +143,7 @@ GitLab. For example: 1. Set the environment variable `GITLAB_THROTTLE_BYPASS_HEADER`. - For [Linux package installations](https://docs.gitlab.com/omnibus/settings/environment-variables.html), set `'GITLAB_THROTTLE_BYPASS_HEADER' => 'Gitlab-Bypass-Rate-Limiting'` in `gitlab_rails['env']`. - - For source installations, set `export GITLAB_THROTTLE_BYPASS_HEADER=Gitlab-Bypass-Rate-Limiting` + - For self-compiled installations, set `export GITLAB_THROTTLE_BYPASS_HEADER=Gitlab-Bypass-Rate-Limiting` in `/etc/default/gitlab`. It is important that your load balancer erases or overwrites the bypass @@ -175,7 +175,7 @@ the allowlist configuration would be `1,53,217`. - For [Linux package installations](https://docs.gitlab.com/omnibus/settings/environment-variables.html), set `'GITLAB_THROTTLE_USER_ALLOWLIST' => '1,53,217'` in `gitlab_rails['env']`. -- For source installations, set `export GITLAB_THROTTLE_USER_ALLOWLIST=1,53,217` +- For self-compiled installations, set `export GITLAB_THROTTLE_USER_ALLOWLIST=1,53,217` in `/etc/default/gitlab`. Requests that bypassed the rate limiter because of the user allowlist diff --git a/doc/administration/terraform_state.md b/doc/administration/terraform_state.md index c0f1e8ebc12..52053072b1f 100644 --- a/doc/administration/terraform_state.md +++ b/doc/administration/terraform_state.md @@ -14,7 +14,7 @@ files. The files are encrypted before being stored. This feature is enabled by d The storage location of these files defaults to: - `/var/opt/gitlab/gitlab-rails/shared/terraform_state` for Linux package installations. -- `/home/git/gitlab/shared/terraform_state` for source installations. +- `/home/git/gitlab/shared/terraform_state` for self-compiled installations. These locations can be configured using the options described below. diff --git a/doc/api/groups.md b/doc/api/groups.md index b54e0c1c0c4..c0560f5f88c 100644 --- a/doc/api/groups.md +++ b/doc/api/groups.md @@ -844,7 +844,7 @@ The `default_branch_protection` attribute determines whether users with the Deve | `1` | Partial protection. Users with the Developer or Maintainer role can: <br>- Push new commits | | `2` | Full protection. Only users with the Maintainer role can: <br>- Push new commits | | `3` | Protected against pushes. Users with the Maintainer role can: <br>- Push new commits<br>- Force push changes<br>- Accept merge requests<br>Users with the Developer role can:<br>- Accept merge requests| -| `4` | Protected against pushes except initial push. User with the Developer role can: <br>- Push commit to empty repository.<br> Users with the Maintainer role can: <br>- Push new commits<br>- Force push changes<br>- Accept merge requests<br>Users with the Developer role can:<br>- Accept merge requests| +| `4` | Full protection after initial push. User with the Developer role can: <br>- Push commit to empty repository.<br> Users with the Maintainer role can: <br>- Push new commits<br>- Accept merge requests| ## New Subgroup diff --git a/doc/development/adding_service_component.md b/doc/development/adding_service_component.md index 314065ffc10..6e47d2991dc 100644 --- a/doc/development/adding_service_component.md +++ b/doc/development/adding_service_component.md @@ -70,7 +70,7 @@ New services to be bundled with GitLab need to be available in the following env The first step of bundling a new service is to provide it in the development environment to engage in collaboration and feedback. - [Include in the GDK](https://gitlab.com/gitlab-org/gitlab-development-kit) -- [Include in the source install instructions](../install/installation.md) +- [Include in the self-compiled installation instructions](../install/installation.md) **Standard install methods** diff --git a/doc/development/application_secrets.md b/doc/development/application_secrets.md index 5b0755e97e3..33bba2b3285 100644 --- a/doc/development/application_secrets.md +++ b/doc/development/application_secrets.md @@ -23,9 +23,9 @@ This page is a development guide for application secrets. |Installation type |Location | |--- |--- | -|Omnibus |[`/etc/gitlab/gitlab-secrets.json`](https://docs.gitlab.com/omnibus/settings/backups.html#backup-and-restore-omnibus-gitlab-configuration) | -|Cloud Native GitLab Charts |[Kubernetes Secrets](https://gitlab.com/gitlab-org/charts/gitlab/-/blob/f65c3d37fc8cf09a7987544680413552fb666aac/doc/installation/secrets.md#gitlab-rails-secret)| -|Source |`<path-to-gitlab-rails>/config/secrets.yml` (Automatically generated by [01_secret_token.rb](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/initializers/01_secret_token.rb)) | +| Linux package |[`/etc/gitlab/gitlab-secrets.json`](https://docs.gitlab.com/omnibus/settings/backups.html#backup-and-restore-omnibus-gitlab-configuration) | +| Cloud Native GitLab Charts |[Kubernetes Secrets](https://gitlab.com/gitlab-org/charts/gitlab/-/blob/f65c3d37fc8cf09a7987544680413552fb666aac/doc/installation/secrets.md#gitlab-rails-secret)| +| Self-compiled |`<path-to-gitlab-rails>/config/secrets.yml` (Automatically generated by [01_secret_token.rb](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/initializers/01_secret_token.rb)) | ## Warning: Before you add a new secret to application secrets @@ -38,9 +38,9 @@ GitLab.com environments prior to changing this file. **Examples** -- [Change for source installation](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/27581) -- [Change for omnibus installation](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/3267) -- [Change for omnibus installation](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/4158) +- [Change for self-compiled installation](https://gitlab.com/gitlab-org/gitlab-foss/-/merge_requests/27581) +- [Change for Linux package installation](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/3267) +- [Change for Linux package installation](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/4158) - [Change for Cloud Native installation](https://gitlab.com/gitlab-org/charts/gitlab/-/merge_requests/1318) ## Further iteration diff --git a/doc/development/redis/new_redis_instance.md b/doc/development/redis/new_redis_instance.md index 00cc102b427..bc58bae45ec 100644 --- a/doc/development/redis/new_redis_instance.md +++ b/doc/development/redis/new_redis_instance.md @@ -30,8 +30,8 @@ Before we can switch any features to using the new instance, we have to support configuring it and referring to it in the codebase. We must support the main installation types: -- Source installs (including development environments) - [example MR](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62767) -- Omnibus - [example MR](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/5316) +- Self-compiled installations (including development environments) - [example MR](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/62767) +- Linux package installations - [example MR](https://gitlab.com/gitlab-org/omnibus-gitlab/-/merge_requests/5316) - Helm charts - [example MR](https://gitlab.com/gitlab-org/charts/gitlab/-/merge_requests/2031) ### Fallback instance diff --git a/doc/development/workhorse/configuration.md b/doc/development/workhorse/configuration.md index 84fb557d9ec..d19e85f3f7a 100644 --- a/doc/development/workhorse/configuration.md +++ b/doc/development/workhorse/configuration.md @@ -189,7 +189,9 @@ You can also set the `GITLAB_WORKHORSE_SENTRY_ENVIRONMENT` environment variable use the Sentry environment feature to separate staging, production and development. -Omnibus GitLab (`/etc/gitlab/gitlab.rb`): +::Tabs + +:::TabTitle Linux package (Omnibus) ```ruby gitlab_workhorse['env'] = { @@ -198,13 +200,15 @@ gitlab_workhorse['env'] = { } ``` -Source installations (`/etc/default/gitlab`): +:::TabTitle Self-compiled (source) ```plaintext export GITLAB_WORKHORSE_SENTRY_DSN='https://foobar' export GITLAB_WORKHORSE_SENTRY_ENVIRONMENT='production' ``` +::EndTabs + ## Distributed tracing Workhorse supports distributed tracing through [LabKit](https://gitlab.com/gitlab-org/labkit/) diff --git a/doc/downgrade_ee_to_ce/index.md b/doc/downgrade_ee_to_ce/index.md index 6a3fcab8bde..5d0baf7e494 100644 --- a/doc/downgrade_ee_to_ce/index.md +++ b/doc/downgrade_ee_to_ce/index.md @@ -38,19 +38,23 @@ use another column for that information.) All integrations are created automatically for every project you have. To avoid getting this error, you must remove all records with the type set to -`GithubService` from your database: +`GithubService` from your database. -- **Omnibus Installation** +::Tabs - ```shell - sudo gitlab-rails runner "Integration.where(type: ['GithubService']).delete_all" - ``` +:::TabTitle Linux package (Omnibus) -- **Source Installation** +```shell +sudo gitlab-rails runner "Integration.where(type: ['GithubService']).delete_all" +``` + +:::TabTitle Self-compiled (source) + +```shell +bundle exec rails runner "Integration.where(type: ['GithubService']).delete_all" production +``` - ```shell - bundle exec rails runner "Integration.where(type: ['GithubService']).delete_all" production - ``` +::EndTabs NOTE: If you are running `GitLab =< v13.0` you must also remove `JenkinsDeprecatedService` records @@ -74,25 +78,25 @@ back to EE and restore the behavior if you leave it alone. After performing the above mentioned steps, you are now ready to downgrade your GitLab installation to the Community Edition. -- **Omnibus Installation** +Remember to follow the correct [update guides](../update/index.md) to make sure all dependencies are up to date. + +### Linux package installations + +To downgrade a Linux package installation, you can install the Community Edition package on top of +the currently installed one. You can do this manually, by either: - To downgrade an Omnibus installation, it is sufficient to install the Community - Edition package on top of the currently installed one. You can do this manually, - by directly [downloading the package](https://packages.gitlab.com/gitlab/gitlab-ce) - you need, or by adding our CE package repository and following the - [CE installation instructions](https://about.gitlab.com/install/?version=ce). +- Directly [downloading the package](https://packages.gitlab.com/gitlab/gitlab-ce). +- Adding our CE package repository and following the [CE installation instructions](https://about.gitlab.com/install/?version=ce). -- **Source Installation** +### Self-compiled installations - To downgrade a source installation, you must replace the current remote of - your GitLab installation with the Community Edition's remote. After that, you - can fetch the latest changes, and checkout the latest stable branch: +To downgrade a self-compiled installation: - ```shell - git remote set-url origin git@gitlab.com:gitlab-org/gitlab-foss.git - git fetch --all - git checkout 8-x-stable - ``` +1. Replace the current remote of your GitLab installation with the Community Edition remote. +1. Fetch the latest changes, and check out the latest stable branch: -Remember to follow the correct [update guides](../update/index.md) to make -sure all dependencies are up to date. + ```shell + git remote set-url origin git@gitlab.com:gitlab-org/gitlab-foss.git + git fetch --all + git checkout 8-x-stable + ``` diff --git a/doc/install/aws/gitlab_hybrid_on_aws.md b/doc/install/aws/gitlab_hybrid_on_aws.md index b4d55e30ab1..42488becbd6 100644 --- a/doc/install/aws/gitlab_hybrid_on_aws.md +++ b/doc/install/aws/gitlab_hybrid_on_aws.md @@ -14,9 +14,9 @@ Amazon provides a managed Kubernetes service offering known as [Amazon Elastic K ## Tested AWS Bill of Materials by reference architecture size -| GitLab Cloud Native Hybrid Ref Arch | GitLab Baseline Performance Test Results Omnibus on Instances | AWS Bill of Materials (BOM) for CNH | AWS Build Performance Testing Results for [CNH](https://gitlab.com/guided-explorations/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/5K/5k-QuickStart-ARM-RDS-Redis_v13-12-3-ee_2021-07-23_140128/5k-QuickStart-ARM-RDS-Redis_v13-12-3-ee_2021-07-23_140128_results.txt) | CNH Cost Estimate 3 AZs* | +| GitLab Cloud Native Hybrid Ref Arch | GitLab Baseline Performance Test Results (using the Linux package on instances) | AWS Bill of Materials (BOM) for CNH | AWS Build Performance Testing Results for [CNH](https://gitlab.com/guided-explorations/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/5K/5k-QuickStart-ARM-RDS-Redis_v13-12-3-ee_2021-07-23_140128/5k-QuickStart-ARM-RDS-Redis_v13-12-3-ee_2021-07-23_140128_results.txt) | CNH Cost Estimate 3 AZs* | | ------------------------------------------------------------ | ------------------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------ | ------------------------------------------------------------ | -| [2K Omnibus](../../administration/reference_architectures/2k_users.md) | [2K Baseline](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/2k) | [2K Cloud Native Hybrid on EKS](#2k-cloud-native-hybrid-on-eks) | GPT Test Results | [1 YR Ec2 Compute Savings + 1 YR RDS & ElastiCache RIs](https://calculator.aws/#/estimate?id=544bcf1162beae6b8130ad257d081cdf9d4504e3)<br />(2 AZ Cost Estimate is in BOM Below) | +| [2K Linux package installation](../../administration/reference_architectures/2k_users.md) | [2K Baseline](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/2k) | [2K Cloud Native Hybrid on EKS](#2k-cloud-native-hybrid-on-eks) | GPT Test Results | [1 YR Ec2 Compute Savings + 1 YR RDS & ElastiCache RIs](https://calculator.aws/#/estimate?id=544bcf1162beae6b8130ad257d081cdf9d4504e3)<br />(2 AZ Cost Estimate is in BOM Below) | | [3K](../../administration/reference_architectures/3k_users.md#cloud-native-hybrid-reference-architecture-with-helm-charts-alternative) | [3k Baseline](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/3k) | [3K Cloud Native Hybrid on EKS](#3k-cloud-native-hybrid-on-eks) | [3K Full Fixed Scale GPT Test Results](https://gitlab.com/guided-explorations/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/3K/3k-QuickStart-ARM-RDS-Cache_v13-12-3-ee_2021-07-23_124216/3k-QuickStart-ARM-RDS-Cache_v13-12-3-ee_2021-07-23_124216_results.txt)<br /><br />[3K Elastic Auto Scale GPT Test Results](https://gitlab.com/guided-explorations/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/3K/3k-QuickStart-AutoScale-ARM-RDS-Cache_v13-12-3-ee_2021-07-23_194200/3k-QuickStart-AutoScale-ARM-RDS-Cache_v13-12-3-ee_2021-07-23_194200_results.txt) | [1 YR Ec2 Compute Savings + 1 YR RDS & ElastiCache RIs](https://calculator.aws/#/estimate?id=f1294fec554e21be999711cddcdab9c5e7f83f14)<br />(2 AZ Cost Estimate is in BOM Below) | | [5K](../../administration/reference_architectures/5k_users.md#cloud-native-hybrid-reference-architecture-with-helm-charts-alternative) | [5k Baseline](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/5k) | [5K Cloud Native Hybrid on EKS](#5k-cloud-native-hybrid-on-eks) | [5K Full Fixed Scale GPT Test Results](https://gitlab.com/guided-explorations/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/5K/5k-QuickStart-ARM-RDS-Redis_v13-12-3-ee_2021-07-23_140128/5k-QuickStart-ARM-RDS-Redis_v13-12-3-ee_2021-07-23_140128_results.txt)<br /><br />[5K AutoScale from 25% GPT Test Results](https://gitlab.com/guided-explorations/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/5K/5k-QuickStart-AutoScale-From-25Percent-ARM-RDS-Redis_v13-12-3-ee_2021-07-24_102717/5k-QuickStart-AutoScale-From-25Percent-ARM-RDS-Redis_v13-12-3-ee_2021-07-24_102717_results.txt) | [1 YR Ec2 Compute Savings + 1 YR RDS & ElastiCache RIs](https://calculator.aws/#/estimate?id=330ee43c5b14662db5df6e52b34898d181a09e16) | | [10K](../../administration/reference_architectures/10k_users.md#cloud-native-hybrid-reference-architecture-with-helm-charts-alternative) | [10k Baseline](https://gitlab.com/gitlab-org/quality/performance/-/wikis/Benchmarks/Latest/10k) | [10K Cloud Native Hybrid on EKS](#10k-cloud-native-hybrid-on-eks) | [10K Full Fixed Scale GPT Test Results](https://gitlab.com/guided-explorations/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/10K/GL-CloudNative-10k-RDS-Graviton_v13-12-3-ee_2021-07-08_194647/GL-CloudNative-10k-RDS-Graviton_v13-12-3-ee_2021-07-08_194647_results.txt)<br /><br />[10K Elastic Auto Scale GPT Test Results](https://gitlab.com/guided-explorations/aws/implementation-patterns/gitlab-cloud-native-hybrid-on-eks/-/blob/master/gitlab-alliances-testing/10K/GL-CloudNative-10k-AutoScaling-Test_v13-12-3-ee_2021-07-09_115139/GL-CloudNative-10k-AutoScaling-Test_v13-12-3-ee_2021-07-09_115139_results.txt) | [10K 1 YR Ec2 Compute Savings + 1 YR RDS & ElastiCache RIs](https://calculator.aws/#/estimate?id=5ac2e07a22e01c36ee76b5477c5a046cd1bea792) | @@ -32,7 +32,7 @@ Amazon provides a managed Kubernetes service offering known as [Amazon Elastic K ## Available Infrastructure as Code for GitLab Cloud Native Hybrid -The [GitLab Environment Toolkit (GET)](https://gitlab.com/gitlab-org/gitlab-environment-toolkit/-/blob/main/README.md) is an effort made by GitLab to create a multi-cloud, multi-GitLab (Omnibus + Cloud Native Hybrid) toolkit to provision GitLab. GET is developed by GitLab developers and is open to community contributions. GET is where GitLab is investing its resources as the primary option for Infrastructure as Code, and is being actively used in production as a part of [GitLab Dedicated](../../subscriptions/gitlab_dedicated/index.md). +The [GitLab Environment Toolkit (GET)](https://gitlab.com/gitlab-org/gitlab-environment-toolkit/-/blob/main/README.md) is an effort made by GitLab to create a multi-cloud, multi-GitLab (Linux package installation + Cloud Native Hybrid) toolkit to provision GitLab. GET is developed by GitLab developers and is open to community contributions. GET is where GitLab is investing its resources as the primary option for Infrastructure as Code, and is being actively used in production as a part of [GitLab Dedicated](../../subscriptions/gitlab_dedicated/index.md). For more information about the project, see [GitLab Environment Toolkit](https://gitlab.com/gitlab-org/gitlab-environment-toolkit/-/blob/main/README.md). @@ -58,8 +58,8 @@ The Beta version deploys Aurora PostgreSQL, but the release version will deploy | Compatible with AWS Meta-Automation Services (via CloudFormation) | - [AWS Service Catalog](https://aws.amazon.com/servicecatalog/) (Direct Import)<br>- [ServiceNow via an AWS Service Catalog Connector](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/integrations-servicenow.html#integrations-servicenow)<br>- [Jira Service Manager via an AWS Service Catalog Connector](https://docs.aws.amazon.com/servicecatalog/latest/adminguide/integrations-jiraservicedesk.html#integrations-jiraservicedesk)<br>- [AWS Control Tower](https://docs.aws.amazon.com/controltower/) ([Integration](https://aws.amazon.com/blogs/infrastructure-and-automation/deploy-aws-quick-start-to-multiple-accounts-using-aws-control-tower/))<br>- Quick Starts<br>- [AWS SaaS Factory](https://aws.amazon.com/partners/programs/saas-factory/) | No | | Results in a Ready-to-Use instance | Yes | Manual Actions or <br />Supplemental IaC Required | | **<u>Configuration Features</u>** | | | -| Can deploy Omnibus GitLab (non-Kubernetes) | No | Yes | -| Can deploy Single Instance Omnibus GitLab (non-Kubernetes) | No | Yes | +| Can deploy Linux package (non-Kubernetes) | No | Yes | +| Can deploy a single instance by using the Linux package (non-Kubernetes) | No | Yes | | Complete Internal Encryption | 85%, Targeting 100% | Manual | | AWS GovCloud Support | Yes | TBD | | No Code Form-Based Deployment User Experience Available | Yes | No | @@ -94,7 +94,7 @@ The AWS Quick Start for GitLab Cloud Native Hybrid on EKS has been tested with G ## AWS PaaS qualified for all GitLab implementations -For both Omnibus GitLab or Cloud Native Hybrid implementations, the following GitLab Service roles can be performed by AWS Services (PaaS). Any PaaS solutions that require preconfigured sizing based on the scale of your instance will also be listed in the per-instance size Bill of Materials lists. Those PaaS that do not require specific sizing, are not repeated in the BOM lists (for example, AWS Certification Manager). +For both implementations that used the Linux package or Cloud Native Hybrid implementations, the following GitLab Service roles can be performed by AWS Services (PaaS). Any PaaS solutions that require preconfigured sizing based on the scale of your instance will also be listed in the per-instance size Bill of Materials lists. Those PaaS that do not require specific sizing, are not repeated in the BOM lists (for example, AWS Certification Manager). These services have been tested with GitLab. diff --git a/doc/install/aws/index.md b/doc/install/aws/index.md index 4dcf2ce0927..febe54a8bb6 100644 --- a/doc/install/aws/index.md +++ b/doc/install/aws/index.md @@ -24,9 +24,9 @@ The following are the currently available implementation patterns for GitLab whe [Provision GitLab Cloud Native Hybrid on AWS EKS (HA)](gitlab_hybrid_on_aws.md). This document includes instructions, patterns, and automation for installing GitLab Cloud Native Hybrid on AWS EKS. It also includes [Bill of Materials](https://en.wikipedia.org/wiki/Bill_of_materials) listings and links to Infrastructure as Code. GitLab Cloud Native Hybrid is the supported way to put as much of GitLab as possible into Kubernetes. -### Patterns to Install Omnibus GitLab on AWS EC2 (HA) +### Patterns to Install GitLab by using the Linux package on AWS EC2 (HA) -[Omnibus GitLab on AWS EC2 (HA)](manual_install_aws.md) - instructions for installing GitLab on EC2 instances. Manual instructions to build a GitLab instance or create your own Infrastructure as Code (IaC). +[Installing a GitLab POC on Amazon Web Services (AWS)](manual_install_aws.md) - instructions for installing GitLab on EC2 instances. Manual instructions to build a GitLab instance or create your own Infrastructure as Code (IaC). ### Patterns for EKS cluster provisioning diff --git a/doc/install/docker.md b/doc/install/docker.md index 68282f108e0..ac15b5490ce 100644 --- a/doc/install/docker.md +++ b/doc/install/docker.md @@ -284,7 +284,7 @@ Here's an example that deploys GitLab with four runners as a [stack](https://doc ## Configuration -This container uses the official Omnibus GitLab package, so all configuration +This container uses the official Linux package, so all configuration is done in the unique configuration file `/etc/gitlab/gitlab.rb`. To access the GitLab configuration file, you can start a shell session in the @@ -326,7 +326,7 @@ You can pre-configure the GitLab Docker image by adding the environment variable `gitlab.rb` setting and is evaluated before the loading of the container's `gitlab.rb` file. This behavior allows you to configure the external GitLab URL, and make database configuration or any other option from the -[Omnibus GitLab template](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/files/gitlab-config-template/gitlab.rb.template). +[Linux package template](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/files/gitlab-config-template/gitlab.rb.template). The settings contained in `GITLAB_OMNIBUS_CONFIG` aren't written to the `gitlab.rb` configuration file, and are evaluated on load. @@ -640,7 +640,7 @@ page. ## Troubleshooting -The following information will help if you encounter problems using Omnibus GitLab and Docker. +The following information will help if you encounter problems with an installation that used the Linux package and Docker. ### Diagnose potential problems @@ -657,8 +657,7 @@ sudo docker exec -it gitlab /bin/bash ``` From within the container you can administer the GitLab container as you would -usually administer an -[Omnibus installation](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md) +usually administer a [Linux package installation](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/README.md). ### 500 Internal Error diff --git a/doc/install/install_methods.md b/doc/install/install_methods.md index 0463c926286..70091534e77 100644 --- a/doc/install/install_methods.md +++ b/doc/install/install_methods.md @@ -13,7 +13,7 @@ or use one of the following methods. | Installation method | Description | When to choose | |----------------------------------------------------------------|-------------|----------------| -| [Linux package](https://docs.gitlab.com/omnibus/installation/) | The official deb/rpm packages (also known as Omnibus GitLab). The package has GitLab and dependent components, including PostgreSQL, Redis, and Sidekiq. | Use if you want the most mature, scalable method. This version is also used on GitLab.com. <br>- For additional flexibility and resilience, see the [reference architecture documentation](../administration/reference_architectures/index.md).<br>- Review the [system requirements](requirements.md).<br>- View the [list of supported Linux operating systems](../administration/package_information/supported_os.md#supported-operating-systems). | +| [Linux package](https://docs.gitlab.com/omnibus/installation/) (previously known as Omnibus GitLab) | The official `deb` and `rpm` packages. The Linux package has GitLab and dependent components, including PostgreSQL, Redis, and Sidekiq. | Use if you want the most mature, scalable method. This version is also used on GitLab.com. <br>- For additional flexibility and resilience, see the [reference architecture documentation](../administration/reference_architectures/index.md).<br>- Review the [system requirements](requirements.md).<br>- View the [list of supported Linux operating systems](../administration/package_information/supported_os.md#supported-operating-systems). | | [Helm chart](https://docs.gitlab.com/charts/) | A chart for installing a cloud-native version of GitLab and its components on Kubernetes. | Use if your infrastructure is on Kubernetes and you're familiar with how it works. Management, observability, and some concepts are different than traditional deployments.<br/>- Administration and troubleshooting requires Kubernetes knowledge.<br/>- It can be more expensive for smaller installations. The default installation requires more resources than a single node Linux package deployment, because most services are deployed in a redundant fashion.<br/><br/> | | [Docker](docker.md) | The GitLab packages in a Docker container. | Use if you're familiar with Docker. | | [Source](installation.md) | GitLab and its components from scratch. | Use if none of the previous methods are available for your platform. Can use for unsupported systems like \*BSD.| @@ -31,8 +31,8 @@ or use one of the following methods. Installation of GitLab on these operating systems is possible, but not supported. See the [installation from source guide](installation.md) and the [installation guides](https://about.gitlab.com/install/) for more information. -See [OS versions that are no longer supported](../administration/package_information/supported_os.md#os-versions-that-are-no-longer-supported) for Omnibus installs page -for a list of supported and unsupported OS versions as well as the last support GitLab version for that OS. +See [OS versions that are no longer supported](../administration/package_information/supported_os.md#os-versions-that-are-no-longer-supported) +for a list of supported and unsupported OS versions for Linux package installations as well as the last support GitLab version for that OS. ## Microsoft Windows diff --git a/doc/install/relative_url.md b/doc/install/relative_url.md index 6f4221f9e2e..d0e8a387ac5 100644 --- a/doc/install/relative_url.md +++ b/doc/install/relative_url.md @@ -11,7 +11,7 @@ this is not possible due to a variety of reasons. In that case, GitLab can also be installed under a relative URL, for example `https://example.com/gitlab`. This document describes how to run GitLab under a relative URL for installations -from source. If you are using an Omnibus package, +from source. If you are using an official Linux package, [the steps are different](https://docs.gitlab.com/omnibus/settings/configuration.html#configuring-a-relative-url-for-gitlab). Use this guide along with the [installation guide](installation.md) if you are installing GitLab for the first time. diff --git a/doc/install/requirements.md b/doc/install/requirements.md index b60d3fd8359..02bc2084e0d 100644 --- a/doc/install/requirements.md +++ b/doc/install/requirements.md @@ -14,7 +14,7 @@ This page includes information about the minimum requirements you need to instal The necessary hard drive space largely depends on the size of the repositories you want to store in GitLab but as a *guideline* you should have at least as much free space as all your repositories combined take up. -The Omnibus GitLab package requires about 2.5 GB of storage space for installation. +The Linux package requires about 2.5 GB of storage space for installation. If you want to be flexible about growing your hard drive space in the future consider mounting it using [logical volume management (LVM)](https://en.wikipedia.org/wiki/Logical_volume_management) so you can add more hard drives when you need them. @@ -66,7 +66,7 @@ process, such as PostgreSQL, which can have disastrous consequences. ## Database -PostgreSQL is the only supported database, which is bundled with the Omnibus GitLab package. +PostgreSQL is the only supported database, which is bundled with the Linux package. You can also use an [external PostgreSQL database](https://docs.gitlab.com/omnibus/settings/database.html#using-a-non-packaged-postgresql-database-management-server). ### PostgreSQL Requirements @@ -106,10 +106,9 @@ Support for [PostgreSQL 9.6 and 10 was removed in GitLab 13.0](https://about.git #### Additional requirements for GitLab Geo If you're using [GitLab Geo](../administration/geo/index.md), we strongly -recommend running Omnibus GitLab-managed instances, as we actively develop and -test based on those. We try to be compatible with most external (not managed by -Omnibus GitLab) databases (for example, [AWS Relational Database Service (RDS)](https://aws.amazon.com/rds/)), -but we can't guarantee compatibility. +recommend running instances installed by using the Linux package, as we actively develop and +test based on those. We try to be compatible with most external (not managed by a Linux package installation) databases +(for example, [AWS Relational Database Service (RDS)](https://aws.amazon.com/rds/)), but we can't guarantee compatibility. #### Operating system locale compatibility and silent index corruption diff --git a/doc/integration/kerberos.md b/doc/integration/kerberos.md index 763c2e441f8..14e22853d19 100644 --- a/doc/integration/kerberos.md +++ b/doc/integration/kerberos.md @@ -44,7 +44,7 @@ sudo chmod 0600 /etc/http.keytab #### Installations from source NOTE: -For source installations, make sure the `kerberos` gem group +For self-compiled installations, make sure the `kerberos` gem group [has been installed](../install/installation.md#install-gems). 1. Edit the `kerberos` section of [`gitlab.yml`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/gitlab.yml.example) to enable Kerberos ticket-based @@ -247,7 +247,21 @@ NOTE: username and password is passed interactively or through a credentials manager. It fails to fall back when the username and password is passed as part of the URL instead. For example, this can happen in GitLab CI/CD jobs that [authenticate with the CI/CD job token](../ci/jobs/ci_job_token.md). -**For source installations with HTTPS** +::Tabs + +:::TabTitle Linux package (Omnibus) + +1. Edit `/etc/gitlab/gitlab.rb`: + + ```ruby + gitlab_rails['kerberos_use_dedicated_port'] = true + gitlab_rails['kerberos_port'] = 8443 + gitlab_rails['kerberos_https'] = true + ``` + +1. [Reconfigure GitLab](../administration/restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect. + +:::TabTitle Self-compiled (source) with HTTPS 1. Edit the NGINX configuration file for GitLab (for example, `/etc/nginx/sites-available/gitlab-ssl`) and configure NGINX to @@ -276,17 +290,7 @@ this can happen in GitLab CI/CD jobs that [authenticate with the CI/CD job token 1. [Restart GitLab](../administration/restart_gitlab.md#installations-from-source) and NGINX for the changes to take effect. -**For Omnibus package installations** - -1. Edit `/etc/gitlab/gitlab.rb`: - - ```ruby - gitlab_rails['kerberos_use_dedicated_port'] = true - gitlab_rails['kerberos_port'] = 8443 - gitlab_rails['kerberos_https'] = true - ``` - -1. [Reconfigure GitLab](../administration/restart_gitlab.md#reconfigure-a-linux-package-installation) for the changes to take effect. +::EndTabs After this change, Git remote URLs have to be updated to `https://gitlab.example.com:8443/mygroup/myproject.git` to use diff --git a/doc/raketasks/index.md b/doc/raketasks/index.md index e998c97a4d7..e97e453f118 100644 --- a/doc/raketasks/index.md +++ b/doc/raketasks/index.md @@ -11,8 +11,8 @@ processes. You can perform GitLab Rake tasks by using: -- `gitlab-rake <raketask>` for [Omnibus GitLab](https://docs.gitlab.com/omnibus/index.html) and [GitLab Helm chart](https://docs.gitlab.com/charts/troubleshooting/kubernetes_cheat_sheet.html#gitlab-specific-kubernetes-information) installations. -- `bundle exec rake <raketask>` for [source](../install/installation.md) installations. +- `gitlab-rake <raketask>` for [Linux package](https://docs.gitlab.com/omnibus/index.html) and [GitLab Helm chart](https://docs.gitlab.com/charts/troubleshooting/kubernetes_cheat_sheet.html#gitlab-specific-kubernetes-information) installations. +- `bundle exec rake <raketask>` for [self-compiled](../install/installation.md) installations. ## Available Rake tasks diff --git a/doc/security/crime_vulnerability.md b/doc/security/crime_vulnerability.md index 39cd8f8e074..fdf3e5055b0 100644 --- a/doc/security/crime_vulnerability.md +++ b/doc/security/crime_vulnerability.md @@ -23,10 +23,10 @@ GitLab supports both Gzip and [SPDY](https://nginx.org/en/docs/http/ngx_http_spd vulnerability by deactivating Gzip when HTTPS is enabled. The sources of the files are here: -- [Source installation NGINX file](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/support/nginx/gitlab-ssl) -- [Omnibus installation NGINX file](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/files/gitlab-cookbooks/gitlab/templates/default/nginx-gitlab-http.conf.erb) +- [Self-compiled installation NGINX file](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/support/nginx/gitlab-ssl) +- [Linux package installation NGINX file](https://gitlab.com/gitlab-org/omnibus-gitlab/blob/master/files/gitlab-cookbooks/gitlab/templates/default/nginx-gitlab-http.conf.erb) -Although SPDY is enabled in Omnibus installations, CRIME relies on compression +Although SPDY is enabled in Linux package installations, CRIME relies on compression (the 'C') and the default compression level in the NGINX SPDY module is 0 (no compression). diff --git a/doc/topics/manage_code.md b/doc/topics/manage_code.md index 136e471d14a..5e9160338a9 100644 --- a/doc/topics/manage_code.md +++ b/doc/topics/manage_code.md @@ -6,7 +6,8 @@ info: To determine the technical writer assigned to the Stage/Group associated w # Manage your code **(FREE)** -Store your source files in a repository, and make changes to them by using merge requests. +Store your source files in a repository, create merge requests, and compile code hosted on GitLab. - [Repositories](../user/project/repository/index.md) - [Merge requests](../user/project/merge_requests/index.md) +- [Remote development](../user/project/remote_development/index.md) diff --git a/doc/update/index.md b/doc/update/index.md index dae16f0f874..dcb9db0e49f 100644 --- a/doc/update/index.md +++ b/doc/update/index.md @@ -26,7 +26,7 @@ Depending on the installation method and your GitLab version, there are multiple official ways to upgrade GitLab: - [Linux packages (Omnibus GitLab)](#linux-packages-omnibus-gitlab) -- [Source installations](#installation-from-source) +- [Self-compiled installations](#self-compiled-installation) - [Docker installations](#installation-using-docker) - [Kubernetes (Helm) installations](#installation-using-helm) @@ -39,7 +39,7 @@ repositories. There are also instructions when you want to [upgrade to a specific version](package/index.md#upgrade-to-a-specific-version-using-the-official-repositories). -### Installation from source +### Self-compiled installation - [Upgrading Community Edition and Enterprise Edition from source](upgrading_from_source.md) - The guidelines for upgrading Community Edition and Enterprise Edition from source. @@ -114,21 +114,25 @@ This section is only applicable if you have enabled the [Elasticsearch integrati Major releases require all [advanced search migrations](../integration/advanced_search/elasticsearch.md#advanced-search-migrations) to be finished from the most recent minor release in your current version before the major version upgrade. You can find pending migrations by -running the following command: +running the following command. -**For Omnibus installations** +::Tabs + +:::TabTitle Linux package (Omnibus) ```shell sudo gitlab-rake gitlab:elastic:list_pending_migrations ``` -**For installations from source** +:::TabTitle Self-compiled (source) ```shell cd /home/git/gitlab sudo -u git -H bundle exec rake gitlab:elastic:list_pending_migrations ``` +::EndTabs + ### What do you do if your advanced search migrations are stuck? In GitLab 15.0, an advanced search migration named `DeleteOrphanedCommit` can be permanently stuck @@ -491,8 +495,8 @@ For more information, see [issue 415724](https://gitlab.com/gitlab-org/gitlab/-/ For example, previously: - - Omnibus GitLab default (`sidekiq['max_concurrency']`): 50 - - From source installation default: 50 + - Linux package installation default (`sidekiq['max_concurrency']`): 50 + - Self-compiled installation default: 50 - Helm chart default (`gitlab.sidekiq.concurrency`): 25 Reference architectures still use a default of 10 as this is set specifically @@ -1017,7 +1021,7 @@ that may remain stuck permanently in a **pending** state. ### 14.5.0 - When `make` is run, Gitaly builds are now created in `_build/bin` and no longer in the root directory of the source directory. If you -are using a source install, update paths to these binaries in your [systemd unit files](upgrading_from_source.md#configure-systemd-units) +are using a self-compiled installation, update paths to these binaries in your [systemd unit files](upgrading_from_source.md#configure-systemd-units) or [init scripts](upgrading_from_source.md#configure-sysv-init-script) by [following the documentation](upgrading_from_source.md). - Connections between Workhorse and Gitaly use the Gitaly `backchannel` protocol by default. If you deployed a gRPC proxy between Workhorse and Gitaly, @@ -1380,7 +1384,7 @@ It is not then required to upgrade to 15.9.3 or later for this issue. ### Gitaly: Omnibus GitLab configuration structure change Gitaly configuration structure in Omnibus GitLab [changes](https://gitlab.com/gitlab-org/gitaly/-/issues/4467) in GitLab 16.0 to be consistent with the Gitaly configuration -structure used in source installs. +structure used in self-compiled installations. As a result of this change, a single hash under `gitaly['configuration']` holds most Gitaly configuration. Some `gitaly['..']` configuration options will continue to be used by Omnibus GitLab 16.0 and later: @@ -1542,7 +1546,7 @@ gitaly['configuration'] = { ### Praefect: Omnibus GitLab configuration structure change Praefect configuration structure in Omnibus GitLab [changes](https://gitlab.com/gitlab-org/gitaly/-/issues/4467) in GitLab 16.0 to be consistent with the Praefect configuration -structure used in source installs. +structure used in self-compiled installations. As a result of this change, a single hash under `praefect['configuration']` holds most Praefect configuration. Some `praefect['..']` configuration options will continue to be used by Omnibus GitLab 16.0 and later: diff --git a/doc/update/plan_your_upgrade.md b/doc/update/plan_your_upgrade.md index 634c430e251..0a67cf174c8 100644 --- a/doc/update/plan_your_upgrade.md +++ b/doc/update/plan_your_upgrade.md @@ -105,7 +105,7 @@ to your instance and then upgrade it for any relevant features you're using. - Generate an upgrade plan by reading and understanding the relevant documentation: - upgrade based on the installation method: - [Linux package (Omnibus)](index.md#linux-packages-omnibus-gitlab) - - [Compiled from source](index.md#installation-from-source) + - [Self-compiled](index.md#self-compiled-installation) - [Docker](index.md#installation-using-docker) - [Helm Charts](index.md#installation-using-helm) - [Zero-downtime upgrades](zero_downtime.md) (if possible and desired) diff --git a/doc/user/profile/achievements.md b/doc/user/profile/achievements.md index a90144beb1b..6222dbf7bca 100644 --- a/doc/user/profile/achievements.md +++ b/doc/user/profile/achievements.md @@ -115,7 +115,7 @@ To supply the avatar file, call the mutation using `curl`: curl "https://gitlab.com/api/graphql" \ -H "Authorization: Bearer <your-pat-token>" \ -H "Content-Type: multipart/form-data" \ - -F operations='{ "query": "mutation ($file: Upload!) { achievementsCreate(input: { namespaceId: \"gid://gitlab/Namespace/<namespace-id>\", name: \"<name>\", description: \"<description>\", avatar: $file }) { achievement { id name description avatarUrl } } }", "variables": { "file": null } }' \ + -F operations='{ "query": "mutation ($file: Upload!) { achievementsCreate(input: { namespaceId: \"gid://gitlab/Namespace/<namespace-id>\", name: \"<name>\", description: \"<description>\", avatar: $file }) { achievement { id name description avatarUrl } } }", "variables": { "file": null } }' \ -F map='{ "0": ["variables.file"] }' \ -F 0='@/path/to/your/file.jpg' ``` @@ -252,7 +252,7 @@ mutation { ## Delete an achievement If you consider you no longer need an achievement, you can delete it. -This will delete all related awarded and revoked instances of the achievement. +This deletes all related awarded and revoked instances of the achievement. Prerequisites: diff --git a/doc/user/workspace/configuration.md b/doc/user/workspace/configuration.md new file mode 100644 index 00000000000..b94170644d6 --- /dev/null +++ b/doc/user/workspace/configuration.md @@ -0,0 +1,169 @@ +--- +stage: Create +group: IDE +info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/product/ux/technical-writing/#assignments +--- + +# Workspace configuration (Beta) **(PREMIUM)** + +> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/112397) in GitLab 15.11 [with a flag](../../administration/feature_flags.md) named `remote_development_feature_flag`. Disabled by default. +> - [Enabled on GitLab.com and self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/391543) in GitLab 16.0. + +FLAG: +On self-managed GitLab, by default this feature is available. To hide the feature, an administrator can [disable the feature flag](../../administration/feature_flags.md) named `remote_development_feature_flag`. On GitLab.com, this feature is available. The feature is not ready for production use. + +WARNING: +This feature is in [Beta](../../policy/experiment-beta-support.md#beta) and subject to change without notice. To leave feedback, see the [feedback issue](https://gitlab.com/gitlab-org/gitlab/-/issues/410031). + +You can use [workspaces](index.md) to create and manage isolated development environments for your GitLab projects. Each workspace includes its own set of dependencies, libraries, and tools, which you can customize to meet the specific needs of each project. + +## Set up a workspace + +### Prerequisites + +- Set up a Kubernetes cluster that the GitLab agent for Kubernetes supports. See the [supported Kubernetes versions](../clusters/agent/index.md#supported-kubernetes-versions-for-gitlab-features). +- Ensure autoscaling for the Kubernetes cluster is enabled. +- In the Kubernetes cluster, verify that a [default storage class](https://kubernetes.io/docs/concepts/storage/storage-classes/) is defined so that volumes can be dynamically provisioned for each workspace. +- In the Kubernetes cluster, install an Ingress controller of your choice (for example, `ingress-nginx`) and make that controller accessible over a domain. For example, point `*.workspaces.example.dev` and `workspaces.example.dev` to the load balancer exposed by the Ingress controller. +- In the Kubernetes cluster, [install `gitlab-workspaces-proxy`](https://gitlab.com/gitlab-org/remote-development/gitlab-workspaces-proxy#installation-instructions). +- In the Kubernetes cluster, [install the GitLab agent for Kubernetes](../clusters/agent/install/index.md). +- Configure remote development settings for the GitLab agent with this snippet and update `dns_zone` as needed: + + ```yaml + remote_development: + enabled: true + dns_zone: "workspaces.example.dev" + ``` + + You can use any agent defined under the root group of your project, provided that remote development is properly configured for that agent. +- You must have at least the Developer role in the root group. +- In each public project you want to use this feature for, create a [devfile](index.md#devfile): + 1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project + 1. In the root directory of your project, create a file named `.devfile.yaml`. You can use one of the [example configurations](index.md#example-configurations). +- Ensure the container images used in the devfile support [arbitrary user IDs](index.md#arbitrary-user-ids). + +### Create a workspace + +To create a workspace: + +1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). +1. Select **Your work**. +1. Select **Workspaces**. +1. Select **New workspace**. +1. From the **Select project** dropdown list, [select a project with a `.devfile.yaml` file](#prerequisites). You can only create workspaces for public projects. +1. From the **Select cluster agent** dropdown list, select a cluster agent owned by the group the project belongs to. +1. In **Time before automatic termination**, enter the number of hours until the workspace automatically terminates. This timeout is a safety measure to prevent a workspace from consuming excessive resources or running indefinitely. +1. Select **Create workspace**. + +The workspace might take a few minutes to start. To open the workspace, under **Preview**, select the workspace. +You also have access to the terminal and can install any necessary dependencies. + +## Connect to a workspace with SSH + +Prerequisites: + +- SSH must be enabled for the workspace. +- You must have a TCP load balancer that points to [`gitlab-workspaces-proxy`](https://gitlab.com/gitlab-org/remote-development/gitlab-workspaces-proxy). + +To connect to a workspace with an SSH client: + +1. Run this command: + + ```shell + ssh <workspace_name>@<ssh_proxy> + ``` + +1. For the password, enter your personal access token with at least the `read_api` scope. + +When you connect to `gitlab-workspaces-proxy` through the TCP load balancer, `gitlab-workspaces-proxy` examines the username (workspace name) and interacts with GitLab to verify: + +- The personal access token +- User access to the workspace + +### Set up `gitlab-workspaces-proxy` for SSH connections + +Prerequisite: + +- You must have an SSH host key for client verification. + +SSH is now enabled by default in [`gitlab-workspaces-proxy`](https://gitlab.com/gitlab-org/remote-development/gitlab-workspaces-proxy). To set up `gitlab-workspaces-proxy` with the GitLab Helm chart: + +1. Run this command: + + ```shell + ssh-keygen -f ssh-host-key -N '' -t rsa + export SSH_HOST_KEY=$(pwd)/ssh-host-key + ``` + +1. Install `gitlab-workspaces-proxy` with the generated SSH host key: + + ```shell + helm upgrade --install gitlab-workspaces-proxy \ + gitlab-workspaces-proxy/gitlab-workspaces-proxy \ + --version 0.1.8 \ + --namespace=gitlab-workspaces \ + --create-namespace \ + --set="auth.client_id=${CLIENT_ID}" \ + --set="auth.client_secret=${CLIENT_SECRET}" \ + --set="auth.host=${GITLAB_URL}" \ + --set="auth.redirect_uri=${REDIRECT_URI}" \ + --set="auth.signing_key=${SIGNING_KEY}" \ + --set="ingress.host.workspaceDomain=${GITLAB_WORKSPACES_PROXY_DOMAIN}" \ + --set="ingress.host.wildcardDomain=${GITLAB_WORKSPACES_WILDCARD_DOMAIN}" \ + --set="ingress.tls.workspaceDomainCert=$(cat ${WORKSPACES_DOMAIN_CERT})" \ + --set="ingress.tls.workspaceDomainKey=$(cat ${WORKSPACES_DOMAIN_KEY})" \ + --set="ingress.tls.wildcardDomainCert=$(cat ${WILDCARD_DOMAIN_CERT})" \ + --set="ingress.tls.wildcardDomainKey=$(cat ${WILDCARD_DOMAIN_KEY})" \ + --set="ssh.host_key=$(cat ${SSH_HOST_KEY})" \ + --set="ingress.className=nginx" + ``` + +### Update your runtime images + +To update your runtime images for SSH connections: + +1. Install [`sshd`](https://man.openbsd.org/sshd.8) in your runtime images. +1. Create a user named `gitlab-workspaces` to allow access to your container without a password. + +```Dockerfile +FROM golang:1.20.5-bullseye + +# Install `openssh-server` and other dependencies +RUN apt update \ + && apt upgrade -y \ + && apt install openssh-server sudo curl git wget software-properties-common apt-transport-https --yes \ + && rm -rf /var/lib/apt/lists/* + +# Permit empty passwords +RUN sed -i 's/nullok_secure/nullok/' /etc/pam.d/common-auth +RUN echo "PermitEmptyPasswords yes" >> /etc/ssh/sshd_config + +# Generate a workspace host key +RUN ssh-keygen -A +RUN chmod 775 /etc/ssh/ssh_host_rsa_key && \ + chmod 775 /etc/ssh/ssh_host_ecdsa_key && \ + chmod 775 /etc/ssh/ssh_host_ed25519_key + +# Create a `gitlab-workspaces` user +RUN useradd -l -u 5001 -G sudo -md /home/gitlab-workspaces -s /bin/bash gitlab-workspaces +RUN passwd -d gitlab-workspaces +ENV HOME=/home/gitlab-workspaces +WORKDIR $HOME +RUN mkdir -p /home/gitlab-workspaces && chgrp -R 0 /home && chmod -R g=u /etc/passwd /etc/group /home + +# Allow sign-in access to `/etc/shadow` +RUN chmod 775 /etc/shadow + +USER gitlab-workspaces +``` + +## Disable remote development in the GitLab agent for Kubernetes + +You can stop the `remote_development` module of the GitLab agent for Kubernetes from communicating with GitLab. To disable remote development in the GitLab agent configuration, set this property: + +```yaml +remote_development: + enabled: false +``` + +If you already have running workspaces, an administrator must manually delete these workspaces in Kubernetes. diff --git a/doc/user/workspace/index.md b/doc/user/workspace/index.md index ccb3f176993..e3dda1ab389 100644 --- a/doc/user/workspace/index.md +++ b/doc/user/workspace/index.md @@ -19,47 +19,6 @@ A workspace is a virtual sandbox environment for your code in GitLab. You can us Each workspace includes its own set of dependencies, libraries, and tools, which you can customize to meet the specific needs of each project. Workspaces use the AMD64 architecture. -## Set up a workspace - -### Prerequisites - -- Set up a Kubernetes cluster that the GitLab agent for Kubernetes supports. See the [supported Kubernetes versions](../clusters/agent/index.md#supported-kubernetes-versions-for-gitlab-features). -- Ensure autoscaling for the Kubernetes cluster is enabled. -- In the Kubernetes cluster, verify that a [default storage class](https://kubernetes.io/docs/concepts/storage/storage-classes/) is defined so that volumes can be dynamically provisioned for each workspace. -- In the Kubernetes cluster, install an Ingress controller of your choice (for example, `ingress-nginx`) and make that controller accessible over a domain. For example, point `*.workspaces.example.dev` and `workspaces.example.dev` to the load balancer exposed by the Ingress controller. -- In the Kubernetes cluster, [install `gitlab-workspaces-proxy`](https://gitlab.com/gitlab-org/remote-development/gitlab-workspaces-proxy#installation-instructions). -- In the Kubernetes cluster, [install the GitLab agent for Kubernetes](../clusters/agent/install/index.md). -- Configure remote development settings for the GitLab agent with this snippet and update `dns_zone` as needed: - - ```yaml - remote_development: - enabled: true - dns_zone: "workspaces.example.dev" - ``` - - You can use any agent defined under the root group of your project, provided that remote development is properly configured for that agent. -- You must have at least the Developer role in the root group. -- In each public project you want to use this feature for, create a [devfile](#devfile): - 1. On the left sidebar, at the top, select **Search GitLab** (**{search}**) to find your project - 1. In the root directory of your project, create a file named `.devfile.yaml`. You can use one of the [example configurations](#example-configurations). -- Ensure the container images used in the devfile support [arbitrary user IDs](#arbitrary-user-ids). - -### Create a workspace - -To create a workspace: - -1. On the left sidebar, expand the top-most chevron (**{chevron-down}**). -1. Select **Your work**. -1. Select **Workspaces**. -1. Select **New workspace**. -1. From the **Select project** dropdown list, [select a project with a `.devfile.yaml` file](#prerequisites). You can only create workspaces for public projects. -1. From the **Select cluster agent** dropdown list, select a cluster agent owned by the group the project belongs to. -1. In **Time before automatic termination**, enter the number of hours until the workspace automatically terminates. This timeout is a safety measure to prevent a workspace from consuming excessive resources or running indefinitely. -1. Select **Create workspace**. - -The workspace might take a few minutes to start. To open the workspace, under **Preview**, select the workspace. -You also have access to the terminal and can install any necessary dependencies. - ## Workspaces and projects Workspaces are scoped to a project. When you create a workspace, you must: @@ -93,7 +52,7 @@ When you delete a project, agent, user, or token associated with a workspace: To clean up orphaned resources, an administrator must manually delete the workspace in Kubernetes. -For more information about our plans to change the current behavior, see [issue 414384](https://gitlab.com/gitlab-org/gitlab/-/issues/414384). +[Issue 414384](https://gitlab.com/gitlab-org/gitlab/-/issues/414384) proposes to change this behavior. ## Devfile @@ -177,17 +136,6 @@ When you stop a workspace, the compute resources for that workspace are scaled d To delete the provisioned volume, you must terminate the workspace. -## Disable remote development in the GitLab agent for Kubernetes - -You can stop the `remote_development` module of the GitLab agent for Kubernetes from communicating with GitLab. To disable remote development in the GitLab agent configuration, set this property: - -```yaml -remote_development: - enabled: false -``` - -If you already have running workspaces, an administrator must manually delete these workspaces in Kubernetes. - ## Arbitrary user IDs You can provide your own container image, which can run as any Linux user ID. It's not possible for GitLab to predict the Linux user ID for a container image. @@ -205,8 +153,6 @@ For more information, see the [OpenShift documentation](https://docs.openshift.c ## Troubleshooting -When working with workspaces, you might encounter the following issues. - ### `Failed to renew lease` when creating a workspace You might not be able to create a workspace due to a known issue in the GitLab agent for Kubernetes. The following error message might appear in the agent's log: diff --git a/lib/gitlab/database/health_status/indicators/patroni_apdex.rb b/lib/gitlab/database/health_status/indicators/patroni_apdex.rb index 680c86cf7b2..98fc530369a 100644 --- a/lib/gitlab/database/health_status/indicators/patroni_apdex.rb +++ b/lib/gitlab/database/health_status/indicators/patroni_apdex.rb @@ -40,7 +40,7 @@ module Gitlab end def fetch_connection_error_message - return 'Patroni Apdex Settings not configured' unless database_apdex_settings.present? + return 'Patroni Apdex Settings not configured' unless prometheus_alert_db_indicators_settings.present? return 'Prometheus client is not ready' unless client.ready? return 'Apdex SLI query is not configured' unless apdex_sli_query return 'Apdex SLO is not configured' unless apdex_slo @@ -48,28 +48,30 @@ module Gitlab def client @client ||= Gitlab::PrometheusClient.new( - database_apdex_settings[:prometheus_api_url], + prometheus_alert_db_indicators_settings[:prometheus_api_url], allow_local_requests: true, verify: true ) end - def database_apdex_settings - @database_apdex_settings ||= Gitlab::CurrentSettings.database_apdex_settings&.with_indifferent_access + def prometheus_alert_db_indicators_settings + @prometheus_alert_db_indicators_settings ||= Gitlab::CurrentSettings + .prometheus_alert_db_indicators_settings + &.with_indifferent_access end def apdex_sli_query { - gitlab_main: database_apdex_settings[:apdex_sli_query][:main], - gitlab_ci: database_apdex_settings[:apdex_sli_query][:ci] + gitlab_main: prometheus_alert_db_indicators_settings[:apdex_sli_query][:main], + gitlab_ci: prometheus_alert_db_indicators_settings[:apdex_sli_query][:ci] }.fetch(gitlab_schema) end strong_memoize_attr :apdex_sli_query def apdex_slo { - gitlab_main: database_apdex_settings[:apdex_slo][:main], - gitlab_ci: database_apdex_settings[:apdex_slo][:ci] + gitlab_main: prometheus_alert_db_indicators_settings[:apdex_slo][:main], + gitlab_ci: prometheus_alert_db_indicators_settings[:apdex_slo][:ci] }.fetch(gitlab_schema) end strong_memoize_attr :apdex_slo diff --git a/locale/gitlab.pot b/locale/gitlab.pot index a7225098388..952e3e6e6ee 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -5552,6 +5552,9 @@ msgstr "" msgid "Another issue tracker is already in use. Only one issue tracker service can be active at a time" msgstr "" +msgid "Another open merge request already exists for this source branch: %{conflicting_mr_reference}" +msgstr "" + msgid "Another third-party wiki is already in use. Only one third-party wiki integration can be active at a time" msgstr "" @@ -15381,7 +15384,7 @@ msgstr "" msgid "DefaultBranchProtection|Protected against pushes" msgstr "" -msgid "Define a custom deploy freeze pattern with %{cronSyntaxStart}cron syntax%{cronSyntaxEnd}" +msgid "Define a custom deploy freeze pattern with %{cronSyntaxStart}cron syntax%{cronSyntaxEnd}." msgstr "" msgid "Define a custom pattern with cron syntax" @@ -15909,9 +15912,6 @@ msgstr "" msgid "DeployFreeze|Add deploy freeze" msgstr "" -msgid "DeployFreeze|Delete" -msgstr "" - msgid "DeployFreeze|Delete deploy freeze?" msgstr "" @@ -15921,7 +15921,7 @@ msgstr "" msgid "DeployFreeze|Deploy freeze from %{start} to %{end} in %{timezone} will be removed. Are you sure?" msgstr "" -msgid "DeployFreeze|Edit" +msgid "DeployFreeze|Deploy freezes" msgstr "" msgid "DeployFreeze|Freeze end" @@ -15930,7 +15930,7 @@ msgstr "" msgid "DeployFreeze|Freeze start" msgstr "" -msgid "DeployFreeze|No deploy freezes exist for this project. To add one, select %{strongStart}Add deploy freeze%{strongEnd}" +msgid "DeployFreeze|No deploy freezes exist for this project. To add one, select %{strongStart}Add deploy freeze%{strongEnd} above." msgstr "" msgid "DeployFreeze|Specify deploy freezes using %{cron_syntax_link_start}cron syntax%{cron_syntax_link_end}." @@ -35859,6 +35859,9 @@ msgstr "" msgid "Profiles|Add new email" msgstr "" +msgid "Profiles|Add new mirror repository" +msgstr "" + msgid "Profiles|An error occurred while updating your username, please try again." msgstr "" diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb index 5f03d721fe7..4b091e9221e 100644 --- a/spec/controllers/projects/environments_controller_spec.rb +++ b/spec/controllers/projects/environments_controller_spec.rb @@ -373,7 +373,7 @@ RSpec.describe Projects::EnvironmentsController, feature_category: :continuous_d end context 'when stop action' do - it 'returns action url for single stop action' do + it 'returns job url for a stop action when job is build' do action = create(:ci_build, :manual) allow_any_instance_of(Environment) @@ -387,6 +387,20 @@ RSpec.describe Projects::EnvironmentsController, feature_category: :continuous_d project_job_url(project, action) }) end + it 'returns pipeline url for a stop action when job is bridge' do + action = create(:ci_bridge, :manual) + + allow_any_instance_of(Environment) + .to receive_messages(available?: true, stop_with_actions!: [action]) + + subject + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response).to eq( + { 'redirect_url' => + project_pipeline_url(project, action.pipeline_id) }) + end + it 'returns environment url for multiple stop actions' do actions = create_list(:ci_build, 2, :manual) diff --git a/spec/features/projects/settings/repository_settings_spec.rb b/spec/features/projects/settings/repository_settings_spec.rb index d53aefe5a4e..838ac67ee3d 100644 --- a/spec/features/projects/settings/repository_settings_spec.rb +++ b/spec/features/projects/settings/repository_settings_spec.rb @@ -156,6 +156,7 @@ RSpec.describe 'Projects > Settings > Repository settings', feature_category: :g before do visit project_settings_repository_path(project) + click_button 'Add new' end it 'shows push mirror settings', :js do diff --git a/spec/frontend/comment_templates/components/form_spec.js b/spec/frontend/comment_templates/components/form_spec.js index 053a5099c37..b48feba5290 100644 --- a/spec/frontend/comment_templates/components/form_spec.js +++ b/spec/frontend/comment_templates/components/form_spec.js @@ -5,6 +5,7 @@ import VueApollo from 'vue-apollo'; import createdSavedReplyResponse from 'test_fixtures/graphql/comment_templates/create_saved_reply.mutation.graphql.json'; import createdSavedReplyErrorResponse from 'test_fixtures/graphql/comment_templates/create_saved_reply_with_errors.mutation.graphql.json'; import createMockApollo from 'helpers/mock_apollo_helper'; +import { mockTracking } from 'helpers/tracking_helper'; import waitForPromises from 'helpers/wait_for_promises'; import Form from '~/comment_templates/components/form.vue'; import createSavedReplyMutation from '~/comment_templates/queries/create_saved_reply.mutation.graphql'; @@ -52,6 +53,12 @@ const findSubmitBtn = () => wrapper.find('[data-testid="comment-template-form-su describe('Comment templates form component', () => { describe('creates comment template', () => { + let trackingSpy; + + beforeEach(() => { + trackingSpy = mockTracking(undefined, window.document, jest.spyOn); + }); + it('calls apollo mutation', async () => { wrapper = createComponent(); @@ -66,6 +73,11 @@ describe('Comment templates form component', () => { content: 'Test content', name: 'Test', }); + expect(trackingSpy).toHaveBeenCalledWith( + expect.any(String), + 'i_code_review_saved_replies_create', + expect.any(Object), + ); }); it('does not submit when form validation fails', async () => { diff --git a/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js b/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js index 6a9e482a184..e9e7f7fdb88 100644 --- a/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js +++ b/spec/frontend/deploy_freeze/components/deploy_freeze_table_spec.js @@ -45,7 +45,9 @@ describe('Deploy freeze table', () => { it('displays empty', () => { expect(findEmptyFreezePeriods().exists()).toBe(true); expect(findEmptyFreezePeriods().text()).toBe( - 'No deploy freezes exist for this project. To add one, select Add deploy freeze', + `No deploy freezes exist for this project. To add one, select + Add deploy freeze + above.`, ); }); diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js index 0cbb9eab018..8b8241f395f 100644 --- a/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js +++ b/spec/frontend/packages_and_registries/container_registry/explorer/components/details_page/tags_list_spec.js @@ -9,6 +9,7 @@ import component from '~/packages_and_registries/container_registry/explorer/com import TagsListRow from '~/packages_and_registries/container_registry/explorer/components/details_page/tags_list_row.vue'; import TagsLoader from '~/packages_and_registries/shared/components/tags_loader.vue'; import RegistryList from '~/packages_and_registries/shared/components/registry_list.vue'; +import PersistedPagination from '~/packages_and_registries/shared/components/persisted_pagination.vue'; import PersistedSearch from '~/packages_and_registries/shared/components/persisted_search.vue'; import getContainerRepositoryTagsQuery from '~/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repository_tags.query.graphql'; import deleteContainerRepositoryTagsMutation from '~/packages_and_registries/container_registry/explorer/graphql/mutations/delete_container_repository_tags.mutation.graphql'; @@ -40,6 +41,7 @@ describe('Tags List', () => { }; const findDeleteModal = () => wrapper.findComponent(DeleteModal); + const findPersistedPagination = () => wrapper.findComponent(PersistedPagination); const findPersistedSearch = () => wrapper.findComponent(PersistedSearch); const findTagsListRow = () => wrapper.findAllComponents(TagsListRow); const findRegistryList = () => wrapper.findComponent(RegistryList); @@ -47,7 +49,7 @@ describe('Tags List', () => { const findTagsLoader = () => wrapper.findComponent(TagsLoader); const fireFirstSortUpdate = () => { - findPersistedSearch().vm.$emit('update', { sort: 'NAME_ASC', filters: [] }); + findPersistedSearch().vm.$emit('update', { sort: 'NAME_ASC', filters: [], pageInfo: {} }); }; const waitForApolloRequestRender = async () => { @@ -103,18 +105,24 @@ describe('Tags List', () => { it('binds the correct props', () => { expect(findRegistryList().props()).toMatchObject({ title: '2 tags', - pagination: tagsPageInfo, items: tags, idProperty: 'name', hiddenDelete: false, }); }); + it('has persisted pagination', () => { + expect(findPersistedPagination().props('pagination')).toEqual(tagsPageInfo); + }); + describe('events', () => { - it('prev-page fetch the previous page', async () => { - findRegistryList().vm.$emit('prev-page'); + it('prev-page fetches the previous page', async () => { + findPersistedPagination().vm.$emit('prev'); await waitForPromises(); + // we are fetching previous page after load, + // so we expect the resolver to have been called twice + expect(resolver).toHaveBeenCalledTimes(2); expect(resolver).toHaveBeenCalledWith({ first: null, name: '', @@ -125,10 +133,13 @@ describe('Tags List', () => { }); }); - it('next-page fetch the previous page', async () => { - findRegistryList().vm.$emit('next-page'); + it('next-page fetches the next page', async () => { + findPersistedPagination().vm.$emit('next'); await waitForPromises(); + // we are fetching next page after load, + // so we expect the resolver to have been called twice + expect(resolver).toHaveBeenCalledTimes(2); expect(resolver).toHaveBeenCalledWith({ after: tagsPageInfo.endCursor, first: GRAPHQL_PAGE_SIZE, @@ -182,6 +193,49 @@ describe('Tags List', () => { }); }); + describe('when persisted search emits update', () => { + beforeEach(() => { + mountComponent(); + }); + + it('with before calls resolver with pagination params', async () => { + findPersistedSearch().vm.$emit('update', { + sort: 'NAME_ASC', + filters: [], + pageInfo: { before: tagsPageInfo.startCursor }, + }); + await waitForPromises(); + + expect(resolver).toHaveBeenCalledTimes(1); + expect(resolver).toHaveBeenCalledWith({ + first: null, + name: '', + sort: 'NAME_ASC', + before: tagsPageInfo.startCursor, + last: GRAPHQL_PAGE_SIZE, + id: '1', + }); + }); + + it('with after calls resolver with pagination params', async () => { + findPersistedSearch().vm.$emit('update', { + sort: 'NAME_ASC', + filters: [], + pageInfo: { after: tagsPageInfo.endCursor }, + }); + await waitForPromises(); + + expect(resolver).toHaveBeenCalledTimes(1); + expect(resolver).toHaveBeenCalledWith({ + after: tagsPageInfo.endCursor, + first: GRAPHQL_PAGE_SIZE, + name: '', + sort: 'NAME_ASC', + id: '1', + }); + }); + }); + describe('list rows', () => { it('one row exist for each tag', async () => { mountComponent(); @@ -334,31 +388,44 @@ describe('Tags List', () => { let mutationResolver; describe('when mutation', () => { - beforeEach(() => { + beforeEach(async () => { mutationResolver = jest.fn().mockResolvedValue(graphQLDeleteImageRepositoryTagsMock); mountComponent({ mutationResolver }); - return waitForApolloRequestRender(); - }); - - it('is started renders loader', async () => { + await waitForApolloRequestRender(); findRegistryList().vm.$emit('delete', [tags[0]]); findDeleteModal().vm.$emit('confirmDelete'); - await nextTick(); + }); + + describe('starts', () => { + beforeEach(async () => { + await nextTick(); + }); + + it('renders loader', () => { + expect(findTagsLoader().exists()).toBe(true); + expect(findTagsListRow().exists()).toBe(false); + }); - expect(findTagsLoader().exists()).toBe(true); - expect(findTagsListRow().exists()).toBe(false); + it('hides pagination', () => { + expect(findPersistedPagination().exists()).toEqual(false); + }); }); - it('ends, loader is hidden', async () => { - findRegistryList().vm.$emit('delete', [tags[0]]); + describe('is resolved', () => { + beforeEach(async () => { + await waitForPromises(); + }); - findDeleteModal().vm.$emit('confirmDelete'); - await waitForPromises(); + it('loader is hidden', () => { + expect(findTagsLoader().exists()).toBe(false); + expect(findTagsListRow().exists()).toBe(true); + }); - expect(findTagsLoader().exists()).toBe(false); - expect(findTagsListRow().exists()).toBe(true); + it('pagination is shown', () => { + expect(findPersistedPagination().props('pagination')).toEqual(tagsPageInfo); + }); }); }); @@ -495,6 +562,11 @@ describe('Tags List', () => { expect(findTagsLoader().exists()).toBe(loadingVisible); expect(findTagsListRow().exists()).toBe(!loadingVisible); + if (queryExecuting) { + expect(findPersistedPagination().props('pagination')).toEqual({}); + } else { + expect(findPersistedPagination().props('pagination')).toEqual(tagsPageInfo); + } }, ); }); diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js index c039870b768..1f1f010e0c4 100644 --- a/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js +++ b/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js @@ -228,7 +228,7 @@ describe('List Page', () => { expect(findPersistedPagination().props('pagination')).toEqual({}); }); - it('cli commands is not visible', () => { + it('cli commands are not visible', () => { mountComponent(); expect(findCliCommands().exists()).toBe(false); @@ -243,11 +243,42 @@ describe('List Page', () => { }); }); + describe('when mutation is loading', () => { + beforeEach(async () => { + mountComponent(); + fireFirstSortUpdate(); + await waitForApolloRequestRender(); + findImageList().vm.$emit('delete', deletedContainerRepository); + findDeleteModal().vm.$emit('confirmDelete'); + findDeleteImage().vm.$emit('start'); + }); + + it('shows the skeleton loader', () => { + expect(findSkeletonLoader().exists()).toBe(true); + }); + + it('imagesList is not visible', () => { + expect(findImageList().exists()).toBe(false); + }); + + it('pagination is hidden', () => { + expect(findPersistedPagination().exists()).toBe(false); + }); + + it('cli commands are not visible', () => { + expect(findCliCommands().exists()).toBe(false); + }); + + it('title has the metadataLoading props set to true', () => { + expect(findRegistryHeader().props('metadataLoading')).toBe(true); + }); + }); + describe('list is empty', () => { describe('project page', () => { const resolver = jest.fn().mockResolvedValue(graphQLEmptyImageListMock); - it('cli commands is not visible', async () => { + it('cli commands are not visible', async () => { mountComponent({ resolver }); await waitForApolloRequestRender(); @@ -279,7 +310,7 @@ describe('List Page', () => { expect(findGroupEmptyState().exists()).toBe(true); }); - it('cli commands is not visible', async () => { + it('cli commands are not visible', async () => { mountComponent({ resolver, config }); await waitForApolloRequestRender(); diff --git a/spec/lib/gitlab/database/health_status/indicators/patroni_apdex_spec.rb b/spec/lib/gitlab/database/health_status/indicators/patroni_apdex_spec.rb index e0e3a0a7c23..a526d951db9 100644 --- a/spec/lib/gitlab/database/health_status/indicators/patroni_apdex_spec.rb +++ b/spec/lib/gitlab/database/health_status/indicators/patroni_apdex_spec.rb @@ -33,7 +33,7 @@ RSpec.describe Gitlab::Database::HealthStatus::Indicators::PatroniApdex, :aggreg let(:database_apdex_sli_query_ci) { 'Apdex query for ci' } let(:database_apdex_slo_main) { 0.99 } let(:database_apdex_slo_ci) { 0.95 } - let(:database_apdex_settings) do + let(:prometheus_alert_db_indicators_settings) do { prometheus_api_url: prometheus_url, apdex_sli_query: { @@ -50,7 +50,7 @@ RSpec.describe Gitlab::Database::HealthStatus::Indicators::PatroniApdex, :aggreg subject(:evaluate) { described_class.new(context).evaluate } before do - stub_application_setting(database_apdex_settings: database_apdex_settings) + stub_application_setting(prometheus_alert_db_indicators_settings: prometheus_alert_db_indicators_settings) allow(Gitlab::PrometheusClient).to receive(:new).with(*prometheus_config).and_return(prometheus_client) allow(prometheus_client).to receive(:ready?).and_return(client_ready) @@ -69,8 +69,8 @@ RSpec.describe Gitlab::Database::HealthStatus::Indicators::PatroniApdex, :aggreg expect(evaluate.reason).to include('indicator disabled') end - context 'without database_apdex_settings' do - let(:database_apdex_settings) { nil } + context 'without prometheus_alert_db_indicators_settings' do + let(:prometheus_alert_db_indicators_settings) { nil } it 'returns Unknown signal' do expect(evaluate).to be_a(Gitlab::Database::HealthStatus::Signals::Unknown) diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index b2275be5893..f447278f812 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -33,7 +33,7 @@ RSpec.describe ApplicationSetting, feature_category: :shared, type: :model do let(:ftp) { 'ftp://example.com' } let(:javascript) { 'javascript:alert(window.opener.document.location)' } - let_it_be(:valid_database_apdex_settings) do + let_it_be(:valid_prometheus_alert_db_indicators_settings) do { prometheus_api_url: 'Prometheus URL', apdex_sli_query: { @@ -260,9 +260,9 @@ RSpec.describe ApplicationSetting, feature_category: :shared, type: :model do it { is_expected.to allow_value(true, false).for(:gitlab_dedicated_instance) } it { is_expected.not_to allow_value(nil).for(:gitlab_dedicated_instance) } - it { is_expected.not_to allow_value(random: :value).for(:database_apdex_settings) } - it { is_expected.to allow_value(nil).for(:database_apdex_settings) } - it { is_expected.to allow_value(valid_database_apdex_settings).for(:database_apdex_settings) } + it { is_expected.not_to allow_value(random: :value).for(:prometheus_alert_db_indicators_settings) } + it { is_expected.to allow_value(nil).for(:prometheus_alert_db_indicators_settings) } + it { is_expected.to allow_value(valid_prometheus_alert_db_indicators_settings).for(:prometheus_alert_db_indicators_settings) } it { is_expected.to allow_value([true, false]).for(:silent_mode_enabled) } it { is_expected.not_to allow_value(nil).for(:silent_mode_enabled) } diff --git a/spec/requests/projects/merge_requests/creations_spec.rb b/spec/requests/projects/merge_requests/creations_spec.rb index e8a073fef5f..8f55aa90bee 100644 --- a/spec/requests/projects/merge_requests/creations_spec.rb +++ b/spec/requests/projects/merge_requests/creations_spec.rb @@ -10,6 +10,17 @@ RSpec.describe 'merge requests creations', feature_category: :code_review_workfl let_it_be(:project) { create(:project, :repository, group: group) } let_it_be(:user) { create(:user) } + let(:get_params) do + { + namespace_id: project.namespace.to_param, + project_id: project, + merge_request: { + source_branch: 'two-commits', + target_branch: 'master' + } + } + end + before_all do group.add_developer(user) end @@ -18,16 +29,52 @@ RSpec.describe 'merge requests creations', feature_category: :code_review_workfl login_as(user) end - def get_new - get namespace_project_new_merge_request_path(namespace_id: project.namespace, project_id: project) + def get_new(params = get_params) + get namespace_project_new_merge_request_path(params) end - it 'avoids N+1 DB queries even with forked projects' do - control = ActiveRecord::QueryRecorder.new(skip_cached: false) { get_new } + describe 'GET new' do + context 'without merge_request params' do + it 'avoids N+1 DB queries even with forked projects' do + control = ActiveRecord::QueryRecorder.new(skip_cached: false) { get_new } + + 5.times { fork_project(project, user) } + + expect { get_new }.not_to exceed_query_limit(control) + end + + it 'renders branch selection screen' do + get_new(get_params.except(:merge_request)) + + expect(response).to be_successful + expect(response).to render_template(partial: '_new_compare') + end + end + + context 'with merge_request params' do + it 'renders new merge request widget template' do + get_new + + expect(response).to be_successful + expect(response).to render_template(partial: '_new_submit') + expect(response).not_to render_template(partial: '_new_compare') + end - 5.times { fork_project(project, user) } + context 'when existing merge request with same target and source branches' do + let_it_be(:existing_mr) { create(:merge_request) } - expect { get_new }.not_to exceed_query_limit(control) + it 'renders branch selection screen' do + allow_next_instance_of(MergeRequest) do |instance| + allow(instance).to receive(:existing_mrs_targeting_same_branch).and_return([existing_mr]) + end + + get_new + + expect(response).to be_successful + expect(response).to render_template(partial: '_new_compare') + end + end + end end it_behaves_like "observability csp policy", Projects::MergeRequests::CreationsController do |