diff --git a/.rubocop_todo/rspec/expect_change.yml b/.rubocop_todo/rspec/expect_change.yml index 497a88f40ea..fbd8acaf14c 100644 --- a/.rubocop_todo/rspec/expect_change.yml +++ b/.rubocop_todo/rspec/expect_change.yml @@ -262,7 +262,6 @@ RSpec/ExpectChange: - 'spec/models/integration_spec.rb' - 'spec/models/integrations/confluence_spec.rb' - 'spec/models/integrations/drone_ci_spec.rb' - - 'spec/models/integrations/shimo_spec.rb' - 'spec/models/label_spec.rb' - 'spec/models/members/last_group_owner_assigner_spec.rb' - 'spec/models/merge_request/cleanup_schedule_spec.rb' diff --git a/.rubocop_todo/rspec/factory_bot/avoid_create.yml b/.rubocop_todo/rspec/factory_bot/avoid_create.yml index 2243f7e61a8..d36df0b01de 100644 --- a/.rubocop_todo/rspec/factory_bot/avoid_create.yml +++ b/.rubocop_todo/rspec/factory_bot/avoid_create.yml @@ -348,7 +348,6 @@ RSpec/FactoryBot/AvoidCreate: - 'spec/lib/sidebars/projects/menus/project_information_menu_spec.rb' - 'spec/lib/sidebars/projects/menus/repository_menu_spec.rb' - 'spec/lib/sidebars/projects/menus/security_compliance_menu_spec.rb' - - 'spec/lib/sidebars/projects/menus/shimo_menu_spec.rb' - 'spec/lib/sidebars/projects/panel_spec.rb' - 'spec/mailers/abuse_report_mailer_spec.rb' - 'spec/mailers/devise_mailer_spec.rb' diff --git a/.rubocop_todo/rspec/feature_category.yml b/.rubocop_todo/rspec/feature_category.yml index 03aa8b77c60..9e78a8821e1 100644 --- a/.rubocop_todo/rspec/feature_category.yml +++ b/.rubocop_todo/rspec/feature_category.yml @@ -4071,7 +4071,6 @@ RSpec/FeatureCategory: - 'spec/lib/gitlab/themes_spec.rb' - 'spec/lib/gitlab/throttle_spec.rb' - 'spec/lib/gitlab/time_tracking_formatter_spec.rb' - - 'spec/lib/gitlab/tracking/destinations/snowplow_micro_spec.rb' - 'spec/lib/gitlab/tracking/destinations/snowplow_spec.rb' - 'spec/lib/gitlab/tracking/event_definition_spec.rb' - 'spec/lib/gitlab/tracking/helpers/weak_password_error_event_spec.rb' @@ -4275,7 +4274,6 @@ RSpec/FeatureCategory: - 'spec/lib/sidebars/projects/menus/monitor_menu_spec.rb' - 'spec/lib/sidebars/projects/menus/security_compliance_menu_spec.rb' - 'spec/lib/sidebars/projects/menus/settings_menu_spec.rb' - - 'spec/lib/sidebars/projects/menus/shimo_menu_spec.rb' - 'spec/lib/sidebars/projects/menus/zentao_menu_spec.rb' - 'spec/lib/system_check/app/authorized_keys_permission_check_spec.rb' - 'spec/lib/system_check/app/git_user_default_ssh_config_check_spec.rb' @@ -4617,7 +4615,6 @@ RSpec/FeatureCategory: - 'spec/models/integrations/pumble_spec.rb' - 'spec/models/integrations/pushover_spec.rb' - 'spec/models/integrations/redmine_spec.rb' - - 'spec/models/integrations/shimo_spec.rb' - 'spec/models/integrations/slack_spec.rb' - 'spec/models/integrations/teamcity_spec.rb' - 'spec/models/integrations/unify_circuit_spec.rb' diff --git a/app/assets/images/logos/shimo.svg b/app/assets/images/logos/shimo.svg deleted file mode 100644 index 65bd1cc7167..00000000000 --- a/app/assets/images/logos/shimo.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/app/assets/javascripts/diffs/store/actions.js b/app/assets/javascripts/diffs/store/actions.js index fcaf8e99b2d..3c7a3628a02 100644 --- a/app/assets/javascripts/diffs/store/actions.js +++ b/app/assets/javascripts/diffs/store/actions.js @@ -658,18 +658,18 @@ export const goToFile = ({ state, commit, dispatch, getters }, { path }) => { const { fileHash } = state.treeEntries[path]; commit(types.SET_CURRENT_DIFF_FILE, fileHash); - document.location.hash = fileHash; + + const newUrl = new URL(window.location); + newUrl.hash = fileHash; + historyPushState(newUrl, { skipScrolling: true }); + scrollToElement('.diff-files-holder', { duration: 0 }); if (!getters.isTreePathLoaded(path)) { - dispatch('fetchFileByFile') - .then(() => { - dispatch('scrollToFile', { path }); - }) - .catch(() => { - createAlert({ - message: LOAD_SINGLE_DIFF_FAILED, - }); + dispatch('fetchFileByFile').catch(() => { + createAlert({ + message: LOAD_SINGLE_DIFF_FAILED, }); + }); } } }; diff --git a/app/assets/javascripts/filtered_search/add_extra_tokens_for_merge_requests.js b/app/assets/javascripts/filtered_search/add_extra_tokens_for_merge_requests.js index 74d91734630..698302c5209 100644 --- a/app/assets/javascripts/filtered_search/add_extra_tokens_for_merge_requests.js +++ b/app/assets/javascripts/filtered_search/add_extra_tokens_for_merge_requests.js @@ -8,7 +8,10 @@ import { TOKEN_TYPE_SOURCE_BRANCH, } from '~/vue_shared/components/filtered_search_bar/constants'; -export default (IssuableTokenKeys, disableBranchFilter = false) => { +export default ( + IssuableTokenKeys, + { disableBranchFilter = false, disableEnvironmentFilter = false } = {}, +) => { const reviewerToken = { formattedKey: TOKEN_TITLE_REVIEWER, key: TOKEN_TYPE_REVIEWER, @@ -171,41 +174,43 @@ export default (IssuableTokenKeys, disableBranchFilter = false) => { ); IssuableTokenKeys.conditions.push(...approvedBy.condition); - const environmentToken = { - formattedKey: __('Environment'), - key: 'environment', - type: 'string', - param: '', - symbol: '', - icon: 'cloud-gear', - tag: 'environment', - }; + if (!disableEnvironmentFilter) { + const environmentToken = { + formattedKey: __('Environment'), + key: 'environment', + type: 'string', + param: '', + symbol: '', + icon: 'cloud-gear', + tag: 'environment', + }; - const deployedBeforeToken = { - formattedKey: __('Deployed-before'), - key: 'deployed-before', - type: 'string', - param: '', - symbol: '', - icon: 'clock', - tag: 'deployed_before', - }; + const deployedBeforeToken = { + formattedKey: __('Deployed-before'), + key: 'deployed-before', + type: 'string', + param: '', + symbol: '', + icon: 'clock', + tag: 'deployed_before', + }; - const deployedAfterToken = { - formattedKey: __('Deployed-after'), - key: 'deployed-after', - type: 'string', - param: '', - symbol: '', - icon: 'clock', - tag: 'deployed_after', - }; + const deployedAfterToken = { + formattedKey: __('Deployed-after'), + key: 'deployed-after', + type: 'string', + param: '', + symbol: '', + icon: 'clock', + tag: 'deployed_after', + }; - IssuableTokenKeys.tokenKeys.push(environmentToken, deployedBeforeToken, deployedAfterToken); + IssuableTokenKeys.tokenKeys.push(environmentToken, deployedBeforeToken, deployedAfterToken); - IssuableTokenKeys.tokenKeysWithAlternative.push( - environmentToken, - deployedBeforeToken, - deployedAfterToken, - ); + IssuableTokenKeys.tokenKeysWithAlternative.push( + environmentToken, + deployedBeforeToken, + deployedAfterToken, + ); + } }; diff --git a/app/assets/javascripts/filtered_search/filtered_search_manager.js b/app/assets/javascripts/filtered_search/filtered_search_manager.js index 8ccf7ba92a5..d00c98adc0d 100644 --- a/app/assets/javascripts/filtered_search/filtered_search_manager.js +++ b/app/assets/javascripts/filtered_search/filtered_search_manager.js @@ -1,6 +1,6 @@ import { last } from 'lodash'; import recentSearchesStorageKeys from 'ee_else_ce/filtered_search/recent_searches_storage_keys'; -import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys'; +import { createFilteredSearchTokenKeys } from '~/filtered_search/issuable_filtered_search_token_keys'; import { createAlert } from '~/alert'; import { STATUS_ALL, @@ -40,7 +40,7 @@ export default class FilteredSearchManager { isGroupAncestor = true, isGroupDecendent = false, useDefaultState = false, - filteredSearchTokenKeys = IssuableFilteredSearchTokenKeys, + filteredSearchTokenKeys = createFilteredSearchTokenKeys(), stateFiltersSelector = '.issues-state-filters', placeholder = __('Search or filter results…'), anchor = null, diff --git a/app/assets/javascripts/filtered_search/issuable_filtered_search_token_keys.js b/app/assets/javascripts/filtered_search/issuable_filtered_search_token_keys.js index 8aa99ec52f9..5a785de2e66 100644 --- a/app/assets/javascripts/filtered_search/issuable_filtered_search_token_keys.js +++ b/app/assets/javascripts/filtered_search/issuable_filtered_search_token_keys.js @@ -17,66 +17,75 @@ import { } from '~/vue_shared/components/filtered_search_bar/constants'; import FilteredSearchTokenKeys from './filtered_search_token_keys'; -export const tokenKeys = [ - { - formattedKey: TOKEN_TITLE_AUTHOR, - key: TOKEN_TYPE_AUTHOR, - type: 'string', - param: 'username', - symbol: '@', - icon: 'pencil', - tag: '@author', - }, - { - formattedKey: TOKEN_TITLE_ASSIGNEE, - key: TOKEN_TYPE_ASSIGNEE, - type: 'string', - param: 'username', - symbol: '@', - icon: 'user', - tag: '@assignee', - }, - { - formattedKey: TOKEN_TITLE_MILESTONE, - key: TOKEN_TYPE_MILESTONE, - type: 'string', - param: 'title', - symbol: '%', - icon: 'clock', - tag: '%milestone', - }, - { - formattedKey: TOKEN_TITLE_RELEASE, - key: TOKEN_TYPE_RELEASE, - type: 'string', - param: 'tag', - symbol: '', - icon: 'rocket', - tag: __('tag name'), - }, - { - formattedKey: TOKEN_TITLE_LABEL, - key: TOKEN_TYPE_LABEL, - type: 'array', - param: 'name[]', - symbol: '~', - icon: 'labels', - tag: '~label', - }, -]; +export const createTokenKeys = ({ disableReleaseFilter = false } = {}) => { + const tokenKeys = [ + { + formattedKey: TOKEN_TITLE_AUTHOR, + key: TOKEN_TYPE_AUTHOR, + type: 'string', + param: 'username', + symbol: '@', + icon: 'pencil', + tag: '@author', + }, + { + formattedKey: TOKEN_TITLE_ASSIGNEE, + key: TOKEN_TYPE_ASSIGNEE, + type: 'string', + param: 'username', + symbol: '@', + icon: 'user', + tag: '@assignee', + }, + { + formattedKey: TOKEN_TITLE_MILESTONE, + key: TOKEN_TYPE_MILESTONE, + type: 'string', + param: 'title', + symbol: '%', + icon: 'clock', + tag: '%milestone', + }, + { + formattedKey: TOKEN_TITLE_LABEL, + key: TOKEN_TYPE_LABEL, + type: 'array', + param: 'name[]', + symbol: '~', + icon: 'labels', + tag: '~label', + }, + ]; -if (gon.current_user_id) { - // Appending tokenkeys only logged-in - tokenKeys.push({ - formattedKey: TOKEN_TITLE_MY_REACTION, - key: TOKEN_TYPE_MY_REACTION, - type: 'string', - param: 'emoji', - symbol: '', - icon: 'thumb-up', - tag: 'emoji', - }); -} + if (!disableReleaseFilter) { + tokenKeys.push({ + formattedKey: TOKEN_TITLE_RELEASE, + key: TOKEN_TYPE_RELEASE, + type: 'string', + param: 'tag', + symbol: '', + icon: 'rocket', + tag: __('tag name'), + }); + } + + if (gon.current_user_id) { + // Appending tokenkeys only logged-in + tokenKeys.push({ + formattedKey: TOKEN_TITLE_MY_REACTION, + key: TOKEN_TYPE_MY_REACTION, + type: 'string', + param: 'emoji', + symbol: '', + icon: 'thumb-up', + tag: 'emoji', + }); + } + + return tokenKeys; +}; + +export const tokenKeys = createTokenKeys(); export const alternativeTokenKeys = [ { @@ -186,10 +195,7 @@ export const conditions = flattenDeep( }), ); -const IssuableFilteredSearchTokenKeys = new FilteredSearchTokenKeys( - tokenKeys, - alternativeTokenKeys, - conditions, -); +export const createFilteredSearchTokenKeys = (config = {}) => + new FilteredSearchTokenKeys(createTokenKeys(config), alternativeTokenKeys, conditions); -export default IssuableFilteredSearchTokenKeys; +export default createFilteredSearchTokenKeys(); diff --git a/app/assets/javascripts/lib/utils/common_utils.js b/app/assets/javascripts/lib/utils/common_utils.js index 27da2ac6ce1..b29c234338d 100644 --- a/app/assets/javascripts/lib/utils/common_utils.js +++ b/app/assets/javascripts/lib/utils/common_utils.js @@ -176,25 +176,13 @@ export const contentTop = () => { () => getOuterHeight('.js-diff-files-changed'), ({ desktop }) => { const diffsTabIsActive = window.mrTabs?.currentAction === 'diffs'; - let size; - - if (desktop && diffsTabIsActive) { - size = getOuterHeight( - '.diffs .diff-file .file-title-flex-parent:not([style="display:none"])', - ); - } - - return size; - }, - ({ desktop }) => { - let size; - - if (desktop) { - size = getOuterHeight('.mr-version-controls'); - } - - return size; + const isDiscussionScroll = + desktop && diffsTabIsActive && window.location.hash.startsWith('#note'); + return isDiscussionScroll + ? getOuterHeight('.diffs .diff-file .file-title-flex-parent:not([style="display:none"])') + : 0; }, + ({ desktop }) => (desktop ? getOuterHeight('.mr-version-controls') : 0), ]; return heightCalculators.reduce((totalHeight, calculator) => { @@ -385,8 +373,8 @@ export const buildUrlWithCurrentLocation = (param) => { * * @param {String} param */ -export const historyPushState = (newUrl) => { - window.history.pushState({}, document.title, newUrl); +export const historyPushState = (newUrl, state = {}) => { + window.history.pushState(state, document.title, newUrl); }; /** diff --git a/app/assets/javascripts/lib/utils/datetime/date_format_utility.js b/app/assets/javascripts/lib/utils/datetime/date_format_utility.js index c4b8f95e99f..7eb9c0f4518 100644 --- a/app/assets/javascripts/lib/utils/datetime/date_format_utility.js +++ b/app/assets/javascripts/lib/utils/datetime/date_format_utility.js @@ -377,28 +377,50 @@ export const dateToTimeInputValue = (date) => { export const formatTimeAsSummary = ({ seconds, hours, days, minutes, weeks, months }) => { if (months) { - return sprintf(s__('ValueStreamAnalytics|%{value}M'), { - value: roundToNearestHalf(months), - }); + const value = roundToNearestHalf(months); + return sprintf( + n__('ValueStreamAnalytics|%{value} month', 'ValueStreamAnalytics|%{value} months', value), + { + value, + }, + ); } if (weeks) { - return sprintf(s__('ValueStreamAnalytics|%{value}w'), { - value: roundToNearestHalf(weeks), - }); + const value = roundToNearestHalf(weeks); + return sprintf( + n__('ValueStreamAnalytics|%{value} week', 'ValueStreamAnalytics|%{value} weeks', value), + { + value, + }, + ); } if (days) { - return sprintf(s__('ValueStreamAnalytics|%{value}d'), { - value: roundToNearestHalf(days), - }); + const value = roundToNearestHalf(days); + return sprintf( + n__('ValueStreamAnalytics|%{value} day', 'ValueStreamAnalytics|%{value} days', value), + { + value, + }, + ); } if (hours) { - return sprintf(s__('ValueStreamAnalytics|%{value}h'), { value: hours }); + return sprintf( + n__('ValueStreamAnalytics|%{value} hour', 'ValueStreamAnalytics|%{value} hours', hours), + { + value: hours, + }, + ); } if (minutes) { - return sprintf(s__('ValueStreamAnalytics|%{value}m'), { value: minutes }); + return sprintf( + n__('ValueStreamAnalytics|%{value} minute', 'ValueStreamAnalytics|%{value} minutes', minutes), + { + value: minutes, + }, + ); } if (seconds) { - return unescape(sanitize(s__('ValueStreamAnalytics|<1m'), { ALLOWED_TAGS: [] })); + return unescape(sanitize(s__('ValueStreamAnalytics|<1 minute'), { ALLOWED_TAGS: [] })); } return '-'; }; diff --git a/app/assets/javascripts/merge_request_tabs.js b/app/assets/javascripts/merge_request_tabs.js index 8ea995b8b4e..76be0a40ca0 100644 --- a/app/assets/javascripts/merge_request_tabs.js +++ b/app/assets/javascripts/merge_request_tabs.js @@ -237,7 +237,8 @@ export default class MergeRequestTabs { bindEvents() { $('.merge-request-tabs a[data-toggle="tabvue"]').on('click', this.clickTab); - window.addEventListener('popstate', () => { + window.addEventListener('popstate', (event) => { + if (event?.state?.skipScrolling) return; const action = getActionFromHref(location.href); this.tabShown(action, location.href); diff --git a/app/assets/javascripts/pages/dashboard/issues/index.js b/app/assets/javascripts/pages/dashboard/issues/index.js index 2ca11e96f69..963dc0c57da 100644 --- a/app/assets/javascripts/pages/dashboard/issues/index.js +++ b/app/assets/javascripts/pages/dashboard/issues/index.js @@ -1,10 +1,14 @@ -import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys'; +import { createFilteredSearchTokenKeys } from '~/filtered_search/issuable_filtered_search_token_keys'; import { mountIssuesDashboardApp } from '~/issues/dashboard'; import initManualOrdering from '~/issues/manual_ordering'; import { FILTERED_SEARCH } from '~/filtered_search/constants'; import initFilteredSearch from '~/pages/search/init_filtered_search'; import { initNewResourceDropdown } from '~/vue_shared/components/new_resource_dropdown/init_new_resource_dropdown'; +const IssuableFilteredSearchTokenKeys = createFilteredSearchTokenKeys({ + disableReleaseFilter: true, +}); + initFilteredSearch({ page: FILTERED_SEARCH.ISSUES, filteredSearchTokenKeys: IssuableFilteredSearchTokenKeys, diff --git a/app/assets/javascripts/pages/dashboard/merge_requests/index.js b/app/assets/javascripts/pages/dashboard/merge_requests/index.js index a8c59ea6f3d..774e234a358 100644 --- a/app/assets/javascripts/pages/dashboard/merge_requests/index.js +++ b/app/assets/javascripts/pages/dashboard/merge_requests/index.js @@ -1,12 +1,20 @@ import addExtraTokensForMergeRequests from 'ee_else_ce/filtered_search/add_extra_tokens_for_merge_requests'; -import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys'; +import { createFilteredSearchTokenKeys } from '~/filtered_search/issuable_filtered_search_token_keys'; import { FILTERED_SEARCH } from '~/filtered_search/constants'; import initFilteredSearch from '~/pages/search/init_filtered_search'; import { initNewResourceDropdown } from '~/vue_shared/components/new_resource_dropdown/init_new_resource_dropdown'; import { RESOURCE_TYPE_MERGE_REQUEST } from '~/vue_shared/components/new_resource_dropdown/constants'; import searchUserProjectsWithMergeRequestsEnabled from '~/vue_shared/components/new_resource_dropdown/graphql/search_user_projects_with_merge_requests_enabled.query.graphql'; -addExtraTokensForMergeRequests(IssuableFilteredSearchTokenKeys, true); +const IssuableFilteredSearchTokenKeys = createFilteredSearchTokenKeys({ + disableReleaseFilter: true, +}); + +addExtraTokensForMergeRequests(IssuableFilteredSearchTokenKeys, { + disableBranchFilter: true, + disableReleaseFilter: true, + disableEnvironmentFilter: true, +}); initFilteredSearch({ page: FILTERED_SEARCH.MERGE_REQUESTS, diff --git a/app/assets/stylesheets/page_bundles/merge_request.scss b/app/assets/stylesheets/page_bundles/merge_request.scss index 8dc4401e72c..71a7b3a7af0 100644 --- a/app/assets/stylesheets/page_bundles/merge_request.scss +++ b/app/assets/stylesheets/page_bundles/merge_request.scss @@ -250,6 +250,14 @@ $comparison-empty-state-height: 62px; } } +.diffs.tab-pane { + @include media-breakpoint-up(md) { + // ensure consistent page height when selected file is loading + // https://gitlab.com/gitlab-org/gitlab/-/issues/426250 + min-height: 100vh; + } +} + // Wrap MR tabs/buttons so you don't have to scroll on desktop @include media-breakpoint-down(md) { .merge-request-tabs-container { diff --git a/app/controllers/projects/integrations/shimos_controller.rb b/app/controllers/projects/integrations/shimos_controller.rb deleted file mode 100644 index 6c8313d0805..00000000000 --- a/app/controllers/projects/integrations/shimos_controller.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -module Projects - module Integrations - class ShimosController < Projects::ApplicationController - feature_category :integrations - - before_action :ensure_renderable - - def show; end - - private - - def ensure_renderable - render_404 unless project.has_shimo? && project.shimo_integration&.render? - end - end - end -end diff --git a/app/models/group.rb b/app/models/group.rb index 70831573dfc..90b4067b037 100644 --- a/app/models/group.rb +++ b/app/models/group.rb @@ -434,15 +434,8 @@ class Group < Namespace ) end - def add_member(user, access_level, current_user: nil, expires_at: nil, ldap: false) - Members::Groups::CreatorService.add_member( # rubocop:disable CodeReuse/ServiceClass - self, - user, - access_level, - current_user: current_user, - expires_at: expires_at, - ldap: ldap - ) + def add_member(user, access_level, ...) + Members::Groups::CreatorService.add_member(self, user, access_level, ...) # rubocop:disable CodeReuse/ServiceClass end def add_guest(user, current_user = nil) diff --git a/app/models/integration.rb b/app/models/integration.rb index 7c14c1b1716..2c5731deb58 100644 --- a/app/models/integration.rb +++ b/app/models/integration.rb @@ -25,10 +25,9 @@ class Integration < ApplicationRecord unify_circuit webex_teams youtrack zentao ].freeze - # TODO Shimo is temporary disabled on group and instance-levels. # See: https://gitlab.com/gitlab-org/gitlab/-/issues/345677 PROJECT_SPECIFIC_INTEGRATION_NAMES = %w[ - apple_app_store gitlab_slack_application google_play jenkins shimo + apple_app_store gitlab_slack_application google_play jenkins ].freeze # Fake integrations to help with local development. diff --git a/app/models/integrations/shimo.rb b/app/models/integrations/shimo.rb deleted file mode 100644 index 1d004356469..00000000000 --- a/app/models/integrations/shimo.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: true - -module Integrations - class Shimo < BaseThirdPartyWiki - validates :external_wiki_url, presence: true, public_url: true, if: :activated? - - field :external_wiki_url, - title: -> { s_('Shimo|Shimo Workspace URL') }, - required: true - - def avatar_url - ActionController::Base.helpers.image_path('logos/shimo.svg') - end - - def render? - valid? && activated? - end - - def self.title - s_('Shimo|Shimo') - end - - def self.description - s_('Shimo|Link to a Shimo Workspace from the sidebar.') - end - - def self.to_param - 'shimo' - end - - # support for `test` method - def execute(_data) - response = Gitlab::HTTP.get(properties['external_wiki_url'], verify: true) - response.body if response.code == 200 - rescue StandardError - nil - end - end -end diff --git a/app/models/project.rb b/app/models/project.rb index 7ff32706566..9607a3067d8 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -232,7 +232,6 @@ class Project < ApplicationRecord has_one :pumble_integration, class_name: 'Integrations::Pumble' has_one :pushover_integration, class_name: 'Integrations::Pushover' has_one :redmine_integration, class_name: 'Integrations::Redmine' - has_one :shimo_integration, class_name: 'Integrations::Shimo' has_one :slack_integration, class_name: 'Integrations::Slack' has_one :slack_slash_commands_integration, class_name: 'Integrations::SlackSlashCommands' has_one :squash_tm_integration, class_name: 'Integrations::SquashTm' @@ -541,7 +540,6 @@ class Project < ApplicationRecord delegate :allow_merge_on_skipped_pipeline, :allow_merge_on_skipped_pipeline?, :allow_merge_on_skipped_pipeline= delegate :allow_merge_without_pipeline, :allow_merge_without_pipeline?, :allow_merge_without_pipeline= delegate :has_confluence? - delegate :has_shimo? delegate :show_diff_preview_in_email, :show_diff_preview_in_email=, :show_diff_preview_in_email? delegate :runner_registration_enabled, :runner_registration_enabled=, :runner_registration_enabled? delegate :emails_enabled, :emails_enabled=, :emails_enabled? @@ -1734,7 +1732,7 @@ class Project < ApplicationRecord def disabled_integrations return [] if Rails.env.development? - names = %w[shimo zentao] + names = %w[zentao] # The Slack Slash Commands integration is only available for customers who cannot use the GitLab for Slack app. # The GitLab for Slack app integration is only available when enabled through settings. diff --git a/app/models/users/in_product_marketing_email.rb b/app/models/users/in_product_marketing_email.rb index 4fe1d6fb67d..5362a726ff5 100644 --- a/app/models/users/in_product_marketing_email.rb +++ b/app/models/users/in_product_marketing_email.rb @@ -3,9 +3,6 @@ module Users class InProductMarketingEmail < ApplicationRecord include BulkInsertSafe - include IgnorableColumns - - ignore_column :campaign, remove_with: '16.7', remove_after: '2023-11-15' belongs_to :user diff --git a/app/models/vulnerability.rb b/app/models/vulnerability.rb index 702e7fce567..7c6c6e8c7e4 100644 --- a/app/models/vulnerability.rb +++ b/app/models/vulnerability.rb @@ -5,7 +5,7 @@ class Vulnerability < ApplicationRecord include EachBatch include IgnorableColumns - ignore_column %i[epic_id milestone_id last_edited_at start_date], + ignore_column %i[epic_id milestone_id last_edited_at start_date start_date_sourcing_milestone_id], remove_with: '16.9', remove_after: '2024-01-13' diff --git a/app/views/admin/application_settings/_signin.html.haml b/app/views/admin/application_settings/_signin.html.haml index 0f20864fc68..2b972a2d7f1 100644 --- a/app/views/admin/application_settings/_signin.html.haml +++ b/app/views/admin/application_settings/_signin.html.haml @@ -29,12 +29,12 @@ .form-text.text-muted = _('Maximum time that users are allowed to skip the setup of two-factor authentication (in hours). Set to 0 (zero) to enforce at next sign in.') .form-group - = f.label :admin_mode, _('Admin mode'), class: 'label-bold' + = f.label :admin_mode, _('Admin Mode'), class: 'label-bold' = sprite_icon('lock', css_class: 'gl-icon') - help_text = _('Require additional authentication for administrative tasks.') - help_link = link_to _('Learn more.'), help_page_path('administration/settings/sign_in_restrictions', anchor: 'admin-mode'), target: '_blank', rel: 'noopener noreferrer' = f.gitlab_ui_checkbox_component :admin_mode, - _('Enable admin mode'), + _('Enable Admin Mode'), help_text: '%{help_text} %{help_link}'.html_safe % { help_text: help_text, help_link: help_link } .form-group = f.label :unknown_sign_in, _('Email notification for unknown sign-ins'), class: 'label-bold' diff --git a/app/views/dashboard/merge_requests.html.haml b/app/views/dashboard/merge_requests.html.haml index 658632b70a6..91cec50226b 100644 --- a/app/views/dashboard/merge_requests.html.haml +++ b/app/views/dashboard/merge_requests.html.haml @@ -22,7 +22,11 @@ .top-area = render 'shared/issuable/nav', type: :merge_requests, display_count: !(@no_filters_set || @search_timeout_occurred) -= render 'shared/issuable/search_bar', type: :merge_requests, disable_target_branch: true += render 'shared/issuable/search_bar', + type: :merge_requests, + disable_target_branch: true, + disable_releases: true, + disable_environments: true - if current_user && @no_filters_set = render 'no_filter_selected' diff --git a/app/views/projects/integrations/shimos/show.html.haml b/app/views/projects/integrations/shimos/show.html.haml deleted file mode 100644 index 165e414f75b..00000000000 --- a/app/views/projects/integrations/shimos/show.html.haml +++ /dev/null @@ -1,10 +0,0 @@ -- breadcrumb_title s_('Shimo|Shimo Workspace') -- page_title s_('Shimo|Shimo Workspace') -- add_page_specific_style 'page_bundles/wiki' -= render layout: 'shared/empty_states/wikis_layout', locals: { image_path: 'illustrations/empty-state/empty-wiki-md.svg' } do - %h4 - = s_('Shimo|Shimo Workspace integration is enabled') - %p - = s_("Shimo|You've enabled the Shimo Workspace integration. You can view your wiki directly in Shimo.") - = link_button_to @project.shimo_integration.external_wiki_url, target: '_blank', rel: 'noopener noreferrer', title: s_('Shimo|Go to Shimo Workspace'), variant: :confirm do - = s_('Shimo|Go to Shimo Workspace') diff --git a/app/views/shared/issuable/_search_bar.html.haml b/app/views/shared/issuable/_search_bar.html.haml index 52c8a4d4123..8db7f7345f4 100644 --- a/app/views/shared/issuable/_search_bar.html.haml +++ b/app/views/shared/issuable/_search_bar.html.haml @@ -1,6 +1,8 @@ - type = local_assigns.fetch(:type) - show_sorting_dropdown = local_assigns.fetch(:show_sorting_dropdown, true) - disable_target_branch = local_assigns.fetch(:disable_target_branch, false) +- disable_releases = local_assigns.fetch(:disable_releases, false) +- disable_environments = local_assigns.fetch(:disable_environments, false) - placeholder = local_assigns[:placeholder] || _('Search or filter results…') - block_css_class = type != :productivity_analytics ? 'row-content-block second-block' : '' @@ -111,19 +113,20 @@ %button.btn.btn-link.js-data-value{ type: 'button' } {{title}} = render_if_exists 'shared/issuable/filter_iteration', type: type - #js-dropdown-release.filtered-search-input-dropdown-menu.dropdown-menu - %ul{ data: { dropdown: true } } - %li.filter-dropdown-item{ data: { value: 'None' } } - %button.btn.btn-link{ type: 'button' } - = _('None') - %li.filter-dropdown-item{ data: { value: 'Any' } } - %button.btn.btn-link{ type: 'button' } - = _('Any') - %li.divider.droplab-item-ignore - %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } } - %li.filter-dropdown-item - %button.btn.btn-link.js-data-value{ type: 'button' } - {{title}} + - unless disable_releases + #js-dropdown-release.filtered-search-input-dropdown-menu.dropdown-menu + %ul{ data: { dropdown: true } } + %li.filter-dropdown-item{ data: { value: 'None' } } + %button.btn.btn-link{ type: 'button' } + = _('None') + %li.filter-dropdown-item{ data: { value: 'Any' } } + %button.btn.btn-link{ type: 'button' } + = _('Any') + %li.divider.droplab-item-ignore + %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } } + %li.filter-dropdown-item + %button.btn.btn-link.js-data-value{ type: 'button' } + {{title}} #js-dropdown-label.filtered-search-input-dropdown-menu.dropdown-menu %ul{ data: { dropdown: true } } %li.filter-dropdown-item{ data: { value: 'None' } } @@ -190,11 +193,12 @@ %li.filter-dropdown-item %button.btn.btn-link.js-data-value.monospace {{title}} - #js-dropdown-environment.filtered-search-input-dropdown-menu.dropdown-menu - %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } } - %li.filter-dropdown-item - %button.btn.btn-link.js-data-value{ type: 'button' } - {{title}} + - unless disable_environments + #js-dropdown-environment.filtered-search-input-dropdown-menu.dropdown-menu + %ul.filter-dropdown{ data: { dynamic: true, dropdown: true } } + %li.filter-dropdown-item + %button.btn.btn-link.js-data-value{ type: 'button' } + {{title}} = render_if_exists 'shared/issuable/filter_weight', type: type diff --git a/config/events/i_analytics_dev_ops_adoption.yml b/config/events/i_analytics_dev_ops_adoption.yml new file mode 100644 index 00000000000..a478ad2064e --- /dev/null +++ b/config/events/i_analytics_dev_ops_adoption.yml @@ -0,0 +1,24 @@ +--- +description: User viewed analytics devops adoption +category: InternalEventTracking +action: i_analytics_dev_ops_adoption +label_description: +property_description: +value_description: +extra_properties: +identifiers: +- project +- user +- namespace +product_section: dev +product_stage: manage +product_group: optimize +milestone: "16.4" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/131045 +distributions: +- ee +- ce +tiers: +- premium +- ultimate +- free diff --git a/config/events/i_analytics_dev_ops_score.yml b/config/events/i_analytics_dev_ops_score.yml new file mode 100644 index 00000000000..c8f75cc8870 --- /dev/null +++ b/config/events/i_analytics_dev_ops_score.yml @@ -0,0 +1,24 @@ +--- +description: User visited /admin/dev_ops_reports +category: InternalEventTracking +action: i_analytics_dev_ops_score +label_description: +property_description: +value_description: +extra_properties: +identifiers: +- project +- user +- namespace +product_section: dev +product_stage: manage +product_group: optimize +milestone: "16.4" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/131045 +distributions: +- ee +- ce +tiers: +- premium +- ultimate +- free diff --git a/config/metrics/counts_all/20211028210001_projects_shimo_active.yml b/config/metrics/counts_all/20211028210001_projects_shimo_active.yml index 1deb27f14b1..fdb10ac57f9 100644 --- a/config/metrics/counts_all/20211028210001_projects_shimo_active.yml +++ b/config/metrics/counts_all/20211028210001_projects_shimo_active.yml @@ -5,7 +5,9 @@ product_section: dev product_stage: manage product_group: integrations value_type: number -status: active +status: removed +removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136143 +milestone_removed: '16.7' milestone: "14.5" introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343386 time_frame: all diff --git a/config/metrics/counts_all/20211028210002_groups_shimo_active.yml b/config/metrics/counts_all/20211028210002_groups_shimo_active.yml index efac7bb2ed7..95e2e7bbe92 100644 --- a/config/metrics/counts_all/20211028210002_groups_shimo_active.yml +++ b/config/metrics/counts_all/20211028210002_groups_shimo_active.yml @@ -5,7 +5,9 @@ product_section: dev product_stage: manage product_group: integrations value_type: number -status: active +status: removed +removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136143 +milestone_removed: '16.7' milestone: "14.5" introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343386 time_frame: all diff --git a/config/metrics/counts_all/20211028210003_instances_shimo_active.yml b/config/metrics/counts_all/20211028210003_instances_shimo_active.yml index ad5e6b7beb2..fa31fb0a9fc 100644 --- a/config/metrics/counts_all/20211028210003_instances_shimo_active.yml +++ b/config/metrics/counts_all/20211028210003_instances_shimo_active.yml @@ -5,7 +5,9 @@ product_section: dev product_stage: manage product_group: integrations value_type: number -status: active +status: removed +removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136143 +milestone_removed: '16.7' milestone: "14.5" introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343386 time_frame: all diff --git a/config/metrics/counts_all/20211028210004_projects_inheriting_shimo_active.yml b/config/metrics/counts_all/20211028210004_projects_inheriting_shimo_active.yml index a2fc5f528fb..e247ccacc0a 100644 --- a/config/metrics/counts_all/20211028210004_projects_inheriting_shimo_active.yml +++ b/config/metrics/counts_all/20211028210004_projects_inheriting_shimo_active.yml @@ -5,7 +5,9 @@ product_section: dev product_stage: manage product_group: integrations value_type: number -status: active +status: removed +removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136143 +milestone_removed: '16.7' milestone: "14.5" introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343386 time_frame: all diff --git a/config/metrics/counts_all/20211028210005_groups_inheriting_shimo_active.yml b/config/metrics/counts_all/20211028210005_groups_inheriting_shimo_active.yml index 5be37a39f47..e973871ed22 100644 --- a/config/metrics/counts_all/20211028210005_groups_inheriting_shimo_active.yml +++ b/config/metrics/counts_all/20211028210005_groups_inheriting_shimo_active.yml @@ -5,7 +5,9 @@ product_section: dev product_stage: manage product_group: integrations value_type: number -status: active +status: removed +removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/136143 +milestone_removed: '16.7' milestone: "14.5" introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343386 time_frame: all diff --git a/config/routes/project.rb b/config/routes/project.rb index 947ed6b5413..9016a683404 100644 --- a/config/routes/project.rb +++ b/config/routes/project.rb @@ -437,10 +437,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do end end - namespace :integrations do - resource :shimo, only: [:show] - end - get :planning_hierarchy resources :badges, only: [] do diff --git a/data/deprecations/15-7-deprecate-shimo-integration.yml b/data/deprecations/15-7-deprecate-shimo-integration.yml index f9437a9f44e..0a9d2dc4825 100644 --- a/data/deprecations/15-7-deprecate-shimo-integration.yml +++ b/data/deprecations/15-7-deprecate-shimo-integration.yml @@ -1,6 +1,6 @@ - title: "Shimo integration" # (required) Clearly explain the change, or planned change. For example, "The `confidential` field for a `Note` is deprecated" or "The maximum number of characters in a job name will be limited to 250." announcement_milestone: "15.7" # (required) The milestone when this feature was first announced as deprecated. - removal_milestone: "16.0" # (required) The milestone when this feature is planned to be removed + removal_milestone: "16.7" # (required) The milestone when this feature is planned to be removed breaking_change: true # (required) If this deprecation is a breaking change, set this value to true reporter: arturoherrero # (required) GitLab username of the person reporting the deprecation stage: Manage # (required) String value of the stage that the feature was created in. e.g., Growth @@ -19,6 +19,5 @@ # OTHER OPTIONAL FIELDS # tiers: [Core, Premium, Ultimate] # (optional - may be required in the future) An array of tiers that the feature is available in currently. e.g., [Free, Silver, Gold, Core, Premium, Ultimate] - documentation_url: https://docs.gitlab.com/ee/user/project/integrations/shimo.html # (optional) This is a link to the current documentation page image_url: # (optional) This is a link to a thumbnail image depicting the feature video_url: # (optional) Use the youtube thumbnail URL with the structure of https://img.youtube.com/vi/UNIQUEID/hqdefault.jpg diff --git a/db/docs/integrations.yml b/db/docs/integrations.yml index d0246caaf12..c087d49968a 100644 --- a/db/docs/integrations.yml +++ b/db/docs/integrations.yml @@ -45,7 +45,6 @@ classes: - Integrations::Pumble - Integrations::Pushover - Integrations::Redmine -- Integrations::Shimo - Integrations::Slack - Integrations::SlackSlashCommands - Integrations::SquashTm diff --git a/db/migrate/20231101171848_add_member_role_id_to_saml_providers.rb b/db/migrate/20231101171848_add_member_role_id_to_saml_providers.rb new file mode 100644 index 00000000000..57354e99483 --- /dev/null +++ b/db/migrate/20231101171848_add_member_role_id_to_saml_providers.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +class AddMemberRoleIdToSamlProviders < Gitlab::Database::Migration[2.2] + milestone '16.7' + enable_lock_retries! + + def change + add_column :saml_providers, :member_role_id, :bigint + end +end diff --git a/db/migrate/20231103160022_add_index_to_saml_providers_on_member_role_id.rb b/db/migrate/20231103160022_add_index_to_saml_providers_on_member_role_id.rb new file mode 100644 index 00000000000..4c3ce75bf63 --- /dev/null +++ b/db/migrate/20231103160022_add_index_to_saml_providers_on_member_role_id.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class AddIndexToSamlProvidersOnMemberRoleId < Gitlab::Database::Migration[2.2] + milestone '16.7' + disable_ddl_transaction! + + INDEX_NAME = 'index_saml_providers_on_member_role_id' + + def up + add_concurrent_index :saml_providers, :member_role_id, name: INDEX_NAME + end + + def down + remove_concurrent_index_by_name :saml_providers, INDEX_NAME + end +end diff --git a/db/migrate/20231103160859_add_fk_to_member_role_on_saml_providers.rb b/db/migrate/20231103160859_add_fk_to_member_role_on_saml_providers.rb new file mode 100644 index 00000000000..a456b0c9859 --- /dev/null +++ b/db/migrate/20231103160859_add_fk_to_member_role_on_saml_providers.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class AddFkToMemberRoleOnSamlProviders < Gitlab::Database::Migration[2.2] + milestone '16.7' + disable_ddl_transaction! + + def up + add_concurrent_foreign_key :saml_providers, :member_roles, column: :member_role_id, on_delete: :nullify + end + + def down + with_lock_retries do + remove_foreign_key :saml_providers, column: :member_role_id + end + end +end diff --git a/db/schema_migrations/20231101171848 b/db/schema_migrations/20231101171848 new file mode 100644 index 00000000000..e422613ea78 --- /dev/null +++ b/db/schema_migrations/20231101171848 @@ -0,0 +1 @@ +6d1e481211af71c48c6a0b0f70117b202a5f4e93df19cdc380ead3a5f55a17ff \ No newline at end of file diff --git a/db/schema_migrations/20231103160022 b/db/schema_migrations/20231103160022 new file mode 100644 index 00000000000..793a96188fe --- /dev/null +++ b/db/schema_migrations/20231103160022 @@ -0,0 +1 @@ +87e93fa0d1c2b8b9bdfc252caa114e3e1216689b3e8aeb1117cef49200ac81fa \ No newline at end of file diff --git a/db/schema_migrations/20231103160859 b/db/schema_migrations/20231103160859 new file mode 100644 index 00000000000..e3dacd9b721 --- /dev/null +++ b/db/schema_migrations/20231103160859 @@ -0,0 +1 @@ +df5b53b47bcbc89ca0385753609d1eab95f5f7133ed0269cb80099ff5a36723a \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 875cf3a4a23..9f877b2227b 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -22942,7 +22942,8 @@ CREATE TABLE saml_providers ( enforced_group_managed_accounts boolean DEFAULT false NOT NULL, prohibited_outer_forks boolean DEFAULT true NOT NULL, default_membership_role smallint DEFAULT 10 NOT NULL, - git_check_enforced boolean DEFAULT false NOT NULL + git_check_enforced boolean DEFAULT false NOT NULL, + member_role_id bigint ); CREATE SEQUENCE saml_providers_id_seq @@ -34337,6 +34338,8 @@ CREATE UNIQUE INDEX index_saml_group_links_on_group_id_and_saml_group_name ON sa CREATE INDEX index_saml_providers_on_group_id ON saml_providers USING btree (group_id); +CREATE INDEX index_saml_providers_on_member_role_id ON saml_providers USING btree (member_role_id); + CREATE UNIQUE INDEX index_saved_replies_on_name_text_pattern_ops ON saved_replies USING btree (user_id, name text_pattern_ops); CREATE INDEX index_sbom_component_versions_on_component_id ON sbom_component_versions USING btree (component_id); @@ -37255,6 +37258,9 @@ ALTER TABLE ONLY namespaces ALTER TABLE ONLY project_topics ADD CONSTRAINT fk_34af9ab07a FOREIGN KEY (topic_id) REFERENCES topics(id) ON DELETE CASCADE; +ALTER TABLE ONLY saml_providers + ADD CONSTRAINT fk_351dde3a84 FOREIGN KEY (member_role_id) REFERENCES member_roles(id) ON DELETE SET NULL; + ALTER TABLE ONLY in_product_marketing_emails ADD CONSTRAINT fk_35c9101b63 FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE; diff --git a/doc/.vale/gitlab/spelling-exceptions.txt b/doc/.vale/gitlab/spelling-exceptions.txt index 575dc713b51..f1d95dbd5f0 100644 --- a/doc/.vale/gitlab/spelling-exceptions.txt +++ b/doc/.vale/gitlab/spelling-exceptions.txt @@ -883,7 +883,6 @@ sharded sharding SHAs shfmt -Shimo Shippo Shopify Sidekiq diff --git a/doc/administration/audit_event_streaming/audit_event_types.md b/doc/administration/audit_event_streaming/audit_event_types.md index 1dbf1e19143..2f95bac8ab5 100644 --- a/doc/administration/audit_event_streaming/audit_event_types.md +++ b/doc/administration/audit_event_streaming/audit_event_types.md @@ -403,7 +403,7 @@ Audit event types belong to the following product categories. | [`user_access_locked`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/124169) | Event triggered when user access to the instance is locked| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.2](https://gitlab.com/gitlab-org/modelops/anti-abuse/team-tasks/-/issues/244) | | [`user_access_unlocked`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/124973) | Event triggered when user access to the instance is unlocked| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [16.2](https://gitlab.com/gitlab-org/modelops/anti-abuse/team-tasks/-/issues/244) | | [`user_disable_two_factor`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/89598) | Audit event triggered when user disables two factor authentication| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [15.1](https://gitlab.com/gitlab-org/gitlab/-/issues/238177) | -| [`user_enable_admin_mode`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104754) | Event triggered on enabling admin mode| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [15.7](https://gitlab.com/gitlab-org/gitlab/-/issues/362101) | +| [`user_enable_admin_mode`](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/104754) | Event triggered on enabling Admin Mode| **{check-circle}** Yes | **{check-circle}** Yes | GitLab [15.7](https://gitlab.com/gitlab-org/gitlab/-/issues/362101) | ### Team planning diff --git a/doc/administration/settings/sign_in_restrictions.md b/doc/administration/settings/sign_in_restrictions.md index 942b706b9a3..cb78f4d3415 100644 --- a/doc/administration/settings/sign_in_restrictions.md +++ b/doc/administration/settings/sign_in_restrictions.md @@ -80,7 +80,8 @@ To enable Admin Mode through the UI: 1. Select **Admin Area**. 1. Select **Settings > General**. 1. Expand **Sign-in restrictions**. -1. In the **Admin Mode** section, select the **Require additional authentication for administrative tasks** checkbox. +1. Select **Enable Admin Mode**. +1. Select **Save changes**. ### Turn on Admin Mode for your session diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 516dc713953..25b7bbd7399 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -30377,7 +30377,6 @@ State of a Sentry error. | `PUMBLE_SERVICE` | PumbleService type. | | `PUSHOVER_SERVICE` | PushoverService type. | | `REDMINE_SERVICE` | RedmineService type. | -| `SHIMO_SERVICE` | ShimoService type. | | `SLACK_SERVICE` | SlackService type. | | `SLACK_SLASH_COMMANDS_SERVICE` | SlackSlashCommandsService type. | | `SQUASH_TM_SERVICE` | SquashTmService type. | diff --git a/doc/development/database/batched_background_migrations.md b/doc/development/database/batched_background_migrations.md index a6d827df820..e3c34c4fdff 100644 --- a/doc/development/database/batched_background_migrations.md +++ b/doc/development/database/batched_background_migrations.md @@ -654,6 +654,30 @@ index 4ae3622479f0800c0553959e132143ec9051898e..d556ec7f55adae9d46a56665ce02de78 Create a Draft merge request with your changes and trigger the manual `db:gitlabcom-database-testing` job. +### Establish dependencies + +In some instances, migrations depended on the completion of previously enqueued BBMs. If the BBMs are +still running, the dependent migration fails. For example: introducing an unique index on a large table can depend on +the previously enqueued BBM to handle any duplicate records. + +The following process has been configured to make dependencies more evident while writing a migration. + +- Version of the migration that queued the BBM is stored in _batched_background_migrations_ table and in BBM dictionary file. +- `DEPENDENT_BATCHED_BACKGROUND_MIGRATIONS` constant is added (commented by default) in each migration file. + To establish the dependency, add `queued_migration_version` of the dependent BBMs. If not, remove + the commented line. +- `Migration::UnfinishedDependencies` cop complains if the dependent BBMs are not yet finished. It determines + whether they got finished by looking up the `finalized_by` key in the + [BBM dictionary](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/generators/batched_background_migration/templates/batched_background_migration_dictionary.template). + +#### Notes + +- `BackgroundMigration::DictionaryFile` cop ensures the presence of `finalize_after` and `introduced_by_url` keys in the + BBM dictionary. + - `finalize_after`: Captures the (approximate) date after which the BBM is expected to be finalized. + - `introduced_by_url`: After the `finalize_after` date, an issue is created using the labels and author from `introduced_by_url`. + - As of writing (2023-08-11), issue [#424886](https://gitlab.com/gitlab-org/gitlab/-/issues/424886) is still open. + ## Managing NOTE: @@ -992,6 +1016,7 @@ background migration. :routes, :id, job_interval: DELAY_INTERVAL, + queued_migration_version: '20231113120650', batch_size: BATCH_SIZE, sub_batch_size: SUB_BATCH_SIZE ) @@ -1003,6 +1028,19 @@ background migration. end ``` + ```yaml + # db/docs/batched_background_migrations/backfill_route_namespace_id.yml + --- + migration_job_name: BackfillRouteNamespaceId + description: Copies source_id values from routes to namespace_id + feature_category: source_code_management + introduced_by_url: "https://mr_url" + milestone: 16.6 + queued_migration_version: 20231113120650 + finalize_after: "2023-11-15" + finalized_by: # version of the migration that ensured this bbm + ``` + NOTE: When queuing a batched background migration, you need to restrict the schema to the database where you make the actual changes. @@ -1015,8 +1053,8 @@ background migration. - Continues using the data as before. - Ensures that both existing and new data are migrated. -1. Add a new post-deployment migration - that checks that the batched background migration is completed. For example: +1. Add a new post-deployment migration that checks that the batched background migration is complete. Also update + `finalized_by` attribute in BBM dictionary with the version of this migration. ```ruby class FinalizeBackfillRouteNamespaceId < Gitlab::Database::Migration[2.1] @@ -1041,6 +1079,19 @@ background migration. end ``` + ```yaml + # db/docs/batched_background_migrations/backfill_route_namespace_id.yml + --- + migration_job_name: BackfillRouteNamespaceId + description: Copies source_id values from routes to namespace_id + feature_category: source_code_management + introduced_by_url: "https://mr_url" + milestone: 16.6 + queued_migration_version: 20231113120650 + finalize_after: "2023-11-15" + finalized_by: 20231115120912 + ``` + NOTE: If the batched background migration is not finished, the system will execute the batched background migration inline. If you don't want diff --git a/doc/development/integrations/index.md b/doc/development/integrations/index.md index a2edb2aa1fb..7538a5a0147 100644 --- a/doc/development/integrations/index.md +++ b/doc/development/integrations/index.md @@ -353,6 +353,5 @@ You can refer to these issues for examples of adding new integrations: - [Datadog](https://gitlab.com/gitlab-org/gitlab/-/issues/270123): Metrics collector, similar to the Prometheus integration. - [EWM/RTC](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36662): External issue tracker. -- [Shimo](https://gitlab.com/gitlab-org/gitlab/-/issues/343386): External wiki, similar to the Confluence and External Wiki integrations. - [Webex Teams](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/31543): Chat notifications. - [ZenTao](https://gitlab.com/gitlab-org/gitlab/-/issues/338178): External issue tracker with custom issue views, similar to the Jira integration. diff --git a/doc/development/internal_api/index.md b/doc/development/internal_api/index.md index 1d38ecb9606..4c5646d2fd4 100644 --- a/doc/development/internal_api/index.md +++ b/doc/development/internal_api/index.md @@ -1649,9 +1649,9 @@ curl --verbose --request PATCH "https://gitlab.example.com/api/scim/v2/applicati Returns an empty response with a `204` status code if successful. -### Remove a single SCIM provisioned user +### Block a single SCIM provisioned user -The user is placed in an `ldap_blocked` status and signed out. This means +The user is placed in a `blocked` state and signed out. This means the user cannot sign in or push or pull code. ```plaintext diff --git a/doc/security/hardening_application_recommendations.md b/doc/security/hardening_application_recommendations.md index 40e99495ea7..9c1b47c94aa 100644 --- a/doc/security/hardening_application_recommendations.md +++ b/doc/security/hardening_application_recommendations.md @@ -168,7 +168,7 @@ checkbox next to **Two-factor authentication** (2FA) is selected. The default setting for **Two-factor grace period** is 48 hours. This should be adjusted to a much lower value, such as 8 hours. -Ensure the checkbox next to **Enable admin mode** is selected so that **Admin Mode** is +Ensure the checkbox next to **Enable Admin Mode** is selected so that **Admin Mode** is active. This requires users with Admin access to have to use additional authentication in order to perform administrative tasks, enforcing additional 2FA by the user. diff --git a/doc/update/deprecations.md b/doc/update/deprecations.md index 6431b8a7012..a46a488bb35 100644 --- a/doc/update/deprecations.md +++ b/doc/update/deprecations.md @@ -1328,6 +1328,21 @@ To prepare for GitLab 15.8 and later, you should: