diff options
158 files changed, 1030 insertions, 757 deletions
diff --git a/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql b/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql index 0712ff12c23..00286ec9096 100644 --- a/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql +++ b/app/assets/javascripts/alert_management/graphql/fragments/detail_item.fragment.graphql @@ -10,6 +10,7 @@ fragment AlertDetailItem on AlertManagementAlert { description updatedAt endedAt + hosts details runbook todos { diff --git a/app/assets/javascripts/issue_show/components/incidents/graphql/queries/get_alert.graphql b/app/assets/javascripts/issue_show/components/incidents/graphql/queries/get_alert.graphql index 00ddc80432d..bb637dea033 100644 --- a/app/assets/javascripts/issue_show/components/incidents/graphql/queries/get_alert.graphql +++ b/app/assets/javascripts/issue_show/components/incidents/graphql/queries/get_alert.graphql @@ -13,6 +13,7 @@ query getAlert($iid: String!, $fullPath: ID!) { service description endedAt + hosts details } } diff --git a/app/assets/javascripts/packages/list/coming_soon/helpers.js b/app/assets/javascripts/packages/list/coming_soon/helpers.js deleted file mode 100644 index 5b6a4b3aa87..00000000000 --- a/app/assets/javascripts/packages/list/coming_soon/helpers.js +++ /dev/null @@ -1,55 +0,0 @@ -/** - * Context: - * https://gitlab.com/gitlab-org/gitlab/-/issues/198524 - * https://gitlab.com/gitlab-org/gitlab/-/merge_requests/29491 - * - */ - -/** - * Constants - * - * LABEL_NAMES - an array of labels to filter issues in the GraphQL query - * WORKFLOW_PREFIX - the prefix for workflow labels - * ACCEPTING_CONTRIBUTIONS_TITLE - the accepting contributions label - */ -export const LABEL_NAMES = ['Package::Coming soon']; -const WORKFLOW_PREFIX = 'workflow::'; -const ACCEPTING_CONTRIBUTIONS_TITLE = 'accepting merge requests'; - -const setScoped = (label, scoped) => (label ? { ...label, scoped } : label); - -/** - * Finds workflow:: scoped labels and returns the first or null. - * @param {Object[]} labels Labels from the issue - */ -export const findWorkflowLabel = (labels = []) => - labels.find(l => l.title.toLowerCase().includes(WORKFLOW_PREFIX.toLowerCase())); - -/** - * Determines if an issue is accepting community contributions by checking if - * the "Accepting merge requests" label is present. - * @param {Object[]} labels - */ -export const findAcceptingContributionsLabel = (labels = []) => - labels.find(l => l.title.toLowerCase() === ACCEPTING_CONTRIBUTIONS_TITLE.toLowerCase()); - -/** - * Formats the GraphQL response into the format that the view template expects. - * @param {Object} data GraphQL response - */ -export const toViewModel = data => { - // This just flatterns the issues -> nodes and labels -> nodes hierarchy - // into an array of objects. - const issues = (data.project?.issues?.nodes || []).map(i => ({ - ...i, - labels: (i.labels?.nodes || []).map(node => node), - })); - - return issues.map(x => ({ - ...x, - labels: [ - setScoped(findWorkflowLabel(x.labels), true), - setScoped(findAcceptingContributionsLabel(x.labels), false), - ].filter(Boolean), - })); -}; diff --git a/app/assets/javascripts/packages/list/coming_soon/packages_coming_soon.vue b/app/assets/javascripts/packages/list/coming_soon/packages_coming_soon.vue deleted file mode 100644 index 766402d3619..00000000000 --- a/app/assets/javascripts/packages/list/coming_soon/packages_coming_soon.vue +++ /dev/null @@ -1,172 +0,0 @@ -<script> -import { - GlAlert, - GlEmptyState, - GlIcon, - GlLabel, - GlLink, - GlSkeletonLoader, - GlSprintf, -} from '@gitlab/ui'; -import { ApolloQuery } from 'vue-apollo'; -import Tracking from '~/tracking'; -import { TrackingActions } from '../../shared/constants'; -import { s__ } from '~/locale'; -import comingSoonIssuesQuery from './queries/issues.graphql'; -import { toViewModel, LABEL_NAMES } from './helpers'; - -export default { - name: 'ComingSoon', - components: { - GlAlert, - GlEmptyState, - GlIcon, - GlLabel, - GlLink, - GlSkeletonLoader, - GlSprintf, - ApolloQuery, - }, - mixins: [Tracking.mixin()], - props: { - illustration: { - type: String, - required: true, - }, - projectPath: { - type: String, - required: true, - }, - suggestedContributionsPath: { - type: String, - required: true, - }, - }, - computed: { - variables() { - return { - projectPath: this.projectPath, - labelNames: LABEL_NAMES, - }; - }, - }, - mounted() { - this.track(TrackingActions.COMING_SOON_REQUESTED); - }, - methods: { - onIssueLinkClick(issueIid, label) { - this.track(TrackingActions.COMING_SOON_LIST, { - label, - value: issueIid, - }); - }, - onDocsLinkClick() { - this.track(TrackingActions.COMING_SOON_HELP); - }, - }, - loadingRows: 5, - i18n: { - alertTitle: s__('PackageRegistry|Upcoming package managers'), - alertIntro: s__( - "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar.", - ), - emptyStateTitle: s__('PackageRegistry|No upcoming issues'), - emptyStateDescription: s__('PackageRegistry|There are no upcoming issues to display.'), - }, - comingSoonIssuesQuery, - toViewModel, -}; -</script> - -<template> - <apollo-query - :query="$options.comingSoonIssuesQuery" - :variables="variables" - :update="$options.toViewModel" - > - <template #default="{ result: { data }, isLoading }"> - <div> - <gl-alert :title="$options.i18n.alertTitle" :dismissible="false" variant="tip"> - <gl-sprintf :message="$options.i18n.alertIntro"> - <template #contributionLink="{ content }"> - <gl-link - :href="suggestedContributionsPath" - target="_blank" - @click="onDocsLinkClick" - >{{ content }}</gl-link - > - </template> - </gl-sprintf> - </gl-alert> - </div> - - <div v-if="isLoading" class="gl-display-flex gl-flex-direction-column"> - <gl-skeleton-loader - v-for="index in $options.loadingRows" - :key="index" - :width="1000" - :height="80" - preserve-aspect-ratio="xMinYMax meet" - > - <rect width="700" height="10" x="0" y="16" rx="4" /> - <rect width="60" height="10" x="0" y="45" rx="4" /> - <rect width="60" height="10" x="70" y="45" rx="4" /> - </gl-skeleton-loader> - </div> - - <template v-else-if="data && data.length"> - <div - v-for="issue in data" - :key="issue.iid" - data-testid="issue-row" - class="gl-responsive-table-row gl-flex-direction-column gl-align-items-baseline" - > - <div class="table-section section-100 gl-white-space-normal text-truncate"> - <gl-link - data-testid="issue-title-link" - :href="issue.webUrl" - class="gl-text-gray-900 gl-font-weight-bold" - @click="onIssueLinkClick(issue.iid, issue.title)" - > - {{ issue.title }} - </gl-link> - </div> - - <div class="table-section section-100 gl-white-space-normal mt-md-3"> - <div class="gl-display-flex gl-text-gray-400"> - <gl-icon name="issues" class="gl-mr-2" /> - <gl-link - data-testid="issue-id-link" - :href="issue.webUrl" - class="gl-text-gray-400 gl-mr-5" - @click="onIssueLinkClick(issue.iid, issue.title)" - >#{{ issue.iid }}</gl-link - > - - <div v-if="issue.milestone" class="gl-display-flex gl-align-items-center gl-mr-5"> - <gl-icon name="clock" class="gl-mr-2" /> - <span data-testid="milestone">{{ issue.milestone.title }}</span> - </div> - - <gl-label - v-for="label in issue.labels" - :key="label.title" - class="gl-mr-3" - size="sm" - :background-color="label.color" - :title="label.title" - :scoped="Boolean(label.scoped)" - /> - </div> - </div> - </div> - </template> - - <gl-empty-state v-else :title="$options.i18n.emptyStateTitle" :svg-path="illustration"> - <template #description> - <p>{{ $options.i18n.emptyStateDescription }}</p> - </template> - </gl-empty-state> - </template> - </apollo-query> -</template> diff --git a/app/assets/javascripts/packages/list/coming_soon/queries/issues.graphql b/app/assets/javascripts/packages/list/coming_soon/queries/issues.graphql deleted file mode 100644 index 36c27d9ad70..00000000000 --- a/app/assets/javascripts/packages/list/coming_soon/queries/issues.graphql +++ /dev/null @@ -1,20 +0,0 @@ -query getComingSoonIssues($projectPath: ID!, $labelNames: [String]) { - project(fullPath: $projectPath) { - issues(state: opened, labelName: $labelNames) { - nodes { - iid - title - webUrl - labels { - nodes { - title - color - } - } - milestone { - title - } - } - } - } -} diff --git a/app/assets/javascripts/packages/list/components/packages_list_app.vue b/app/assets/javascripts/packages/list/components/packages_list_app.vue index ad60ee6f379..cbb3bfd35ac 100644 --- a/app/assets/javascripts/packages/list/components/packages_list_app.vue +++ b/app/assets/javascripts/packages/list/components/packages_list_app.vue @@ -9,7 +9,6 @@ import PackageFilter from './packages_filter.vue'; import PackageList from './packages_list.vue'; import PackageSort from './packages_sort.vue'; import { PACKAGE_REGISTRY_TABS, DELETE_PACKAGE_SUCCESS_MESSAGE } from '../constants'; -import PackagesComingSoon from '../coming_soon/packages_coming_soon.vue'; import PackageTitle from './package_title.vue'; export default { @@ -22,14 +21,12 @@ export default { PackageFilter, PackageList, PackageSort, - PackagesComingSoon, PackageTitle, }, computed: { ...mapState({ emptyListIllustration: state => state.config.emptyListIllustration, emptyListHelpUrl: state => state.config.emptyListHelpUrl, - comingSoon: state => state.config.comingSoon, filterQuery: state => state.filterQuery, selectedType: state => state.selectedType, packageHelpUrl: state => state.config.packageHelpUrl, @@ -122,14 +119,6 @@ export default { </template> </package-list> </gl-tab> - - <gl-tab v-if="comingSoon" :title="__('Coming soon')" lazy> - <packages-coming-soon - :illustration="emptyListIllustration" - :project-path="comingSoon.projectPath" - :suggested-contributions-path="comingSoon.suggestedContributions" - /> - </gl-tab> </gl-tabs> </div> </template> diff --git a/app/assets/javascripts/packages/list/stores/mutations.js b/app/assets/javascripts/packages/list/stores/mutations.js index a47ba356c0a..2fe7981b3d9 100644 --- a/app/assets/javascripts/packages/list/stores/mutations.js +++ b/app/assets/javascripts/packages/list/stores/mutations.js @@ -1,19 +1,12 @@ import * as types from './mutation_types'; -import { - parseIntPagination, - normalizeHeaders, - convertObjectPropsToCamelCase, -} from '~/lib/utils/common_utils'; +import { parseIntPagination, normalizeHeaders } from '~/lib/utils/common_utils'; import { GROUP_PAGE_TYPE } from '../constants'; export default { [types.SET_INITIAL_STATE](state, config) { const { comingSoonJson, ...rest } = config; - const comingSoonObj = JSON.parse(comingSoonJson); - state.config = { ...rest, - comingSoon: comingSoonObj && convertObjectPropsToCamelCase(comingSoonObj), isGroupPage: config.pageType === GROUP_PAGE_TYPE, }; }, diff --git a/app/assets/javascripts/packages/shared/constants.js b/app/assets/javascripts/packages/shared/constants.js index e5131db59bf..c481abd8658 100644 --- a/app/assets/javascripts/packages/shared/constants.js +++ b/app/assets/javascripts/packages/shared/constants.js @@ -14,9 +14,6 @@ export const TrackingActions = { REQUEST_DELETE_PACKAGE: 'request_delete_package', CANCEL_DELETE_PACKAGE: 'cancel_delete_package', PULL_PACKAGE: 'pull_package', - COMING_SOON_REQUESTED: 'activate_coming_soon_requested', - COMING_SOON_LIST: 'click_coming_soon_issue_link', - COMING_SOON_HELP: 'click_coming_soon_documentation_link', }; export const TrackingCategories = { diff --git a/app/assets/javascripts/pages/projects/new/index.js b/app/assets/javascripts/pages/projects/new/index.js index 637ed28a758..477a1ab887b 100644 --- a/app/assets/javascripts/pages/projects/new/index.js +++ b/app/assets/javascripts/pages/projects/new/index.js @@ -3,13 +3,14 @@ import initProjectNew from '../../../projects/project_new'; import { __ } from '~/locale'; import { deprecatedCreateFlash as createFlash } from '~/flash'; import Tracking from '~/tracking'; +import { isExperimentEnabled } from '~/lib/utils/experimentation'; document.addEventListener('DOMContentLoaded', () => { initProjectVisibilitySelector(); initProjectNew.bindEvents(); const { category, property } = gon.tracking_data ?? { category: 'projects:new' }; - const hasNewCreateProjectUi = 'newCreateProjectUi' in gon?.features; + const hasNewCreateProjectUi = isExperimentEnabled('newCreateProjectUi'); if (!hasNewCreateProjectUi) { // Setting additional tracking for HAML template diff --git a/app/assets/javascripts/pages/shared/wikis/wikis.js b/app/assets/javascripts/pages/shared/wikis/wikis.js index 41d43812b5d..ab948fd106f 100644 --- a/app/assets/javascripts/pages/shared/wikis/wikis.js +++ b/app/assets/javascripts/pages/shared/wikis/wikis.js @@ -10,7 +10,7 @@ const MARKDOWN_LINK_TEXT = { }; const TRACKING_EVENT_NAME = 'view_wiki_page'; -const TRACKING_CONTEXT_SCHEMA = 'iglu:com.gitlab/wiki_page_context/jsonschema/1-0-0'; +const TRACKING_CONTEXT_SCHEMA = 'iglu:com.gitlab/wiki_page_context/jsonschema/1-0-1'; export default class Wikis { constructor() { diff --git a/app/assets/javascripts/vue_shared/components/alert_details_table.vue b/app/assets/javascripts/vue_shared/components/alert_details_table.vue index a70b8e11a83..3d445626303 100644 --- a/app/assets/javascripts/vue_shared/components/alert_details_table.vue +++ b/app/assets/javascripts/vue_shared/components/alert_details_table.vue @@ -23,6 +23,7 @@ const allowedFields = [ 'endedAt', 'details', 'environment', + 'hosts', ]; const isAllowed = fieldName => allowedFields.includes(fieldName); diff --git a/app/controllers/google_api/authorizations_controller.rb b/app/controllers/google_api/authorizations_controller.rb index 5723ccc14a7..76a1c43dfa3 100644 --- a/app/controllers/google_api/authorizations_controller.rb +++ b/app/controllers/google_api/authorizations_controller.rb @@ -6,6 +6,8 @@ module GoogleApi before_action :validate_session_key! + feature_category :kubernetes_management + def callback token, expires_at = GoogleApi::CloudPlatform::Client .new(nil, callback_google_api_auth_url) diff --git a/app/controllers/graphql_controller.rb b/app/controllers/graphql_controller.rb index b004851587a..5edad410724 100644 --- a/app/controllers/graphql_controller.rb +++ b/app/controllers/graphql_controller.rb @@ -26,6 +26,8 @@ class GraphqlController < ApplicationController # callback execution order here around_action :sessionless_bypass_admin_mode!, if: :sessionless_user? + feature_category :not_owned + def execute result = multiplex? ? execute_multiplex : execute_query @@ -113,6 +115,12 @@ class GraphqlController < ApplicationController # Merging to :metadata will ensure these are logged as top level keys payload[:metadata] ||= {} - payload[:metadata].merge!(graphql: { operation_name: params[:operationName] }) + payload[:metadata].merge!(graphql: logs) + end + + def logs + RequestStore.store[:graphql_logs].to_h + .except(:duration_s, :query_string) + .merge(operation_name: params[:operationName]) end end diff --git a/app/controllers/groups/avatars_controller.rb b/app/controllers/groups/avatars_controller.rb index 8e4dc2bb6e9..1f13be449a9 100644 --- a/app/controllers/groups/avatars_controller.rb +++ b/app/controllers/groups/avatars_controller.rb @@ -5,6 +5,8 @@ class Groups::AvatarsController < Groups::ApplicationController skip_cross_project_access_check :destroy + feature_category :subgroups + def destroy @group.remove_avatar! @group.save diff --git a/app/controllers/groups/boards_controller.rb b/app/controllers/groups/boards_controller.rb index ea7e83a2caf..b971c5783a8 100644 --- a/app/controllers/groups/boards_controller.rb +++ b/app/controllers/groups/boards_controller.rb @@ -12,6 +12,8 @@ class Groups::BoardsController < Groups::ApplicationController push_frontend_feature_flag(:boards_with_swimlanes, group, default_enabled: false) end + feature_category :boards + private def assign_endpoint_vars diff --git a/app/controllers/groups/children_controller.rb b/app/controllers/groups/children_controller.rb index 236a19a8dc4..718914dea35 100644 --- a/app/controllers/groups/children_controller.rb +++ b/app/controllers/groups/children_controller.rb @@ -5,6 +5,8 @@ module Groups before_action :group skip_cross_project_access_check :index + feature_category :subgroups + def index parent = if params[:parent_id].present? GroupFinder.new(current_user).execute(id: params[:parent_id]) diff --git a/app/controllers/groups/deploy_tokens_controller.rb b/app/controllers/groups/deploy_tokens_controller.rb index de951f2cb9f..79152bf2695 100644 --- a/app/controllers/groups/deploy_tokens_controller.rb +++ b/app/controllers/groups/deploy_tokens_controller.rb @@ -3,6 +3,8 @@ class Groups::DeployTokensController < Groups::ApplicationController before_action :authorize_destroy_deploy_token! + feature_category :continuous_delivery + def revoke @token = @group.deploy_tokens.find(params[:id]) @token.revoke! diff --git a/app/controllers/groups/group_links_controller.rb b/app/controllers/groups/group_links_controller.rb index 06c793b5c4c..3b775af9722 100644 --- a/app/controllers/groups/group_links_controller.rb +++ b/app/controllers/groups/group_links_controller.rb @@ -4,6 +4,8 @@ class Groups::GroupLinksController < Groups::ApplicationController before_action :authorize_admin_group! before_action :group_link, only: [:update, :destroy] + feature_category :subgroups + def create shared_with_group = Group.find(params[:shared_with_group_id]) if params[:shared_with_group_id].present? diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb index 63311ab983b..7cf07afd63b 100644 --- a/app/controllers/groups/group_members_controller.rb +++ b/app/controllers/groups/group_members_controller.rb @@ -19,6 +19,8 @@ class Groups::GroupMembersController < Groups::ApplicationController :approve_access_request, :leave, :resend_invite, :override + feature_category :authentication_and_authorization + def index @sort = params[:sort].presence || sort_value_name diff --git a/app/controllers/groups/imports_controller.rb b/app/controllers/groups/imports_controller.rb index b611685f9bc..7cf39e378db 100644 --- a/app/controllers/groups/imports_controller.rb +++ b/app/controllers/groups/imports_controller.rb @@ -3,6 +3,8 @@ class Groups::ImportsController < Groups::ApplicationController include ContinueParams + feature_category :importers + def show if @group.import_state.nil? || @group.import_state.finished? if continue_params[:to] diff --git a/app/controllers/groups/labels_controller.rb b/app/controllers/groups/labels_controller.rb index 97d9f8fcecd..34856f8d84e 100644 --- a/app/controllers/groups/labels_controller.rb +++ b/app/controllers/groups/labels_controller.rb @@ -10,6 +10,8 @@ class Groups::LabelsController < Groups::ApplicationController respond_to :html + feature_category :issue_tracking + def index respond_to do |format| format.html do diff --git a/app/controllers/groups/milestones_controller.rb b/app/controllers/groups/milestones_controller.rb index 3f2894d378b..173a24ceb74 100644 --- a/app/controllers/groups/milestones_controller.rb +++ b/app/controllers/groups/milestones_controller.rb @@ -9,6 +9,8 @@ class Groups::MilestonesController < Groups::ApplicationController push_frontend_feature_flag(:burnup_charts, @group) end + feature_category :issue_tracking + def index respond_to do |format| format.html do diff --git a/app/controllers/groups/packages_controller.rb b/app/controllers/groups/packages_controller.rb index 600acc72e67..47f1816cc4c 100644 --- a/app/controllers/groups/packages_controller.rb +++ b/app/controllers/groups/packages_controller.rb @@ -4,6 +4,8 @@ module Groups class PackagesController < Groups::ApplicationController before_action :verify_packages_enabled! + feature_category :package_registry + private def verify_packages_enabled! diff --git a/app/controllers/groups/registry/repositories_controller.rb b/app/controllers/groups/registry/repositories_controller.rb index 87a62a8f9b0..d914e0bffc6 100644 --- a/app/controllers/groups/registry/repositories_controller.rb +++ b/app/controllers/groups/registry/repositories_controller.rb @@ -7,6 +7,8 @@ module Groups before_action :verify_container_registry_enabled! before_action :authorize_read_container_image! + feature_category :package_registry + def index respond_to do |format| format.html diff --git a/app/controllers/groups/releases_controller.rb b/app/controllers/groups/releases_controller.rb index 500c57a6f3e..6a42f30b847 100644 --- a/app/controllers/groups/releases_controller.rb +++ b/app/controllers/groups/releases_controller.rb @@ -2,6 +2,8 @@ module Groups class ReleasesController < Groups::ApplicationController + feature_category :release_evidence + def index respond_to do |format| format.json do diff --git a/app/controllers/groups/runners_controller.rb b/app/controllers/groups/runners_controller.rb index edebffe2912..dbfd31ebcad 100644 --- a/app/controllers/groups/runners_controller.rb +++ b/app/controllers/groups/runners_controller.rb @@ -7,6 +7,8 @@ class Groups::RunnersController < Groups::ApplicationController before_action :runner, only: [:edit, :update, :destroy, :pause, :resume, :show] + feature_category :continuous_integration + def show render 'shared/runners/show' end diff --git a/app/controllers/groups/settings/ci_cd_controller.rb b/app/controllers/groups/settings/ci_cd_controller.rb index ceee049d824..0c72c8a037b 100644 --- a/app/controllers/groups/settings/ci_cd_controller.rb +++ b/app/controllers/groups/settings/ci_cd_controller.rb @@ -13,6 +13,8 @@ module Groups end before_action :define_variables, only: [:show] + feature_category :continuous_integration + NUMBER_OF_RUNNERS_PER_PAGE = 4 def show diff --git a/app/controllers/groups/settings/integrations_controller.rb b/app/controllers/groups/settings/integrations_controller.rb index e8551a7f270..b089cfdf341 100644 --- a/app/controllers/groups/settings/integrations_controller.rb +++ b/app/controllers/groups/settings/integrations_controller.rb @@ -7,6 +7,8 @@ module Groups before_action :authorize_admin_group! + feature_category :integrations + def index @integrations = Service.find_or_initialize_all(Service.for_group(group)).sort_by(&:title) end diff --git a/app/controllers/groups/settings/repository_controller.rb b/app/controllers/groups/settings/repository_controller.rb index e2fbdc39692..ccc1fa12458 100644 --- a/app/controllers/groups/settings/repository_controller.rb +++ b/app/controllers/groups/settings/repository_controller.rb @@ -10,6 +10,8 @@ module Groups push_frontend_feature_flag(:ajax_new_deploy_token, @group) end + feature_category :continuous_delivery + def create_deploy_token result = Groups::DeployTokens::CreateService.new(@group, current_user, deploy_token_params).execute @new_deploy_token = result[:deploy_token] diff --git a/app/controllers/groups/shared_projects_controller.rb b/app/controllers/groups/shared_projects_controller.rb index 30b7bfc70ae..90ec64d4768 100644 --- a/app/controllers/groups/shared_projects_controller.rb +++ b/app/controllers/groups/shared_projects_controller.rb @@ -6,6 +6,8 @@ module Groups before_action :group skip_cross_project_access_check :index + feature_category :subgroups + def index shared_projects = GroupProjectsFinder.new( group: group, diff --git a/app/controllers/groups/uploads_controller.rb b/app/controllers/groups/uploads_controller.rb index 3ae7e36c740..49249f87d31 100644 --- a/app/controllers/groups/uploads_controller.rb +++ b/app/controllers/groups/uploads_controller.rb @@ -9,6 +9,8 @@ class Groups::UploadsController < Groups::ApplicationController before_action :authorize_upload_file!, only: [:create, :authorize] before_action :verify_workhorse_api!, only: [:authorize] + feature_category :subgroups + private def upload_model_class diff --git a/app/controllers/groups/variables_controller.rb b/app/controllers/groups/variables_controller.rb index fb639f6e472..51670325ce3 100644 --- a/app/controllers/groups/variables_controller.rb +++ b/app/controllers/groups/variables_controller.rb @@ -6,6 +6,8 @@ module Groups skip_cross_project_access_check :show, :update + feature_category :continuous_integration + def show respond_to do |format| format.json do diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb index 2d6f5d0377a..833350d4a68 100644 --- a/app/controllers/groups_controller.rb +++ b/app/controllers/groups_controller.rb @@ -46,6 +46,17 @@ class GroupsController < Groups::ApplicationController layout :determine_layout + feature_category :subgroups, [ + :index, :new, :create, :show, :edit, :update, + :destroy, :details, :transfer + ] + + feature_category :audit_events, [:activity] + feature_category :issue_tracking, [:issues, :issues_calendar, :preview_markdown] + feature_category :code_review, [:merge_requests] + feature_category :projects, [:projects] + feature_category :importers, [:export, :download_export] + def index redirect_to(current_user ? dashboard_groups_path : explore_groups_path) end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 848625ff6b5..88a4a276750 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -37,7 +37,7 @@ class ProjectsController < Projects::ApplicationController # Experiments before_action only: [:new, :create] do frontend_experimentation_tracking_data(:new_create_project_ui, 'click_tab') - push_frontend_feature_flag(:new_create_project_ui) if experiment_enabled?(:new_create_project_ui) + push_frontend_experiment(:new_create_project_ui) end before_action only: [:edit] do diff --git a/app/graphql/mutations/notes/update/image_diff_note.rb b/app/graphql/mutations/notes/update/image_diff_note.rb index 7aad3af1e04..31b8828001b 100644 --- a/app/graphql/mutations/notes/update/image_diff_note.rb +++ b/app/graphql/mutations/notes/update/image_diff_note.rb @@ -28,7 +28,7 @@ module Mutations 'body or position arguments are required' end - super(args) + super(**args) end private diff --git a/app/helpers/packages_helper.rb b/app/helpers/packages_helper.rb index 0a296b4e6ba..a3a899dbe1a 100644 --- a/app/helpers/packages_helper.rb +++ b/app/helpers/packages_helper.rb @@ -34,26 +34,12 @@ module PackagesHelper expose_url(api_v4_group___packages_composer_packages_path(id: group_id, format: '.json')) end - def packages_coming_soon_enabled?(resource) - ::Feature.enabled?(:packages_coming_soon, resource) && ::Gitlab.dev_env_or_com? - end - - def packages_coming_soon_data(resource) - return unless packages_coming_soon_enabled?(resource) - - { - project_path: ::Gitlab.com? ? 'gitlab-org/gitlab' : 'gitlab-org/gitlab-test', - suggested_contributions: help_page_path('user/packages/index', anchor: 'suggested-contributions') - } - end - def packages_list_data(type, resource) { resource_id: resource.id, page_type: type, empty_list_help_url: help_page_path('user/packages/package_registry/index'), empty_list_illustration: image_path('illustrations/no-packages.svg'), - coming_soon_json: packages_coming_soon_data(resource).to_json, package_help_url: help_page_path('user/packages/index') } end diff --git a/app/helpers/wiki_helper.rb b/app/helpers/wiki_helper.rb index 8c756b9370b..786081ca815 100644 --- a/app/helpers/wiki_helper.rb +++ b/app/helpers/wiki_helper.rb @@ -142,7 +142,8 @@ module WikiHelper 'wiki-format' => page.format, 'wiki-title-size' => page.title.bytesize, 'wiki-content-size' => page.raw_content.bytesize, - 'wiki-directory-nest-level' => page.path.scan('/').count + 'wiki-directory-nest-level' => page.path.scan('/').count, + 'wiki-container-type' => page.wiki.container.class.name } end diff --git a/app/models/alert_management/alert.rb b/app/models/alert_management/alert.rb index fea7e962783..b92bcec4988 100644 --- a/app/models/alert_management/alert.rb +++ b/app/models/alert_management/alert.rb @@ -21,13 +21,6 @@ module AlertManagement ignored: 3 }.freeze - STATUS_EVENTS = { - triggered: :trigger, - acknowledged: :acknowledge, - resolved: :resolve, - ignored: :ignore - }.freeze - OPEN_STATUSES = [ :triggered, :acknowledged @@ -190,6 +183,15 @@ module AlertManagement reference.to_i > 0 && reference.to_i <= Gitlab::Database::MAX_INT_VALUE end + def status_event_for(status) + self.class.state_machines[:status].events.transitions_for(self, to: status.to_s.to_sym).first&.event + end + + def change_status_to(new_status) + event = status_event_for(new_status) + event && fire_status_event(event) + end + def prometheus? monitoring_tool == Gitlab::AlertManagement::Payload::MONITORING_TOOLS[:prometheus] end diff --git a/app/models/design_management/design_at_version.rb b/app/models/design_management/design_at_version.rb index b4cafb93c2c..0cf653ce696 100644 --- a/app/models/design_management/design_at_version.rb +++ b/app/models/design_management/design_at_version.rb @@ -22,7 +22,7 @@ module DesignManagement end def self.instantiate(attrs) - new(attrs).tap { |obj| obj.validate! } + new(**attrs).tap { |obj| obj.validate! } end # The ID, needed by GraphQL types and as part of the Lazy-fetch diff --git a/app/models/project.rb b/app/models/project.rb index 8eac170746c..8e0e6c5932d 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -367,6 +367,7 @@ class Project < ApplicationRecord allow_destroy: true, reject_if: ->(attrs) { attrs[:id].blank? && attrs[:url].blank? } + accepts_nested_attributes_for :tracing_setting, update_only: true, allow_destroy: true accepts_nested_attributes_for :incident_management_setting, update_only: true accepts_nested_attributes_for :error_tracking_setting, update_only: true accepts_nested_attributes_for :metrics_setting, update_only: true, allow_destroy: true diff --git a/app/models/user.rb b/app/models/user.rb index 5bbdb2b2e9a..5ef1498bd85 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -304,13 +304,18 @@ class User < ApplicationRecord transition deactivated: :active transition blocked: :active transition ldap_blocked: :active + transition blocked_pending_approval: :active + end + + event :block_pending_approval do + transition active: :blocked_pending_approval end event :deactivate do transition active: :deactivated end - state :blocked, :ldap_blocked do + state :blocked, :ldap_blocked, :blocked_pending_approval do def blocked? true end @@ -333,7 +338,7 @@ class User < ApplicationRecord # Scopes scope :admins, -> { where(admin: true) } - scope :blocked, -> { with_states(:blocked, :ldap_blocked) } + scope :blocked, -> { with_states(:blocked, :ldap_blocked, :blocked_pending_approval) } scope :external, -> { where(external: true) } scope :confirmed, -> { where.not(confirmed_at: nil) } scope :active, -> { with_state(:active).non_internal } @@ -378,7 +383,9 @@ class User < ApplicationRecord # The messages for these keys are defined in `devise.en.yml` def inactive_message - if blocked? + if blocked_pending_approval? + :blocked_pending_approval + elsif blocked? :blocked elsif internal? :forbidden diff --git a/app/services/alert_management/alerts/update_service.rb b/app/services/alert_management/alerts/update_service.rb index 18d615aa7e7..a7c8af908fe 100644 --- a/app/services/alert_management/alerts/update_service.rb +++ b/app/services/alert_management/alerts/update_service.rb @@ -112,7 +112,7 @@ module AlertManagement def filter_status return unless params[:status] - status_event = AlertManagement::Alert::STATUS_EVENTS[status_key] + status_event = alert.status_event_for(status_key) unless status_event param_errors << _('Invalid status') diff --git a/app/services/ci/update_build_state_service.rb b/app/services/ci/update_build_state_service.rb index cc8e2060888..cbb43c3c59e 100644 --- a/app/services/ci/update_build_state_service.rb +++ b/app/services/ci/update_build_state_service.rb @@ -6,6 +6,7 @@ module Ci include ::Gitlab::ExclusiveLeaseHelpers Result = Struct.new(:status, :backoff, keyword_init: true) + InvalidTraceError = Class.new(StandardError) ACCEPT_TIMEOUT = 5.minutes.freeze @@ -76,8 +77,20 @@ module Ci metrics.increment_trace_operation(operation: :finalized) end - unless ::Gitlab::Ci::Trace::Checksum.new(build).valid? - metrics.increment_trace_operation(operation: :invalid) + ::Gitlab::Ci::Trace::Checksum.new(build).then do |checksum| + unless checksum.valid? + metrics.increment_trace_operation(operation: :invalid) + + next unless log_invalid_chunks? + + ::Gitlab::ErrorTracking.log_exception(InvalidTraceError.new, + project_path: build.project.full_path, + build_id: build.id, + state_crc32: checksum.state_crc32, + chunks_crc32: checksum.chunks_crc32, + chunks_count: checksum.chunks_count + ) + end end end @@ -182,5 +195,9 @@ module Ci def chunks_migration_enabled? ::Gitlab::Ci::Features.accept_trace?(build.project) end + + def log_invalid_chunks? + ::Gitlab::Ci::Features.log_invalid_trace_chunks?(build.project) + end end end diff --git a/app/services/projects/operations/update_service.rb b/app/services/projects/operations/update_service.rb index 7af489c3751..7dfe7fffa1b 100644 --- a/app/services/projects/operations/update_service.rb +++ b/app/services/projects/operations/update_service.rb @@ -18,6 +18,7 @@ module Projects .merge(grafana_integration_params) .merge(prometheus_integration_params) .merge(incident_management_setting_params) + .merge(tracing_setting_params) end def alerting_setting_params @@ -121,6 +122,15 @@ module Projects { incident_management_setting_attributes: attrs } end + + def tracing_setting_params + attr = params[:tracing_setting_attributes] + return {} unless attr + + destroy = attr[:external_url].blank? + + { tracing_setting_attributes: attr.merge(_destroy: destroy) } + end end end end diff --git a/changelogs/unreleased/feat-jcunha-adds-terraform-ci-latest-template.yml b/changelogs/unreleased/feat-jcunha-adds-terraform-ci-latest-template.yml new file mode 100644 index 00000000000..563b7d65650 --- /dev/null +++ b/changelogs/unreleased/feat-jcunha-adds-terraform-ci-latest-template.yml @@ -0,0 +1,6 @@ +--- +title: Adds a Terraform.latest.gitlab-ci.yml to support quick development of Terraform + related features +merge_request: 43802 +author: +type: added diff --git a/changelogs/unreleased/issue_237977.yml b/changelogs/unreleased/issue_237977.yml new file mode 100644 index 00000000000..97ba5a982a8 --- /dev/null +++ b/changelogs/unreleased/issue_237977.yml @@ -0,0 +1,5 @@ +--- +title: Populate issues blocking_issues_count +merge_request: 42277 +author: +type: other diff --git a/changelogs/unreleased/mwaw-230438-log-usage-data-failed-queries.yml b/changelogs/unreleased/mwaw-230438-log-usage-data-failed-queries.yml new file mode 100644 index 00000000000..72033578f4d --- /dev/null +++ b/changelogs/unreleased/mwaw-230438-log-usage-data-failed-queries.yml @@ -0,0 +1,5 @@ +--- +title: Log failed BatchCount queries +merge_request: 41552 +author: +type: added diff --git a/changelogs/unreleased/tr-add-detail-fields-to-table.yml b/changelogs/unreleased/tr-add-detail-fields-to-table.yml new file mode 100644 index 00000000000..f4992b7a0f6 --- /dev/null +++ b/changelogs/unreleased/tr-add-detail-fields-to-table.yml @@ -0,0 +1,5 @@ +--- +title: Add hosts field to alert detail table +merge_request: 43087 +author: +type: changed diff --git a/config/feature_flags/development/ci_artifacts_exclude.yml b/config/feature_flags/development/ci_artifacts_exclude.yml index 6e9d27efe42..86398f085d8 100644 --- a/config/feature_flags/development/ci_artifacts_exclude.yml +++ b/config/feature_flags/development/ci_artifacts_exclude.yml @@ -1,7 +1,7 @@ --- name: ci_artifacts_exclude -introduced_by_url: -rollout_issue_url: -group: +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/30708 +rollout_issue_url: +group: group::continuous integration type: development default_enabled: true diff --git a/config/feature_flags/development/ci_build_metadata_config.yml b/config/feature_flags/development/ci_build_metadata_config.yml index add7c963272..176abbfd387 100644 --- a/config/feature_flags/development/ci_build_metadata_config.yml +++ b/config/feature_flags/development/ci_build_metadata_config.yml @@ -1,7 +1,7 @@ --- name: ci_build_metadata_config -introduced_by_url: -rollout_issue_url: -group: +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/7238 +rollout_issue_url: +group: group::continuous integration type: development default_enabled: false diff --git a/config/feature_flags/development/ci_enable_live_trace.yml b/config/feature_flags/development/ci_enable_live_trace.yml index e9fd998f6df..7ae59946330 100644 --- a/config/feature_flags/development/ci_enable_live_trace.yml +++ b/config/feature_flags/development/ci_enable_live_trace.yml @@ -1,7 +1,7 @@ --- name: ci_enable_live_trace -introduced_by_url: -rollout_issue_url: -group: +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/5255 +rollout_issue_url: +group: group::continuous integration type: development default_enabled: false diff --git a/config/feature_flags/development/ci_pipeline_latest.yml b/config/feature_flags/development/ci_pipeline_latest.yml index 661d0714e53..87b064043a3 100644 --- a/config/feature_flags/development/ci_pipeline_latest.yml +++ b/config/feature_flags/development/ci_pipeline_latest.yml @@ -1,7 +1,7 @@ --- name: ci_pipeline_latest -introduced_by_url: -rollout_issue_url: -group: +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/34160 +rollout_issue_url: +group: group::continuous integration type: development default_enabled: true diff --git a/config/feature_flags/development/packages_coming_soon.yml b/config/feature_flags/development/packages_coming_soon.yml deleted file mode 100644 index 0a0d1f989dc..00000000000 --- a/config/feature_flags/development/packages_coming_soon.yml +++ /dev/null @@ -1,7 +0,0 @@ ---- -name: packages_coming_soon -introduced_by_url: -rollout_issue_url: -group: -type: development -default_enabled: false diff --git a/config/feature_flags/ops/ci_trace_log_invalid_chunks.yml b/config/feature_flags/ops/ci_trace_log_invalid_chunks.yml new file mode 100644 index 00000000000..f5e8bbae258 --- /dev/null +++ b/config/feature_flags/ops/ci_trace_log_invalid_chunks.yml @@ -0,0 +1,7 @@ +--- +name: ci_trace_log_invalid_chunks +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/44409 +rollout_issue_url: +type: ops +group: group::continuous integration +default_enabled: false diff --git a/config/locales/devise.en.yml b/config/locales/devise.en.yml index 14580e2bb3b..5e5fc5f9af7 100644 --- a/config/locales/devise.en.yml +++ b/config/locales/devise.en.yml @@ -18,6 +18,7 @@ en: unconfirmed: "You have to confirm your email address before continuing. Please check your email for the link we sent you, or click 'Resend confirmation email'." blocked: "Your account has been blocked. Please contact your GitLab administrator if you think this is an error." forbidden: "Your account does not have the required permission to login. Please contact your GitLab administrator if you think this is an error." + blocked_pending_approval: "Your account is pending approval from your GitLab administrator and hence blocked. Please contact your GitLab administrator if you think this is an error." mailer: confirmation_instructions: subject: "Confirmation instructions" diff --git a/db/migrate/20200226100624_requirements_add_project_fk.rb b/db/migrate/20200226100624_requirements_add_project_fk.rb index 7c133e820f3..b44ce1d34ec 100644 --- a/db/migrate/20200226100624_requirements_add_project_fk.rb +++ b/db/migrate/20200226100624_requirements_add_project_fk.rb @@ -7,7 +7,7 @@ class RequirementsAddProjectFk < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key(:requirements, :projects, column: :project_id, on_delete: :cascade) # rubocop: disable Migration/AddConcurrentForeignKey + add_foreign_key(:requirements, :projects, column: :project_id, on_delete: :cascade) end end diff --git a/db/migrate/20200226100634_requirements_add_author_fk.rb b/db/migrate/20200226100634_requirements_add_author_fk.rb index 8e1a726bb76..b458657827f 100644 --- a/db/migrate/20200226100634_requirements_add_author_fk.rb +++ b/db/migrate/20200226100634_requirements_add_author_fk.rb @@ -7,7 +7,7 @@ class RequirementsAddAuthorFk < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key(:requirements, :users, column: :author_id, on_delete: :nullify) # rubocop: disable Migration/AddConcurrentForeignKey + add_foreign_key(:requirements, :users, column: :author_id, on_delete: :nullify) end end diff --git a/db/migrate/20200304121828_add_ci_sources_project_pipeline_foreign_key.rb b/db/migrate/20200304121828_add_ci_sources_project_pipeline_foreign_key.rb index d5b0af41d4a..ed244a7d308 100644 --- a/db/migrate/20200304121828_add_ci_sources_project_pipeline_foreign_key.rb +++ b/db/migrate/20200304121828_add_ci_sources_project_pipeline_foreign_key.rb @@ -7,7 +7,7 @@ class AddCiSourcesProjectPipelineForeignKey < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :ci_sources_projects, :ci_pipelines, column: :pipeline_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :ci_sources_projects, :ci_pipelines, column: :pipeline_id, on_delete: :cascade end end diff --git a/db/migrate/20200304121844_add_ci_sources_project_source_project_foreign_key.rb b/db/migrate/20200304121844_add_ci_sources_project_source_project_foreign_key.rb index 4f679bef85e..56ae2106644 100644 --- a/db/migrate/20200304121844_add_ci_sources_project_source_project_foreign_key.rb +++ b/db/migrate/20200304121844_add_ci_sources_project_source_project_foreign_key.rb @@ -7,7 +7,7 @@ class AddCiSourcesProjectSourceProjectForeignKey < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :ci_sources_projects, :projects, column: :source_project_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :ci_sources_projects, :projects, column: :source_project_id, on_delete: :cascade end end diff --git a/db/migrate/20200316173312_add_vulnerability_export_project_foreign_key.rb b/db/migrate/20200316173312_add_vulnerability_export_project_foreign_key.rb index 23837f559d2..84b96c64658 100644 --- a/db/migrate/20200316173312_add_vulnerability_export_project_foreign_key.rb +++ b/db/migrate/20200316173312_add_vulnerability_export_project_foreign_key.rb @@ -7,7 +7,7 @@ class AddVulnerabilityExportProjectForeignKey < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :vulnerability_exports, :projects, column: :project_id, on_delete: :cascade, index: false # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :vulnerability_exports, :projects, column: :project_id, on_delete: :cascade, index: false end end diff --git a/db/migrate/20200317142110_add_vulnerability_export_user_foreign_key.rb b/db/migrate/20200317142110_add_vulnerability_export_user_foreign_key.rb index 032577f2f2a..c4f685701b9 100644 --- a/db/migrate/20200317142110_add_vulnerability_export_user_foreign_key.rb +++ b/db/migrate/20200317142110_add_vulnerability_export_user_foreign_key.rb @@ -7,7 +7,7 @@ class AddVulnerabilityExportUserForeignKey < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :vulnerability_exports, :users, column: :author_id, on_delete: :cascade, index: false # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :vulnerability_exports, :users, column: :author_id, on_delete: :cascade, index: false end end diff --git a/db/migrate/20200326124443_add_projects_fk_to_jira_imports_table.rb b/db/migrate/20200326124443_add_projects_fk_to_jira_imports_table.rb index 6410f530b30..654d35619e3 100644 --- a/db/migrate/20200326124443_add_projects_fk_to_jira_imports_table.rb +++ b/db/migrate/20200326124443_add_projects_fk_to_jira_imports_table.rb @@ -7,7 +7,7 @@ class AddProjectsFkToJiraImportsTable < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :jira_imports, :projects, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :jira_imports, :projects, on_delete: :cascade end end diff --git a/db/migrate/20200326134443_add_users_fk_to_jira_imports_table.rb b/db/migrate/20200326134443_add_users_fk_to_jira_imports_table.rb index 0956a8e814b..429f72628e2 100644 --- a/db/migrate/20200326134443_add_users_fk_to_jira_imports_table.rb +++ b/db/migrate/20200326134443_add_users_fk_to_jira_imports_table.rb @@ -7,7 +7,7 @@ class AddUsersFkToJiraImportsTable < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :jira_imports, :users, on_delete: :nullify # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :jira_imports, :users, on_delete: :nullify end end diff --git a/db/migrate/20200326144443_add_labels_fk_to_jira_imports_table.rb b/db/migrate/20200326144443_add_labels_fk_to_jira_imports_table.rb index ead04100a96..9bcadcb61c1 100644 --- a/db/migrate/20200326144443_add_labels_fk_to_jira_imports_table.rb +++ b/db/migrate/20200326144443_add_labels_fk_to_jira_imports_table.rb @@ -7,7 +7,7 @@ class AddLabelsFkToJiraImportsTable < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :jira_imports, :labels, on_delete: :nullify # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :jira_imports, :labels, on_delete: :nullify end end diff --git a/db/migrate/20200416120354_add_locked_by_user_id_foreign_key_to_terraform_state.rb b/db/migrate/20200416120354_add_locked_by_user_id_foreign_key_to_terraform_state.rb index ecee028351a..144291d94be 100644 --- a/db/migrate/20200416120354_add_locked_by_user_id_foreign_key_to_terraform_state.rb +++ b/db/migrate/20200416120354_add_locked_by_user_id_foreign_key_to_terraform_state.rb @@ -7,7 +7,7 @@ class AddLockedByUserIdForeignKeyToTerraformState < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :terraform_states, :users, column: :locked_by_user_id # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :terraform_states, :users, column: :locked_by_user_id end end diff --git a/db/migrate/20200423075720_add_user_id_foreign_key_to_resource_state_events.rb b/db/migrate/20200423075720_add_user_id_foreign_key_to_resource_state_events.rb index 702347e5d43..91a6dbe4214 100644 --- a/db/migrate/20200423075720_add_user_id_foreign_key_to_resource_state_events.rb +++ b/db/migrate/20200423075720_add_user_id_foreign_key_to_resource_state_events.rb @@ -7,7 +7,7 @@ class AddUserIdForeignKeyToResourceStateEvents < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :resource_state_events, :users, column: :user_id, on_delete: :nullify # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :resource_state_events, :users, column: :user_id, on_delete: :nullify end end diff --git a/db/migrate/20200423080334_add_issue_id_foreign_key_to_resource_state_events.rb b/db/migrate/20200423080334_add_issue_id_foreign_key_to_resource_state_events.rb index 660c51eb3a6..b9f0fdeaa16 100644 --- a/db/migrate/20200423080334_add_issue_id_foreign_key_to_resource_state_events.rb +++ b/db/migrate/20200423080334_add_issue_id_foreign_key_to_resource_state_events.rb @@ -7,7 +7,7 @@ class AddIssueIdForeignKeyToResourceStateEvents < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :resource_state_events, :issues, column: :issue_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :resource_state_events, :issues, column: :issue_id, on_delete: :cascade end end diff --git a/db/migrate/20200423080607_add_merge_request_id_foreign_key_to_resource_state_events.rb b/db/migrate/20200423080607_add_merge_request_id_foreign_key_to_resource_state_events.rb index 4f0a689a992..3c070984f9e 100644 --- a/db/migrate/20200423080607_add_merge_request_id_foreign_key_to_resource_state_events.rb +++ b/db/migrate/20200423080607_add_merge_request_id_foreign_key_to_resource_state_events.rb @@ -7,7 +7,7 @@ class AddMergeRequestIdForeignKeyToResourceStateEvents < ActiveRecord::Migration def up with_lock_retries do - add_foreign_key :resource_state_events, :merge_requests, column: :merge_request_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :resource_state_events, :merge_requests, column: :merge_request_id, on_delete: :cascade end end diff --git a/db/migrate/20200429015603_add_fk_to_project_repository_storage_moves.rb b/db/migrate/20200429015603_add_fk_to_project_repository_storage_moves.rb index a68ce66e4a6..166ce320a23 100644 --- a/db/migrate/20200429015603_add_fk_to_project_repository_storage_moves.rb +++ b/db/migrate/20200429015603_add_fk_to_project_repository_storage_moves.rb @@ -7,7 +7,7 @@ class AddFkToProjectRepositoryStorageMoves < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :project_repository_storage_moves, :projects, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :project_repository_storage_moves, :projects, on_delete: :cascade end end diff --git a/db/migrate/20200510183128_add_foreign_key_from_webauthn_registrations_to_users.rb b/db/migrate/20200510183128_add_foreign_key_from_webauthn_registrations_to_users.rb index f71a5276dee..9071e3e17e3 100644 --- a/db/migrate/20200510183128_add_foreign_key_from_webauthn_registrations_to_users.rb +++ b/db/migrate/20200510183128_add_foreign_key_from_webauthn_registrations_to_users.rb @@ -9,7 +9,7 @@ class AddForeignKeyFromWebauthnRegistrationsToUsers < ActiveRecord::Migration[6. def up with_lock_retries do - add_foreign_key :webauthn_registrations, :users, column: :user_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :webauthn_registrations, :users, column: :user_id, on_delete: :cascade end end diff --git a/db/migrate/20200511092505_add_foreign_key_to_epic_id_on_resource_state_events.rb b/db/migrate/20200511092505_add_foreign_key_to_epic_id_on_resource_state_events.rb index 8072fe81c4a..1daa620501a 100644 --- a/db/migrate/20200511092505_add_foreign_key_to_epic_id_on_resource_state_events.rb +++ b/db/migrate/20200511092505_add_foreign_key_to_epic_id_on_resource_state_events.rb @@ -7,7 +7,7 @@ class AddForeignKeyToEpicIdOnResourceStateEvents < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :resource_state_events, :epics, column: :epic_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :resource_state_events, :epics, column: :epic_id, on_delete: :cascade end end diff --git a/db/migrate/20200511121549_add_group_wiki_repositories_shard_id_foreign_key.rb b/db/migrate/20200511121549_add_group_wiki_repositories_shard_id_foreign_key.rb index c2606dfb0d5..d1bb3fcc6ea 100644 --- a/db/migrate/20200511121549_add_group_wiki_repositories_shard_id_foreign_key.rb +++ b/db/migrate/20200511121549_add_group_wiki_repositories_shard_id_foreign_key.rb @@ -7,7 +7,7 @@ class AddGroupWikiRepositoriesShardIdForeignKey < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :group_wiki_repositories, :shards, on_delete: :restrict # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :group_wiki_repositories, :shards, on_delete: :restrict end end diff --git a/db/migrate/20200511121610_add_group_wiki_repositories_group_id_foreign_key.rb b/db/migrate/20200511121610_add_group_wiki_repositories_group_id_foreign_key.rb index 3a4c75be3b9..40f272cc0e7 100644 --- a/db/migrate/20200511121610_add_group_wiki_repositories_group_id_foreign_key.rb +++ b/db/migrate/20200511121610_add_group_wiki_repositories_group_id_foreign_key.rb @@ -7,7 +7,7 @@ class AddGroupWikiRepositoriesGroupIdForeignKey < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :group_wiki_repositories, :namespaces, column: :group_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :group_wiki_repositories, :namespaces, column: :group_id, on_delete: :cascade end end diff --git a/db/migrate/20200511191027_add_author_foreign_key_to_test_reports.rb b/db/migrate/20200511191027_add_author_foreign_key_to_test_reports.rb index a9fbee388c5..532133fe7f9 100644 --- a/db/migrate/20200511191027_add_author_foreign_key_to_test_reports.rb +++ b/db/migrate/20200511191027_add_author_foreign_key_to_test_reports.rb @@ -7,7 +7,7 @@ class AddAuthorForeignKeyToTestReports < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :requirements_management_test_reports, :users, column: :author_id, on_delete: :nullify # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :requirements_management_test_reports, :users, column: :author_id, on_delete: :nullify end end diff --git a/db/migrate/20200511208012_add_pipeline_foreign_key_to_test_reports.rb b/db/migrate/20200511208012_add_pipeline_foreign_key_to_test_reports.rb index 2b9b3464580..46657f9af6d 100644 --- a/db/migrate/20200511208012_add_pipeline_foreign_key_to_test_reports.rb +++ b/db/migrate/20200511208012_add_pipeline_foreign_key_to_test_reports.rb @@ -7,7 +7,7 @@ class AddPipelineForeignKeyToTestReports < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :requirements_management_test_reports, :ci_pipelines, column: :pipeline_id, on_delete: :nullify # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :requirements_management_test_reports, :ci_pipelines, column: :pipeline_id, on_delete: :nullify end end diff --git a/db/migrate/20200521225337_add_foreign_key_to_user_id_on_alert_management_alert_assignees.rb b/db/migrate/20200521225337_add_foreign_key_to_user_id_on_alert_management_alert_assignees.rb index 9d97c68f78f..4a6a25a8472 100644 --- a/db/migrate/20200521225337_add_foreign_key_to_user_id_on_alert_management_alert_assignees.rb +++ b/db/migrate/20200521225337_add_foreign_key_to_user_id_on_alert_management_alert_assignees.rb @@ -7,7 +7,7 @@ class AddForeignKeyToUserIdOnAlertManagementAlertAssignees < ActiveRecord::Migra def up with_lock_retries do - add_foreign_key :alert_management_alert_assignees, :users, column: :user_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :alert_management_alert_assignees, :users, column: :user_id, on_delete: :cascade end end diff --git a/db/migrate/20200521225346_add_foreign_key_to_alert_id_on_alert_mangagement_alert_assignees.rb b/db/migrate/20200521225346_add_foreign_key_to_alert_id_on_alert_mangagement_alert_assignees.rb index 1d6197edef9..77d374f08fa 100644 --- a/db/migrate/20200521225346_add_foreign_key_to_alert_id_on_alert_mangagement_alert_assignees.rb +++ b/db/migrate/20200521225346_add_foreign_key_to_alert_id_on_alert_mangagement_alert_assignees.rb @@ -7,7 +7,7 @@ class AddForeignKeyToAlertIdOnAlertMangagementAlertAssignees < ActiveRecord::Mig def up with_lock_retries do - add_foreign_key :alert_management_alert_assignees, :alert_management_alerts, column: :alert_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :alert_management_alert_assignees, :alert_management_alerts, column: :alert_id, on_delete: :cascade end end diff --git a/db/migrate/20200526164947_add_foreign_key_to_ops_feature_flags_issues.rb b/db/migrate/20200526164947_add_foreign_key_to_ops_feature_flags_issues.rb index 1cad53cb371..a11a8094823 100644 --- a/db/migrate/20200526164947_add_foreign_key_to_ops_feature_flags_issues.rb +++ b/db/migrate/20200526164947_add_foreign_key_to_ops_feature_flags_issues.rb @@ -7,7 +7,7 @@ class AddForeignKeyToOpsFeatureFlagsIssues < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :operations_feature_flags_issues, :issues, column: :issue_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :operations_feature_flags_issues, :issues, column: :issue_id, on_delete: :cascade end end diff --git a/db/migrate/20200527135313_add_requirements_build_reference.rb b/db/migrate/20200527135313_add_requirements_build_reference.rb index 3385243fbdd..b492871a19b 100644 --- a/db/migrate/20200527135313_add_requirements_build_reference.rb +++ b/db/migrate/20200527135313_add_requirements_build_reference.rb @@ -11,7 +11,7 @@ class AddRequirementsBuildReference < ActiveRecord::Migration[6.0] add_index :requirements_management_test_reports, :build_id, name: INDEX_NAME # rubocop:disable Migration/AddIndex with_lock_retries do - add_foreign_key :requirements_management_test_reports, :ci_builds, column: :build_id, on_delete: :nullify # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :requirements_management_test_reports, :ci_builds, column: :build_id, on_delete: :nullify end end diff --git a/db/migrate/20200527152116_add_foreign_key_to_build_id_on_build_report_results.rb b/db/migrate/20200527152116_add_foreign_key_to_build_id_on_build_report_results.rb index 1c41389b15b..1809fed551a 100644 --- a/db/migrate/20200527152116_add_foreign_key_to_build_id_on_build_report_results.rb +++ b/db/migrate/20200527152116_add_foreign_key_to_build_id_on_build_report_results.rb @@ -7,7 +7,7 @@ class AddForeignKeyToBuildIdOnBuildReportResults < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :ci_build_report_results, :ci_builds, column: :build_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :ci_build_report_results, :ci_builds, column: :build_id, on_delete: :cascade end end diff --git a/db/migrate/20200527152657_add_foreign_key_to_project_id_on_build_report_results.rb b/db/migrate/20200527152657_add_foreign_key_to_project_id_on_build_report_results.rb index da870722bc3..1857cb07b06 100644 --- a/db/migrate/20200527152657_add_foreign_key_to_project_id_on_build_report_results.rb +++ b/db/migrate/20200527152657_add_foreign_key_to_project_id_on_build_report_results.rb @@ -7,7 +7,7 @@ class AddForeignKeyToProjectIdOnBuildReportResults < ActiveRecord::Migration[6.0 def up with_lock_retries do - add_foreign_key :ci_build_report_results, :projects, column: :project_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :ci_build_report_results, :projects, column: :project_id, on_delete: :cascade end end diff --git a/db/migrate/20200604174544_add_users_foreign_key_to_board_user_preferences.rb b/db/migrate/20200604174544_add_users_foreign_key_to_board_user_preferences.rb index 8f60c41a9c7..cc613e0261e 100644 --- a/db/migrate/20200604174544_add_users_foreign_key_to_board_user_preferences.rb +++ b/db/migrate/20200604174544_add_users_foreign_key_to_board_user_preferences.rb @@ -7,7 +7,7 @@ class AddUsersForeignKeyToBoardUserPreferences < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :board_user_preferences, :users, column: :user_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :board_user_preferences, :users, column: :user_id, on_delete: :cascade end end diff --git a/db/migrate/20200604174558_add_boards_foreign_key_to_board_user_preferences.rb b/db/migrate/20200604174558_add_boards_foreign_key_to_board_user_preferences.rb index a18f0eac505..4ac978d3741 100644 --- a/db/migrate/20200604174558_add_boards_foreign_key_to_board_user_preferences.rb +++ b/db/migrate/20200604174558_add_boards_foreign_key_to_board_user_preferences.rb @@ -7,7 +7,7 @@ class AddBoardsForeignKeyToBoardUserPreferences < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :board_user_preferences, :boards, column: :board_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :board_user_preferences, :boards, column: :board_id, on_delete: :cascade end end diff --git a/db/migrate/20200605003204_add_foreign_key_to_alert_management_alert_user_mentions.rb b/db/migrate/20200605003204_add_foreign_key_to_alert_management_alert_user_mentions.rb index 35a250521a6..3198544d3a9 100644 --- a/db/migrate/20200605003204_add_foreign_key_to_alert_management_alert_user_mentions.rb +++ b/db/migrate/20200605003204_add_foreign_key_to_alert_management_alert_user_mentions.rb @@ -7,7 +7,7 @@ class AddForeignKeyToAlertManagementAlertUserMentions < ActiveRecord::Migration[ def up with_lock_retries do - add_foreign_key :alert_management_alert_user_mentions, :notes, column: :note_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :alert_management_alert_user_mentions, :notes, column: :note_id, on_delete: :cascade end end diff --git a/db/migrate/20200623073431_add_source_merge_request_id_to_resource_state_events.rb b/db/migrate/20200623073431_add_source_merge_request_id_to_resource_state_events.rb index 8970797d3c0..01d0d8ce1d4 100644 --- a/db/migrate/20200623073431_add_source_merge_request_id_to_resource_state_events.rb +++ b/db/migrate/20200623073431_add_source_merge_request_id_to_resource_state_events.rb @@ -20,7 +20,7 @@ class AddSourceMergeRequestIdToResourceStateEvents < ActiveRecord::Migration[6.0 unless foreign_key_exists?(:resource_state_events, :merge_requests, column: :source_merge_request_id) with_lock_retries do - add_foreign_key :resource_state_events, :merge_requests, column: :source_merge_request_id, on_delete: :nullify # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :resource_state_events, :merge_requests, column: :source_merge_request_id, on_delete: :nullify end end end diff --git a/db/migrate/20200722132040_add_users_fk_to_resource_iteration_events_table.rb b/db/migrate/20200722132040_add_users_fk_to_resource_iteration_events_table.rb index e28405be53d..c3d95c9dfc2 100644 --- a/db/migrate/20200722132040_add_users_fk_to_resource_iteration_events_table.rb +++ b/db/migrate/20200722132040_add_users_fk_to_resource_iteration_events_table.rb @@ -7,7 +7,7 @@ class AddUsersFkToResourceIterationEventsTable < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :resource_iteration_events, :users, column: :user_id, on_delete: :nullify # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :resource_iteration_events, :users, column: :user_id, on_delete: :nullify end end diff --git a/db/migrate/20200722132540_add_issues_fk_to_resource_iteration_events_table.rb b/db/migrate/20200722132540_add_issues_fk_to_resource_iteration_events_table.rb index adb10aaa707..b603f14f62b 100644 --- a/db/migrate/20200722132540_add_issues_fk_to_resource_iteration_events_table.rb +++ b/db/migrate/20200722132540_add_issues_fk_to_resource_iteration_events_table.rb @@ -7,7 +7,7 @@ class AddIssuesFkToResourceIterationEventsTable < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :resource_iteration_events, :issues, column: :issue_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :resource_iteration_events, :issues, column: :issue_id, on_delete: :cascade end end diff --git a/db/migrate/20200722133040_add_merge_requests_fk_to_resource_iteration_events_table.rb b/db/migrate/20200722133040_add_merge_requests_fk_to_resource_iteration_events_table.rb index 8b1859bb253..e047b157a53 100644 --- a/db/migrate/20200722133040_add_merge_requests_fk_to_resource_iteration_events_table.rb +++ b/db/migrate/20200722133040_add_merge_requests_fk_to_resource_iteration_events_table.rb @@ -7,7 +7,7 @@ class AddMergeRequestsFkToResourceIterationEventsTable < ActiveRecord::Migration def up with_lock_retries do - add_foreign_key :resource_iteration_events, :merge_requests, column: :merge_request_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :resource_iteration_events, :merge_requests, column: :merge_request_id, on_delete: :cascade end end diff --git a/db/migrate/20200722133540_add_iterations_fk_to_resource_iteration_events_table.rb b/db/migrate/20200722133540_add_iterations_fk_to_resource_iteration_events_table.rb index b42c29a0634..1bb3ac7c8bd 100644 --- a/db/migrate/20200722133540_add_iterations_fk_to_resource_iteration_events_table.rb +++ b/db/migrate/20200722133540_add_iterations_fk_to_resource_iteration_events_table.rb @@ -7,7 +7,7 @@ class AddIterationsFkToResourceIterationEventsTable < ActiveRecord::Migration[6. def up with_lock_retries do - add_foreign_key :resource_iteration_events, :sprints, column: :iteration_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :resource_iteration_events, :sprints, column: :iteration_id, on_delete: :cascade end end diff --git a/db/migrate/20200731201408_add_foreign_key_to_experiment_on_experiment_users.rb b/db/migrate/20200731201408_add_foreign_key_to_experiment_on_experiment_users.rb index 3961803bf52..c1a6dae242b 100644 --- a/db/migrate/20200731201408_add_foreign_key_to_experiment_on_experiment_users.rb +++ b/db/migrate/20200731201408_add_foreign_key_to_experiment_on_experiment_users.rb @@ -8,7 +8,7 @@ class AddForeignKeyToExperimentOnExperimentUsers < ActiveRecord::Migration[6.0] def up with_lock_retries do # There is no need to use add_concurrent_foreign_key since it's an empty table - add_foreign_key :experiment_users, :experiments, column: :experiment_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :experiment_users, :experiments, column: :experiment_id, on_delete: :cascade end end diff --git a/db/migrate/20200731201834_add_foreign_key_to_user_on_experiment_users.rb b/db/migrate/20200731201834_add_foreign_key_to_user_on_experiment_users.rb index 42c337fecff..673a0bde0b1 100644 --- a/db/migrate/20200731201834_add_foreign_key_to_user_on_experiment_users.rb +++ b/db/migrate/20200731201834_add_foreign_key_to_user_on_experiment_users.rb @@ -8,7 +8,7 @@ class AddForeignKeyToUserOnExperimentUsers < ActiveRecord::Migration[6.0] def up with_lock_retries do # There is no need to use add_concurrent_foreign_key since it's an empty table - add_foreign_key :experiment_users, :users, column: :user_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :experiment_users, :users, column: :user_id, on_delete: :cascade end end diff --git a/db/migrate/20200805151001_add_foreign_key_to_pipeline_id_on_pipeline_artifact.rb b/db/migrate/20200805151001_add_foreign_key_to_pipeline_id_on_pipeline_artifact.rb index d6c3a4fe742..5cfe0496b8d 100644 --- a/db/migrate/20200805151001_add_foreign_key_to_pipeline_id_on_pipeline_artifact.rb +++ b/db/migrate/20200805151001_add_foreign_key_to_pipeline_id_on_pipeline_artifact.rb @@ -7,7 +7,7 @@ class AddForeignKeyToPipelineIdOnPipelineArtifact < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :ci_pipeline_artifacts, :ci_pipelines, column: :pipeline_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :ci_pipeline_artifacts, :ci_pipelines, column: :pipeline_id, on_delete: :cascade end end diff --git a/db/migrate/20200805151726_add_foreign_key_to_project_id_on_pipeline_artifact.rb b/db/migrate/20200805151726_add_foreign_key_to_project_id_on_pipeline_artifact.rb index 367a2774d62..fe418f4c5af 100644 --- a/db/migrate/20200805151726_add_foreign_key_to_project_id_on_pipeline_artifact.rb +++ b/db/migrate/20200805151726_add_foreign_key_to_project_id_on_pipeline_artifact.rb @@ -7,7 +7,7 @@ class AddForeignKeyToProjectIdOnPipelineArtifact < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :ci_pipeline_artifacts, :projects, column: :project_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :ci_pipeline_artifacts, :projects, column: :project_id, on_delete: :cascade end end diff --git a/db/migrate/20200825081035_boards_epic_user_preferences_fk_board.rb b/db/migrate/20200825081035_boards_epic_user_preferences_fk_board.rb index eb52cadaecf..1c014573fb4 100644 --- a/db/migrate/20200825081035_boards_epic_user_preferences_fk_board.rb +++ b/db/migrate/20200825081035_boards_epic_user_preferences_fk_board.rb @@ -7,7 +7,7 @@ class BoardsEpicUserPreferencesFkBoard < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :boards_epic_user_preferences, :boards, column: :board_id, on_delete: :cascade # rubocop: disable Migration/AddConcurrentForeignKey + add_foreign_key :boards_epic_user_preferences, :boards, column: :board_id, on_delete: :cascade end end diff --git a/db/migrate/20200825081045_boards_epic_user_preferences_fk_user.rb b/db/migrate/20200825081045_boards_epic_user_preferences_fk_user.rb index 98d0a5b64f6..3edc3bc0ded 100644 --- a/db/migrate/20200825081045_boards_epic_user_preferences_fk_user.rb +++ b/db/migrate/20200825081045_boards_epic_user_preferences_fk_user.rb @@ -7,7 +7,7 @@ class BoardsEpicUserPreferencesFkUser < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :boards_epic_user_preferences, :users, column: :user_id, on_delete: :cascade # rubocop: disable Migration/AddConcurrentForeignKey + add_foreign_key :boards_epic_user_preferences, :users, column: :user_id, on_delete: :cascade end end diff --git a/db/migrate/20200825081055_boards_epic_user_preferences_fk_epic.rb b/db/migrate/20200825081055_boards_epic_user_preferences_fk_epic.rb index 46498f186c4..0354060b7c1 100644 --- a/db/migrate/20200825081055_boards_epic_user_preferences_fk_epic.rb +++ b/db/migrate/20200825081055_boards_epic_user_preferences_fk_epic.rb @@ -7,7 +7,7 @@ class BoardsEpicUserPreferencesFkEpic < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :boards_epic_user_preferences, :epics, column: :epic_id, on_delete: :cascade # rubocop: disable Migration/AddConcurrentForeignKey + add_foreign_key :boards_epic_user_preferences, :epics, column: :epic_id, on_delete: :cascade end end diff --git a/db/migrate/20200827060911_add_merge_request_foreign_key_to_merge_request_reviewers.rb b/db/migrate/20200827060911_add_merge_request_foreign_key_to_merge_request_reviewers.rb index dc3356375fd..73d0eea9819 100644 --- a/db/migrate/20200827060911_add_merge_request_foreign_key_to_merge_request_reviewers.rb +++ b/db/migrate/20200827060911_add_merge_request_foreign_key_to_merge_request_reviewers.rb @@ -10,7 +10,7 @@ class AddMergeRequestForeignKeyToMergeRequestReviewers < ActiveRecord::Migration def up with_lock_retries do - add_foreign_key :merge_request_reviewers, :merge_requests, column: :merge_request_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :merge_request_reviewers, :merge_requests, column: :merge_request_id, on_delete: :cascade end end diff --git a/db/migrate/20200827060932_add_user_foreign_key_to_merge_request_reviewers.rb b/db/migrate/20200827060932_add_user_foreign_key_to_merge_request_reviewers.rb index d6c6985a668..5463c3d9846 100644 --- a/db/migrate/20200827060932_add_user_foreign_key_to_merge_request_reviewers.rb +++ b/db/migrate/20200827060932_add_user_foreign_key_to_merge_request_reviewers.rb @@ -10,7 +10,7 @@ class AddUserForeignKeyToMergeRequestReviewers < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :merge_request_reviewers, :users, column: :user_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :merge_request_reviewers, :users, column: :user_id, on_delete: :cascade end end diff --git a/db/migrate/20200828155134_add_foreign_key_on_scan_id_to_security_scans.rb b/db/migrate/20200828155134_add_foreign_key_on_scan_id_to_security_scans.rb index 612bd79a282..9d815cc75dc 100644 --- a/db/migrate/20200828155134_add_foreign_key_on_scan_id_to_security_scans.rb +++ b/db/migrate/20200828155134_add_foreign_key_on_scan_id_to_security_scans.rb @@ -7,7 +7,7 @@ class AddForeignKeyOnScanIdToSecurityScans < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :security_findings, :security_scans, column: :scan_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :security_findings, :security_scans, column: :scan_id, on_delete: :cascade end end diff --git a/db/migrate/20200828155205_add_foreign_key_on_scanner_id_to_vulnerability_scanners.rb b/db/migrate/20200828155205_add_foreign_key_on_scanner_id_to_vulnerability_scanners.rb index eb3e878c8be..015e83b59b1 100644 --- a/db/migrate/20200828155205_add_foreign_key_on_scanner_id_to_vulnerability_scanners.rb +++ b/db/migrate/20200828155205_add_foreign_key_on_scanner_id_to_vulnerability_scanners.rb @@ -7,7 +7,7 @@ class AddForeignKeyOnScannerIdToVulnerabilityScanners < ActiveRecord::Migration[ def up with_lock_retries do - add_foreign_key :security_findings, :vulnerability_scanners, column: :scanner_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :security_findings, :vulnerability_scanners, column: :scanner_id, on_delete: :cascade end end diff --git a/db/migrate/20200911121027_add_pages_deployment_project_foreign_key.rb b/db/migrate/20200911121027_add_pages_deployment_project_foreign_key.rb index 70418881c4f..665b9de9230 100644 --- a/db/migrate/20200911121027_add_pages_deployment_project_foreign_key.rb +++ b/db/migrate/20200911121027_add_pages_deployment_project_foreign_key.rb @@ -7,7 +7,7 @@ class AddPagesDeploymentProjectForeignKey < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :pages_deployments, :projects, column: :project_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :pages_deployments, :projects, column: :project_id, on_delete: :cascade end end diff --git a/db/migrate/20200911121048_add_pages_deployment_ci_build_foreign_key.rb b/db/migrate/20200911121048_add_pages_deployment_ci_build_foreign_key.rb index ece721d88d5..83f38b2fae3 100644 --- a/db/migrate/20200911121048_add_pages_deployment_ci_build_foreign_key.rb +++ b/db/migrate/20200911121048_add_pages_deployment_ci_build_foreign_key.rb @@ -7,7 +7,7 @@ class AddPagesDeploymentCiBuildForeignKey < ActiveRecord::Migration[6.0] def up with_lock_retries do - add_foreign_key :pages_deployments, :ci_builds, column: :ci_build_id, on_delete: :nullify # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :pages_deployments, :ci_builds, column: :ci_build_id, on_delete: :nullify end end diff --git a/db/migrate/20200912193210_add_scheduling_issues_temp_indexes.rb b/db/migrate/20200912193210_add_scheduling_issues_temp_indexes.rb new file mode 100644 index 00000000000..bc2b8d4ce97 --- /dev/null +++ b/db/migrate/20200912193210_add_scheduling_issues_temp_indexes.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class AddSchedulingIssuesTempIndexes < ActiveRecord::Migration[6.0] + include Gitlab::Database::MigrationHelpers + + DOWNTIME = false + + disable_ddl_transaction! + + def up + add_concurrent_index :issue_links, [:source_id], where: 'link_type = 1', name: 'tmp_idx_blocking_type_links' + add_concurrent_index :issue_links, [:target_id], where: 'link_type = 2', name: 'tmp_idx_blocked_by_type_links' + add_concurrent_index :issues, :id, where: '(state_id = 1 AND blocking_issues_count = 0)', name: 'tmp_idx_index_issues_with_outdate_blocking_count' + end + + def down + remove_concurrent_index_by_name(:issue_links, 'tmp_idx_blocking_type_links') + remove_concurrent_index_by_name(:issue_links, 'tmp_idx_blocked_by_type_links') + remove_concurrent_index_by_name(:issues, 'tmp_idx_index_issues_with_outdate_blocking_count') + end +end diff --git a/db/post_migrate/20200810191256_remove_pipeline_id_from_test_reports.rb b/db/post_migrate/20200810191256_remove_pipeline_id_from_test_reports.rb index 4a5e6942371..f99629a921e 100644 --- a/db/post_migrate/20200810191256_remove_pipeline_id_from_test_reports.rb +++ b/db/post_migrate/20200810191256_remove_pipeline_id_from_test_reports.rb @@ -13,9 +13,7 @@ class RemovePipelineIdFromTestReports < ActiveRecord::Migration[6.0] add_column :requirements_management_test_reports, :pipeline_id, :integer with_lock_retries do - # rubocop:disable Migration/AddConcurrentForeignKey add_foreign_key :requirements_management_test_reports, :ci_pipelines, column: :pipeline_id, on_delete: :nullify - # rubocop:enable Migration/AddConcurrentForeignKey end end end diff --git a/db/post_migrate/20200914185610_schedule_sync_blocking_issues_count.rb b/db/post_migrate/20200914185610_schedule_sync_blocking_issues_count.rb new file mode 100644 index 00000000000..74272cf5b39 --- /dev/null +++ b/db/post_migrate/20200914185610_schedule_sync_blocking_issues_count.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +class ScheduleSyncBlockingIssuesCount < ActiveRecord::Migration[6.0] + include Gitlab::Database::MigrationHelpers + + BATCH_SIZE = 50 + DELAY_INTERVAL = 120.seconds.to_i + MIGRATION = 'SyncBlockingIssuesCount'.freeze + + disable_ddl_transaction! + + class Issue < ActiveRecord::Base + include EachBatch + + self.table_name = 'issues' + end + + def up + return unless Gitlab.ee? + + blocking_issues_ids = <<-SQL + SELECT issue_links.source_id AS blocking_issue_id + FROM issue_links + INNER JOIN issues ON issue_links.source_id = issues.id + WHERE issue_links.link_type = 1 + AND issues.state_id = 1 + AND issues.blocking_issues_count = 0 + UNION + SELECT issue_links.target_id AS blocking_issue_id + FROM issue_links + INNER JOIN issues ON issue_links.target_id = issues.id + WHERE issue_links.link_type = 2 + AND issues.state_id = 1 + AND issues.blocking_issues_count = 0 + SQL + + relation = + Issue.where("id IN(#{blocking_issues_ids})") # rubocop:disable GitlabSecurity/SqlInjection + + queue_background_migration_jobs_by_range_at_intervals( + relation, + MIGRATION, + DELAY_INTERVAL, + batch_size: BATCH_SIZE + ) + end + + def down + # no-op + end +end diff --git a/db/schema_migrations/20200912193210 b/db/schema_migrations/20200912193210 new file mode 100644 index 00000000000..a6ce007630a --- /dev/null +++ b/db/schema_migrations/20200912193210 @@ -0,0 +1 @@ +bcc84e89e4e9772d3209aa8df1368c188b1c6334114bcf339870cae74e724d01
\ No newline at end of file diff --git a/db/schema_migrations/20200914185610 b/db/schema_migrations/20200914185610 new file mode 100644 index 00000000000..a2bf098a7ac --- /dev/null +++ b/db/schema_migrations/20200914185610 @@ -0,0 +1 @@ +50cdb8d42baa0890b39ca7d07a4c157aea7d52a39dee48ee59e51417442eaaf4
\ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index fbd33ecc19c..038fcd4120e 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -21755,6 +21755,12 @@ CREATE INDEX terraform_state_versions_verification_failure_partial ON terraform_ CREATE INDEX tmp_build_stage_position_index ON ci_builds USING btree (stage_id, stage_idx) WHERE (stage_idx IS NOT NULL); +CREATE INDEX tmp_idx_blocked_by_type_links ON issue_links USING btree (target_id) WHERE (link_type = 2); + +CREATE INDEX tmp_idx_blocking_type_links ON issue_links USING btree (source_id) WHERE (link_type = 1); + +CREATE INDEX tmp_idx_index_issues_with_outdate_blocking_count ON issues USING btree (id) WHERE ((state_id = 1) AND (blocking_issues_count = 0)); + CREATE INDEX tmp_index_for_email_unconfirmation_migration ON emails USING btree (id) WHERE (confirmed_at IS NOT NULL); CREATE UNIQUE INDEX unique_merge_request_metrics_by_merge_request_id ON merge_request_metrics USING btree (merge_request_id); diff --git a/doc/development/cicd/templates.md b/doc/development/cicd/templates.md index 77cedc9814e..aff4405dc51 100644 --- a/doc/development/cicd/templates.md +++ b/doc/development/cicd/templates.md @@ -13,15 +13,16 @@ This document explains how to develop [GitLab CI/CD templates](../../ci/examples All template files reside in the `lib/gitlab/ci/templates` directory, and are categorized by the following sub-directories: -| Sub-directory | Content | [Selectable in UI](#make-sure-the-new-template-can-be-selected-in-ui) | -|----------------|--------------------------------------------------------------|-----------------------------------------------------------------------| -| `/AWS/*` | Cloud Deployment (AWS) related jobs | No | -| `/Jobs/*` | Auto DevOps related jobs | No | -| `/Pages/*` | Static site generators for GitLab Pages (for example Jekyll) | Yes | -| `/Security/*` | Security related jobs | Yes | -| `/Verify/*` | Verify/testing related jobs | Yes | -| `/Workflows/*` | Common uses of the `workflow:` keyword | No | -| `/*` (root) | General templates | Yes | +| Sub-directory | Content | [Selectable in UI](#make-sure-the-new-template-can-be-selected-in-ui) | +|----------------|----------------------------------------------------|-----------------------------------------------------------------------| +| `/AWS/*` | Cloud Deployment (AWS) related jobs | No | +| `/Jobs/*` | Auto DevOps related jobs | No | +| `/Pages/*` | Static site generators for GitLab Pages (for example Jekyll) | Yes | +| `/Security/*` | Security related jobs | Yes | +| `/Terraform/*` | Infrastructure as Code related templates | No | +| `/Verify/*` | Verify/testing related jobs | Yes | +| `/Workflows/*` | Common uses of the `workflow:` keyword | No | +| `/*` (root) | General templates | Yes | ## Criteria diff --git a/doc/development/migration_style_guide.md b/doc/development/migration_style_guide.md index 48de6e53a85..268770193f9 100644 --- a/doc/development/migration_style_guide.md +++ b/doc/development/migration_style_guide.md @@ -300,7 +300,7 @@ include Gitlab::Database::MigrationHelpers def up with_lock_retries do - add_foreign_key :imports, :projects, column: :project_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :imports, :projects, column: :project_id, on_delete: :cascade end end @@ -318,7 +318,7 @@ include Gitlab::Database::MigrationHelpers def up with_lock_retries do - add_foreign_key :imports, :users, column: :user_id, on_delete: :cascade # rubocop:disable Migration/AddConcurrentForeignKey + add_foreign_key :imports, :users, column: :user_id, on_delete: :cascade end end diff --git a/doc/topics/autodevops/upgrading_postgresql.md b/doc/topics/autodevops/upgrading_postgresql.md index 2ebe362280f..bcbc1d914be 100644 --- a/doc/topics/autodevops/upgrading_postgresql.md +++ b/doc/topics/autodevops/upgrading_postgresql.md @@ -178,8 +178,11 @@ You can also PostgreSQL. 1. Set `AUTO_DEVOPS_POSTGRES_DELETE_V1` to a non-empty value. This flag is a safeguard to prevent accidental deletion of databases. -1. Set `POSTGRES_VERSION` to `11.7`. This is the minimum PostgreSQL - version supported. + <!-- DO NOT REPLACE when upgrading GitLab's supported version. This is NOT related to GitLab's PostgreSQL version support, but the one deployed by Auto DevOps. --> +1. If you have a `POSTGRES_VERSION` set, make sure it is set to `9.6.16` *or +higher*. This is the + minimum PostgreSQL version supported by Auto DevOps. See also the list of + [tags available](https://hub.docker.com/r/bitnami/postgresql/tags). 1. Set `PRODUCTION_REPLICAS` to `0`. For other environments, use `REPLICAS` with an [environment scope](../../ci/environments/index.md#scoping-environments-with-specs). 1. If you have set the `DB_INITIALIZE` or `DB_MIGRATE` variables, either diff --git a/lib/gitlab/auth/user_access_denied_reason.rb b/lib/gitlab/auth/user_access_denied_reason.rb index cc4b8d887ff..36b54ba2e46 100644 --- a/lib/gitlab/auth/user_access_denied_reason.rb +++ b/lib/gitlab/auth/user_access_denied_reason.rb @@ -11,6 +11,8 @@ module Gitlab case rejection_type when :internal "This action cannot be performed by internal users" + when :blocked_pending_approval + "Your account is pending approval from your administrator and hence blocked." when :terms_not_accepted "You (#{@user.to_reference}) must accept the Terms of Service in order to perform this action. "\ "Please access GitLab from a web browser to accept these terms." @@ -31,6 +33,8 @@ module Gitlab def rejection_type if @user.internal? :internal + elsif @user.blocked_pending_approval? + :blocked_pending_approval elsif @user.required_terms_not_accepted? :terms_not_accepted elsif @user.deactivated? diff --git a/lib/gitlab/background_migration/sync_blocking_issues_count.rb b/lib/gitlab/background_migration/sync_blocking_issues_count.rb new file mode 100644 index 00000000000..6262320128c --- /dev/null +++ b/lib/gitlab/background_migration/sync_blocking_issues_count.rb @@ -0,0 +1,13 @@ +# frozen_string_literal: true +# rubocop:disable Style/Documentation + +module Gitlab + module BackgroundMigration + class SyncBlockingIssuesCount + def perform(start_id, end_id) + end + end + end +end + +Gitlab::BackgroundMigration::SyncBlockingIssuesCount.prepend_if_ee('EE::Gitlab::BackgroundMigration::SyncBlockingIssuesCount') diff --git a/lib/gitlab/ci/features.rb b/lib/gitlab/ci/features.rb index e14d56af978..1a53cf614f9 100644 --- a/lib/gitlab/ci/features.rb +++ b/lib/gitlab/ci/features.rb @@ -59,6 +59,10 @@ module Gitlab ::Feature.enabled?(:ci_accept_trace, project, type: :ops, default_enabled: false) end + def self.log_invalid_trace_chunks?(project) + ::Feature.enabled?(:ci_trace_log_invalid_chunks, project, type: :ops, default_enabled: false) + end + def self.new_artifact_file_reader_enabled?(project) ::Feature.enabled?(:ci_new_artifact_file_reader, project, default_enabled: true) end diff --git a/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml new file mode 100644 index 00000000000..b08ccf18b58 --- /dev/null +++ b/lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml @@ -0,0 +1,22 @@ +include: + - template: Terraform/Base.latest.gitlab-ci.yml # https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/templates/Terraform/Base.gitlab-ci.yml + +stages: + - init + - validate + - build + - deploy + +init: + extends: .init + +validate: + extends: .validate + +build: + extends: .build + +deploy: + extends: .deploy + dependencies: + - build diff --git a/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml new file mode 100644 index 00000000000..000a1a7f580 --- /dev/null +++ b/lib/gitlab/ci/templates/Terraform/Base.latest.gitlab-ci.yml @@ -0,0 +1,53 @@ +# Terraform/Base.latest +# +# The purpose of this template is to provide flexibility to the user so +# they are able to only include the jobs that they find interesting. +# +# Therefore, this template is not supposed to run any jobs. The idea is to only +# create hidden jobs. See: https://docs.gitlab.com/ee/ci/yaml/#hide-jobs +# +# There is a more opinionated template which we suggest the users to abide, +# which is the lib/gitlab/ci/templates/Terraform.latest.gitlab-ci.yml + +image: + name: registry.gitlab.com/gitlab-org/terraform-images/stable:latest + +before_script: + - cd ${TF_ROOT} + +variables: + TF_ROOT: ${CI_PROJECT_DIR} + +cache: + key: "${TF_ROOT}" + paths: + - ${TF_ROOT}/.terraform/ + +.init: &init + stage: init + script: + - gitlab-terraform init + +.validate: &validate + stage: validate + script: + - gitlab-terraform validate + +.build: &build + stage: build + script: + - gitlab-terraform plan + - gitlab-terraform plan-json + artifacts: + paths: + - ${TF_ROOT}/plan.cache + reports: + terraform: ${TF_ROOT}/plan.json + +.deploy: &deploy + stage: deploy + script: + - gitlab-terraform apply + when: manual + only: + - master diff --git a/lib/gitlab/ci/trace/checksum.rb b/lib/gitlab/ci/trace/checksum.rb index b01136a6d24..62532ef1cd2 100644 --- a/lib/gitlab/ci/trace/checksum.rb +++ b/lib/gitlab/ci/trace/checksum.rb @@ -30,12 +30,14 @@ module Gitlab end def state_crc32 - strong_memoize(:crc32) { build.pending_state&.crc32 } + strong_memoize(:state_crc32) { build.pending_state&.crc32 } end def chunks_crc32 - trace_chunks.reduce(0) do |crc32, chunk| - Zlib.crc32_combine(crc32, chunk.crc32, chunk_size(chunk)) + strong_memoize(:chunks_crc32) do + trace_chunks.reduce(0) do |crc32, chunk| + Zlib.crc32_combine(crc32, chunk.crc32, chunk_size(chunk)) + end end end @@ -62,6 +64,10 @@ module Gitlab end end + def chunks_count + trace_chunks.to_a.size + end + private def chunk_size(chunk) diff --git a/lib/gitlab/database/batch_count.rb b/lib/gitlab/database/batch_count.rb index 0de67ed8cf0..11d9881aac2 100644 --- a/lib/gitlab/database/batch_count.rb +++ b/lib/gitlab/database/batch_count.rb @@ -86,14 +86,16 @@ module Gitlab batch_start = start while batch_start <= finish + batch_relation = build_relation_batch(batch_start, batch_start + batch_size, mode) begin - results = merge_results(results, batch_fetch(batch_start, batch_start + batch_size, mode)) + results = merge_results(results, batch_relation.send(@operation, *@operation_args)) # rubocop:disable GitlabSecurity/PublicSend batch_start += batch_size - rescue ActiveRecord::QueryCanceled + rescue ActiveRecord::QueryCanceled => error # retry with a safe batch size & warmer cache if batch_size >= 2 * MIN_REQUIRED_BATCH_SIZE batch_size /= 2 else + log_canceled_batch_fetch(batch_start, mode, batch_relation.to_sql, error) return FALLBACK end end @@ -113,13 +115,12 @@ module Gitlab end end - def batch_fetch(start, finish, mode) - # rubocop:disable GitlabSecurity/PublicSend - @relation.select(@column).public_send(mode).where(between_condition(start, finish)).send(@operation, *@operation_args) - end - private + def build_relation_batch(start, finish, mode) + @relation.select(@column).public_send(mode).where(between_condition(start, finish)) # rubocop:disable GitlabSecurity/PublicSend + end + def batch_size_for_mode_and_operation(mode, operation) return DEFAULT_SUM_BATCH_SIZE if operation == :sum @@ -145,6 +146,20 @@ module Gitlab raise 'Use distinct count for optimized distinct counting' if @relation.limit(1).distinct_value.present? && mode != :distinct raise 'Use distinct count only with non id fields' if @column == :id && mode == :distinct end + + def log_canceled_batch_fetch(batch_start, mode, query, error) + Gitlab::AppJsonLogger + .error( + event: 'batch_count', + relation: @relation.table_name, + operation: @operation, + operation_args: @operation_args, + start: batch_start, + mode: mode, + query: query, + message: "Query has been canceled with message: #{error.message}" + ) + end end end end diff --git a/lib/gitlab/git/wiki.rb b/lib/gitlab/git/wiki.rb index da2d015ca4a..83bd1091c7b 100644 --- a/lib/gitlab/git/wiki.rb +++ b/lib/gitlab/git/wiki.rb @@ -173,9 +173,9 @@ module Gitlab gitaly_pages = if load_content - gitaly_wiki_client.load_all_pages(params) + gitaly_wiki_client.load_all_pages(**params) else - gitaly_wiki_client.list_all_pages(params) + gitaly_wiki_client.list_all_pages(**params) end gitaly_pages.map do |wiki_page, version| diff --git a/lib/gitlab/graphql/query_analyzers/logger_analyzer.rb b/lib/gitlab/graphql/query_analyzers/logger_analyzer.rb index 1e568e9dcbc..1285365376f 100644 --- a/lib/gitlab/graphql/query_analyzers/logger_analyzer.rb +++ b/lib/gitlab/graphql/query_analyzers/logger_analyzer.rb @@ -25,7 +25,7 @@ module Gitlab end def call(memo, visit_type, irep_node) - memo + RequestStore.store[:graphql_logs] = memo end def final_value(memo) @@ -35,6 +35,8 @@ module Gitlab memo[:depth] = depth memo[:complexity] = complexity + # This duration is not the execution time of the + # query but the execution time of the analyzer. memo[:duration_s] = duration(memo[:time_started]).round(1) memo[:used_fields] = field_usages.first memo[:used_deprecated_fields] = field_usages.second diff --git a/lib/gitlab/template/gitlab_ci_yml_template.rb b/lib/gitlab/template/gitlab_ci_yml_template.rb index bb1e9db55fa..e12af6bf0a4 100644 --- a/lib/gitlab/template/gitlab_ci_yml_template.rb +++ b/lib/gitlab/template/gitlab_ci_yml_template.rb @@ -3,7 +3,7 @@ module Gitlab module Template class GitlabCiYmlTemplate < BaseTemplate - BASE_EXCLUDED_PATTERNS = [%r{\.latest$}].freeze + BASE_EXCLUDED_PATTERNS = [%r{\.latest\.}].freeze def content explanation = "# This file is a template, and might need editing before it works on your project." diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 5f83f93e7cc..2605bd918d5 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -6456,9 +6456,6 @@ msgstr "" msgid "ComboSearch is not defined" msgstr "" -msgid "Coming soon" -msgstr "" - msgid "Comma-separated, e.g. '1.1.1.1, 2.2.2.0/24'" msgstr "" @@ -18305,9 +18302,6 @@ msgstr "" msgid "PackageRegistry|If you haven't already done so, you will need to add the below to your %{codeStart}pom.xml%{codeEnd} file." msgstr "" -msgid "PackageRegistry|Is your favorite package manager missing? We'd love your help in building first-class support for it into GitLab! %{contributionLinkStart}Visit the contribution documentation%{contributionLinkEnd} to learn more about how to build support for new package managers into GitLab. Below is a list of package managers that are on our radar." -msgstr "" - msgid "PackageRegistry|Learn how to %{noPackagesLinkStart}publish and share your packages%{noPackagesLinkEnd} with GitLab." msgstr "" @@ -18329,9 +18323,6 @@ msgstr "" msgid "PackageRegistry|NPM" msgstr "" -msgid "PackageRegistry|No upcoming issues" -msgstr "" - msgid "PackageRegistry|NuGet" msgstr "" @@ -18377,9 +18368,6 @@ msgstr "" msgid "PackageRegistry|There are no packages yet" msgstr "" -msgid "PackageRegistry|There are no upcoming issues to display." -msgstr "" - msgid "PackageRegistry|There was a problem fetching the details for this package." msgstr "" @@ -18395,9 +18383,6 @@ msgstr "" msgid "PackageRegistry|Unable to load package" msgstr "" -msgid "PackageRegistry|Upcoming package managers" -msgstr "" - msgid "PackageRegistry|You are about to delete %{name}, this operation is irreversible, are you sure?" msgstr "" diff --git a/package.json b/package.json index c1bce4dc1a5..dec2b6d7a15 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "@babel/preset-env": "^7.10.1", "@gitlab/at.js": "1.5.5", "@gitlab/svgs": "1.170.0", - "@gitlab/ui": "21.14.0", + "@gitlab/ui": "21.16.0", "@gitlab/visual-review-tools": "1.6.1", "@rails/actioncable": "^6.0.3-3", "@rails/ujs": "^6.0.3-2", diff --git a/rubocop/cop/migration/add_concurrent_foreign_key.rb b/rubocop/cop/migration/add_concurrent_foreign_key.rb index 236de6224a4..31cf426b2d4 100644 --- a/rubocop/cop/migration/add_concurrent_foreign_key.rb +++ b/rubocop/cop/migration/add_concurrent_foreign_key.rb @@ -11,7 +11,11 @@ module RuboCop MSG = '`add_foreign_key` requires downtime, use `add_concurrent_foreign_key` instead'.freeze def_node_matcher :false_node?, <<~PATTERN - (false) + (false) + PATTERN + + def_node_matcher :with_lock_retries?, <<~PATTERN + (:send nil? :with_lock_retries) PATTERN def on_send(node) @@ -19,9 +23,11 @@ module RuboCop name = node.children[1] - if name == :add_foreign_key && !not_valid_fk?(node) - add_offense(node, location: :selector) - end + return unless name == :add_foreign_key + return if in_with_lock_retries?(node) + return if not_valid_fk?(node) + + add_offense(node, location: :selector) end def method_name(node) @@ -33,6 +39,12 @@ module RuboCop pair.children[0].children[0] == :validate && false_node?(pair.children[1]) end end + + def in_with_lock_retries?(node) + node.each_ancestor(:block).any? do |parent| + with_lock_retries?(parent.to_a.first) + end + end end end end diff --git a/spec/controllers/every_controller_spec.rb b/spec/controllers/every_controller_spec.rb index 85f6f57bab6..d301c8b84ff 100644 --- a/spec/controllers/every_controller_spec.rb +++ b/spec/controllers/every_controller_spec.rb @@ -29,7 +29,7 @@ RSpec.describe "Every controller" do 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', - 'X', 'Y', 'Z', 'A', + 'X', 'Y', 'Z', 'A', 'G', 'Projects::MergeRequestsController') "#{controller}##{action}" diff --git a/spec/controllers/graphql_controller_spec.rb b/spec/controllers/graphql_controller_spec.rb index b0aa4b016d9..e4aea688a69 100644 --- a/spec/controllers/graphql_controller_spec.rb +++ b/spec/controllers/graphql_controller_spec.rb @@ -156,9 +156,11 @@ RSpec.describe GraphqlController do describe '#append_info_to_payload' do let(:graphql_query) { graphql_query_for('project', { 'fullPath' => 'foo' }, %w(id name)) } + let(:mock_store) { { graphql_logs: { foo: :bar } } } let(:log_payload) { {} } before do + allow(RequestStore).to receive(:store).and_return(mock_store) allow(controller).to receive(:append_info_to_payload).and_wrap_original do |method, *| method.call(log_payload) end @@ -168,7 +170,7 @@ RSpec.describe GraphqlController do post :execute, params: { query: graphql_query, operationName: 'Foo' } expect(controller).to have_received(:append_info_to_payload) - expect(log_payload.dig(:metadata, :graphql, :operation_name)).to eq('Foo') + expect(log_payload.dig(:metadata, :graphql)).to eq({ operation_name: 'Foo', foo: :bar }) end end end diff --git a/spec/controllers/projects/web_ide_terminals_controller_spec.rb b/spec/controllers/projects/web_ide_terminals_controller_spec.rb index 3eb3d5da351..09c471d2885 100644 --- a/spec/controllers/projects/web_ide_terminals_controller_spec.rb +++ b/spec/controllers/projects/web_ide_terminals_controller_spec.rb @@ -9,17 +9,20 @@ RSpec.describe Projects::WebIdeTerminalsController do let_it_be(:developer) { create(:user) } let_it_be(:reporter) { create(:user) } let_it_be(:guest) { create(:user) } - let_it_be(:project) { create(:project, :private, :repository, namespace: owner.namespace) } + let_it_be(:project) do + create(:project, :private, :repository, namespace: owner.namespace).tap do |project| + project.add_maintainer(maintainer) + project.add_developer(developer) + project.add_reporter(reporter) + project.add_guest(guest) + end + end + let(:pipeline) { create(:ci_pipeline, project: project, source: :webide, config_source: :webide_source, user: user) } let(:job) { create(:ci_build, pipeline: pipeline, user: user, project: project) } let(:user) { maintainer } before do - project.add_maintainer(maintainer) - project.add_developer(developer) - project.add_reporter(reporter) - project.add_guest(guest) - sign_in(user) end @@ -158,11 +161,11 @@ RSpec.describe Projects::WebIdeTerminalsController do end context 'access rights' do - before do - subject + it_behaves_like 'terminal access rights' do + before do + subject + end end - - it_behaves_like 'terminal access rights' end it 'increases the web ide terminal counter' do diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index 47d234df22b..75bcc32e6f3 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -100,6 +100,16 @@ RSpec.describe SessionsController do end end + context 'a `blocked pending approval` user' do + it 'does not authenticate the user' do + user.block_pending_approval! + post_action + + expect(@request.env['warden']).not_to be_authenticated + expect(flash[:alert]).to include('Your account is pending approval from your GitLab administrator and hence blocked') + end + end + context 'an internal user' do it 'does not authenticate the user' do user.ghost! diff --git a/spec/factories/projects.rb b/spec/factories/projects.rb index 091c9d5a245..87e4a8e355d 100644 --- a/spec/factories/projects.rb +++ b/spec/factories/projects.rb @@ -15,7 +15,7 @@ FactoryBot.define do # Associations namespace - creator { group ? create(:user) : namespace&.owner } + creator { group ? association(:user) : namespace&.owner } transient do # Nest Project Feature attributes diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 1a8c5d7e40c..2e5b3be3bf2 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -23,6 +23,14 @@ FactoryBot.define do after(:build) { |user, _| user.block! } end + trait :blocked_pending_approval do + after(:build) { |user, _| user.block_pending_approval! } + end + + trait :ldap_blocked do + after(:build) { |user, _| user.ldap_block! } + end + trait :bot do user_type { :alert_bot } end diff --git a/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb b/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb index 3dc49fb4dea..444d5371e7a 100644 --- a/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb +++ b/spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb @@ -47,7 +47,7 @@ RSpec.describe 'Merge request > User merges when pipeline succeeds', :js do it_behaves_like 'Merge when pipeline succeeds activator' end - context 'when enabled after pipeline status changed' do + context 'when enabled after pipeline status changed', quarantine: 'https://gitlab.com/gitlab-org/gitlab/-/issues/258667' do before do pipeline.run! diff --git a/spec/frontend/packages/list/coming_soon/helpers_spec.js b/spec/frontend/packages/list/coming_soon/helpers_spec.js deleted file mode 100644 index 4a996bfad76..00000000000 --- a/spec/frontend/packages/list/coming_soon/helpers_spec.js +++ /dev/null @@ -1,36 +0,0 @@ -import * as comingSoon from '~/packages/list/coming_soon/helpers'; -import { fakeIssues, asGraphQLResponse, asViewModel } from './mock_data'; - -jest.mock('~/api.js'); - -describe('Coming Soon Helpers', () => { - const [noLabels, acceptingMergeRequestLabel, workflowLabel] = fakeIssues; - - describe('toViewModel', () => { - it('formats a GraphQL response correctly', () => { - expect(comingSoon.toViewModel(asGraphQLResponse)).toEqual(asViewModel); - }); - }); - - describe('findWorkflowLabel', () => { - it('finds a workflow label', () => { - expect(comingSoon.findWorkflowLabel(workflowLabel.labels)).toEqual(workflowLabel.labels[0]); - }); - - it("returns undefined when there isn't one", () => { - expect(comingSoon.findWorkflowLabel(noLabels.labels)).toBeUndefined(); - }); - }); - - describe('findAcceptingContributionsLabel', () => { - it('finds the correct label when it exists', () => { - expect(comingSoon.findAcceptingContributionsLabel(acceptingMergeRequestLabel.labels)).toEqual( - acceptingMergeRequestLabel.labels[0], - ); - }); - - it("returns undefined when there isn't one", () => { - expect(comingSoon.findAcceptingContributionsLabel(noLabels.labels)).toBeUndefined(); - }); - }); -}); diff --git a/spec/frontend/packages/list/coming_soon/mock_data.js b/spec/frontend/packages/list/coming_soon/mock_data.js deleted file mode 100644 index bb4568e4bd5..00000000000 --- a/spec/frontend/packages/list/coming_soon/mock_data.js +++ /dev/null @@ -1,90 +0,0 @@ -export const fakeIssues = [ - { - id: 1, - iid: 1, - title: 'issue one', - webUrl: 'foo', - }, - { - id: 2, - iid: 2, - title: 'issue two', - labels: [{ title: 'Accepting merge requests', color: '#69d100' }], - milestone: { - title: '12.10', - }, - webUrl: 'foo', - }, - { - id: 3, - iid: 3, - title: 'issue three', - labels: [{ title: 'workflow::In dev', color: '#428bca' }], - webUrl: 'foo', - }, - { - id: 4, - iid: 4, - title: 'issue four', - labels: [ - { title: 'Accepting merge requests', color: '#69d100' }, - { title: 'workflow::In dev', color: '#428bca' }, - ], - webUrl: 'foo', - }, -]; - -export const asGraphQLResponse = { - project: { - issues: { - nodes: fakeIssues.map(x => ({ - ...x, - labels: { - nodes: x.labels, - }, - })), - }, - }, -}; - -export const asViewModel = [ - { - ...fakeIssues[0], - labels: [], - }, - { - ...fakeIssues[1], - labels: [ - { - title: 'Accepting merge requests', - color: '#69d100', - scoped: false, - }, - ], - }, - { - ...fakeIssues[2], - labels: [ - { - title: 'workflow::In dev', - color: '#428bca', - scoped: true, - }, - ], - }, - { - ...fakeIssues[3], - labels: [ - { - title: 'workflow::In dev', - color: '#428bca', - scoped: true, - }, - { - title: 'Accepting merge requests', - color: '#69d100', - scoped: false, - }, - ], - }, -]; diff --git a/spec/frontend/packages/list/coming_soon/packages_coming_soon_spec.js b/spec/frontend/packages/list/coming_soon/packages_coming_soon_spec.js deleted file mode 100644 index c4cdadc45e6..00000000000 --- a/spec/frontend/packages/list/coming_soon/packages_coming_soon_spec.js +++ /dev/null @@ -1,138 +0,0 @@ -import { GlEmptyState, GlSkeletonLoader, GlLabel } from '@gitlab/ui'; -import { mount, createLocalVue } from '@vue/test-utils'; -import VueApollo, { ApolloQuery } from 'vue-apollo'; -import ComingSoon from '~/packages/list/coming_soon/packages_coming_soon.vue'; -import { TrackingActions } from '~/packages/shared/constants'; -import { asViewModel } from './mock_data'; -import Tracking from '~/tracking'; - -jest.mock('~/packages/list/coming_soon/helpers.js'); - -const localVue = createLocalVue(); -localVue.use(VueApollo); - -describe('packages_coming_soon', () => { - let wrapper; - - const findSkeletonLoader = () => wrapper.find(GlSkeletonLoader); - const findAllIssues = () => wrapper.findAll('[data-testid="issue-row"]'); - const findIssuesData = () => - findAllIssues().wrappers.map(x => { - const titleLink = x.find('[data-testid="issue-title-link"]'); - const milestone = x.find('[data-testid="milestone"]'); - const issueIdLink = x.find('[data-testid="issue-id-link"]'); - const labels = x.findAll(GlLabel); - - const issueId = Number(issueIdLink.text().substr(1)); - - return { - id: issueId, - iid: issueId, - title: titleLink.text(), - webUrl: titleLink.attributes('href'), - labels: labels.wrappers.map(label => ({ - color: label.props('backgroundColor'), - title: label.props('title'), - scoped: label.props('scoped'), - })), - ...(milestone.exists() ? { milestone: { title: milestone.text() } } : {}), - }; - }); - const findIssueTitleLink = () => wrapper.find('[data-testid="issue-title-link"]'); - const findIssueIdLink = () => wrapper.find('[data-testid="issue-id-link"]'); - const findEmptyState = () => wrapper.find(GlEmptyState); - - const mountComponent = (testParams = {}) => { - const $apolloData = { - loading: testParams.isLoading || false, - }; - - wrapper = mount(ComingSoon, { - localVue, - propsData: { - illustration: 'foo', - projectPath: 'foo', - suggestedContributionsPath: 'foo', - }, - stubs: { - ApolloQuery, - GlLink: true, - }, - mocks: { - $apolloData, - }, - }); - - // Mock the GraphQL query result - wrapper.find(ApolloQuery).setData({ - result: { - data: testParams.issues || asViewModel, - }, - }); - }; - - afterEach(() => { - wrapper.destroy(); - wrapper = null; - }); - - describe('when loading', () => { - beforeEach(() => mountComponent({ isLoading: true })); - - it('renders the skeleton loader', () => { - expect(findSkeletonLoader().exists()).toBe(true); - }); - }); - - describe('when there are no issues', () => { - beforeEach(() => mountComponent({ issues: [] })); - - it('renders the empty state', () => { - expect(findEmptyState().exists()).toBe(true); - }); - }); - - describe('when there are issues', () => { - beforeEach(() => mountComponent()); - - it('renders each issue', () => { - expect(findIssuesData()).toEqual(asViewModel); - }); - }); - - describe('tracking', () => { - const firstIssue = asViewModel[0]; - let eventSpy; - - beforeEach(() => { - eventSpy = jest.spyOn(Tracking, 'event'); - mountComponent(); - }); - - it('tracks when mounted', () => { - expect(eventSpy).toHaveBeenCalledWith(undefined, TrackingActions.COMING_SOON_REQUESTED, {}); - }); - - it('tracks when an issue title link is clicked', () => { - eventSpy.mockClear(); - - findIssueTitleLink().vm.$emit('click'); - - expect(eventSpy).toHaveBeenCalledWith(undefined, TrackingActions.COMING_SOON_LIST, { - label: firstIssue.title, - value: firstIssue.iid, - }); - }); - - it('tracks when an issue id link is clicked', () => { - eventSpy.mockClear(); - - findIssueIdLink().vm.$emit('click'); - - expect(eventSpy).toHaveBeenCalledWith(undefined, TrackingActions.COMING_SOON_LIST, { - label: firstIssue.title, - value: firstIssue.iid, - }); - }); - }); -}); diff --git a/spec/frontend/packages/list/components/__snapshots__/packages_list_app_spec.js.snap b/spec/frontend/packages/list/components/__snapshots__/packages_list_app_spec.js.snap index 9a52531ae8d..ce3a58c856d 100644 --- a/spec/frontend/packages/list/components/__snapshots__/packages_list_app_spec.js.snap +++ b/spec/frontend/packages/list/components/__snapshots__/packages_list_app_spec.js.snap @@ -444,8 +444,6 @@ exports[`packages_list_app renders 1`] = ` </div> </template> </b-tab-stub> - - <!----> </template> <template> <div diff --git a/spec/frontend/packages/list/stores/mutations_spec.js b/spec/frontend/packages/list/stores/mutations_spec.js index 563a3dabbb3..0d424a0c011 100644 --- a/spec/frontend/packages/list/stores/mutations_spec.js +++ b/spec/frontend/packages/list/stores/mutations_spec.js @@ -18,7 +18,6 @@ describe('Mutations Registry Store', () => { userCanDelete: '', emptyListIllustration: 'foo', emptyListHelpUrl: 'baz', - comingSoonJson: '{ "project_path": "gitlab-org/gitlab-test" }', }; const expectedState = { diff --git a/spec/frontend/vue_shared/components/alert_details_table_spec.js b/spec/frontend/vue_shared/components/alert_details_table_spec.js index dbdb7705d3c..2bc599bcf79 100644 --- a/spec/frontend/vue_shared/components/alert_details_table_spec.js +++ b/spec/frontend/vue_shared/components/alert_details_table_spec.js @@ -14,6 +14,7 @@ const mockAlert = { assignees: { nodes: [] }, notes: { nodes: [] }, todos: { nodes: [] }, + hosts: ['host1', 'host2'], __typename: 'AlertManagementAlert', }; @@ -83,6 +84,7 @@ describe('AlertDetails', () => { expect(findTableField(fields, 'Severity').exists()).toBe(true); expect(findTableField(fields, 'Status').exists()).toBe(true); expect(findTableField(fields, 'Environment').exists()).toBe(true); + expect(findTableField(fields, 'Hosts').exists()).toBe(true); }); it('should not show disallowed alert fields', () => { diff --git a/spec/frontend/wikis_spec.js b/spec/frontend/wikis_spec.js index 3469be4da1c..cf1ea972697 100644 --- a/spec/frontend/wikis_spec.js +++ b/spec/frontend/wikis_spec.js @@ -146,7 +146,7 @@ describe('Wikis', () => { expect(Tracking.event).toHaveBeenCalledWith(trackingPage, 'view_wiki_page', { label: 'view_wiki_page', context: { - schema: 'iglu:com.gitlab/wiki_page_context/jsonschema/1-0-0', + schema: 'iglu:com.gitlab/wiki_page_context/jsonschema/1-0-1', data: trackingContext, }, }); diff --git a/spec/graphql/mutations/design_management/move_spec.rb b/spec/graphql/mutations/design_management/move_spec.rb index 7519347d07c..d17483e69b3 100644 --- a/spec/graphql/mutations/design_management/move_spec.rb +++ b/spec/graphql/mutations/design_management/move_spec.rb @@ -29,7 +29,7 @@ RSpec.describe Mutations::DesignManagement::Move do next_design: next_design&.to_global_id }.compact - mutation.resolve(args) + mutation.resolve(**args) end shared_examples "resource not available" do diff --git a/spec/helpers/packages_helper_spec.rb b/spec/helpers/packages_helper_spec.rb index 1917c851547..3988b80dd13 100644 --- a/spec/helpers/packages_helper_spec.rb +++ b/spec/helpers/packages_helper_spec.rb @@ -51,38 +51,4 @@ RSpec.describe PackagesHelper do expect(url).to eq("#{base_url}group/1/-/packages/composer/packages.json") end end - - describe 'packages_coming_soon_enabled?' do - it 'returns false when the feature flag is disabled' do - stub_feature_flags(packages_coming_soon: false) - - expect(helper.packages_coming_soon_enabled?(project)).to eq(false) - end - - it 'returns false when not on dev or gitlab.com' do - expect(helper.packages_coming_soon_enabled?(project)).to eq(false) - end - end - - describe 'packages_coming_soon_data' do - let_it_be(:group) { create(:group) } - - before do - allow(Gitlab).to receive(:dev_env_or_com?) { true } - end - - it 'returns the gitlab project on gitlab.com' do - allow(Gitlab).to receive(:com?) { true } - - expect(helper.packages_coming_soon_data(project)).to include({ project_path: 'gitlab-org/gitlab' }) - end - - it 'returns the test project when not on gitlab.com' do - expect(helper.packages_coming_soon_data(project)).to include({ project_path: 'gitlab-org/gitlab-test' }) - end - - it 'works correctly with a group' do - expect(helper.packages_coming_soon_data(group)).to include({ project_path: 'gitlab-org/gitlab-test' }) - end - end end diff --git a/spec/helpers/wiki_helper_spec.rb b/spec/helpers/wiki_helper_spec.rb index 28678104c2d..45e1859893f 100644 --- a/spec/helpers/wiki_helper_spec.rb +++ b/spec/helpers/wiki_helper_spec.rb @@ -135,7 +135,8 @@ RSpec.describe WikiHelper do 'wiki-format' => :markdown, 'wiki-title-size' => 9, 'wiki-content-size' => 4, - 'wiki-directory-nest-level' => 2 + 'wiki-directory-nest-level' => 2, + 'wiki-container-type' => 'Project' ) end diff --git a/spec/lib/gitlab/auth/user_access_denied_reason_spec.rb b/spec/lib/gitlab/auth/user_access_denied_reason_spec.rb index 5cbd22827c9..d3c6cde5590 100644 --- a/spec/lib/gitlab/auth/user_access_denied_reason_spec.rb +++ b/spec/lib/gitlab/auth/user_access_denied_reason_spec.rb @@ -49,5 +49,13 @@ RSpec.describe Gitlab::Auth::UserAccessDeniedReason do it { is_expected.to match /Your primary email address is not confirmed/ } end + + context 'when the user is blocked pending approval' do + before do + user.block_pending_approval! + end + + it { is_expected.to eq('Your account is pending approval from your administrator and hence blocked.') } + end end end diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb index 74360637897..1768ab41a71 100644 --- a/spec/lib/gitlab/auth_spec.rb +++ b/spec/lib/gitlab/auth_spec.rb @@ -726,6 +726,12 @@ RSpec.describe Gitlab::Auth, :use_clean_rails_memory_store_caching do expect( gl_auth.find_with_user_password(username, password) ).not_to eql user end + it 'does not find user in blocked_pending_approval state' do + user.block_pending_approval + + expect( gl_auth.find_with_user_password(username, password) ).not_to eql user + end + context 'with increment_failed_attempts' do wrong_password = 'incorrect_password' diff --git a/spec/lib/gitlab/ci/templates/Terraform/base_gitlab_ci_yaml_spec.rb b/spec/lib/gitlab/ci/templates/Terraform/base_gitlab_ci_yaml_spec.rb new file mode 100644 index 00000000000..8df739d9245 --- /dev/null +++ b/spec/lib/gitlab/ci/templates/Terraform/base_gitlab_ci_yaml_spec.rb @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Terraform/Base.latest.gitlab-ci.yml' do + subject(:template) { Gitlab::Template::GitlabCiYmlTemplate.find('Terraform/Base.latest') } + + describe 'the created pipeline' do + let(:user) { create(:admin) } + let(:default_branch) { 'master' } + let(:pipeline_branch) { default_branch } + let(:project) { create(:project, :custom_repo, files: { 'README.md' => '' }) } + let(:service) { Ci::CreatePipelineService.new(project, user, ref: pipeline_branch ) } + let(:pipeline) { service.execute!(:push) } + let(:build_names) { pipeline.builds.pluck(:name) } + + before do + stub_ci_pipeline_yaml_file(template.content) + allow_any_instance_of(Ci::BuildScheduleWorker).to receive(:perform).and_return(true) + allow(project).to receive(:default_branch).and_return(default_branch) + end + + it 'does not create any jobs' do + expect(build_names).to be_empty + end + end +end diff --git a/spec/lib/gitlab/ci/templates/terraform_latest_gitlab_ci_yaml_spec.rb b/spec/lib/gitlab/ci/templates/terraform_latest_gitlab_ci_yaml_spec.rb new file mode 100644 index 00000000000..5eec021b9d7 --- /dev/null +++ b/spec/lib/gitlab/ci/templates/terraform_latest_gitlab_ci_yaml_spec.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe 'Terraform.latest.gitlab-ci.yml' do + before do + allow(Gitlab::Template::GitlabCiYmlTemplate).to receive(:excluded_patterns).and_return([]) + end + + subject(:template) { Gitlab::Template::GitlabCiYmlTemplate.find('Terraform.latest') } + + describe 'the created pipeline' do + let_it_be(:user) { create(:admin) } + + let(:default_branch) { 'master' } + let(:pipeline_branch) { default_branch } + let(:project) { create(:project, :custom_repo, files: { 'README.md' => '' }) } + let(:service) { Ci::CreatePipelineService.new(project, user, ref: pipeline_branch ) } + let(:pipeline) { service.execute!(:push) } + let(:build_names) { pipeline.builds.pluck(:name) } + + before do + stub_ci_pipeline_yaml_file(template.content) + allow_any_instance_of(Ci::BuildScheduleWorker).to receive(:perform).and_return(true) + allow(project).to receive(:default_branch).and_return(default_branch) + end + + context 'on master branch' do + it 'creates init, validate and build jobs' do + expect(build_names).to include('init', 'validate', 'build', 'deploy') + end + end + + context 'outside the master branch' do + let(:pipeline_branch) { 'patch-1' } + + before do + project.repository.create_branch(pipeline_branch) + end + + it 'does not creates a deploy and a test job' do + expect(build_names).not_to include('deploy') + end + end + end +end diff --git a/spec/lib/gitlab/database/batch_count_spec.rb b/spec/lib/gitlab/database/batch_count_spec.rb index 93c499eb56d..31a8b4afa03 100644 --- a/spec/lib/gitlab/database/batch_count_spec.rb +++ b/spec/lib/gitlab/database/batch_count_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe Gitlab::Database::BatchCount do let_it_be(:fallback) { ::Gitlab::Database::BatchCounter::FALLBACK } - let_it_be(:small_batch_size) { ::Gitlab::Database::BatchCounter::MIN_REQUIRED_BATCH_SIZE - 1 } + let_it_be(:small_batch_size) { calculate_batch_size(::Gitlab::Database::BatchCounter::MIN_REQUIRED_BATCH_SIZE) } let(:model) { Issue } let(:column) { :author_id } @@ -22,6 +22,12 @@ RSpec.describe Gitlab::Database::BatchCount do allow(ActiveRecord::Base.connection).to receive(:transaction_open?).and_return(in_transaction) end + def calculate_batch_size(batch_size) + zero_offset_modifier = -1 + + batch_size + zero_offset_modifier + end + shared_examples 'disallowed configurations' do |method| it 'returns fallback if start is bigger than finish' do expect(described_class.public_send(method, *args, start: 1, finish: 0)).to eq(fallback) @@ -45,6 +51,46 @@ RSpec.describe Gitlab::Database::BatchCount do end end + shared_examples 'when batch fetch query is canceled' do + let(:batch_size) { 22_000 } + let(:relation) { instance_double(ActiveRecord::Relation) } + + it 'reduces batch size by half and retry fetch' do + too_big_batch_relation_mock = instance_double(ActiveRecord::Relation) + allow(model).to receive_message_chain(:select, public_send: relation) + allow(relation).to receive(:where).with("id" => 0..calculate_batch_size(batch_size)).and_return(too_big_batch_relation_mock) + allow(too_big_batch_relation_mock).to receive(:send).and_raise(ActiveRecord::QueryCanceled) + + expect(relation).to receive(:where).with("id" => 0..calculate_batch_size(batch_size / 2)).and_return(double(send: 1)) + + subject.call(model, column, batch_size: batch_size, start: 0) + end + + context 'when all retries fail' do + let(:batch_count_query) { 'SELECT COUNT(id) FROM relation WHERE id BETWEEN 0 and 1' } + + before do + allow(model).to receive_message_chain(:select, :public_send, where: relation) + allow(relation).to receive(:send).and_raise(ActiveRecord::QueryCanceled.new('query timed out')) + allow(relation).to receive(:to_sql).and_return(batch_count_query) + end + + it 'logs failing query' do + expect(Gitlab::AppJsonLogger).to receive(:error).with( + event: 'batch_count', + relation: model.table_name, + operation: operation, + operation_args: operation_args, + start: 0, + mode: mode, + query: batch_count_query, + message: 'Query has been canceled with message: query timed out' + ) + expect(subject.call(model, column, batch_size: batch_size, start: 0)).to eq(-1) + end + end + end + describe '#batch_count' do it 'counts table' do expect(described_class.batch_count(model)).to eq(5) @@ -86,10 +132,11 @@ RSpec.describe Gitlab::Database::BatchCount do it "defaults the batch size to #{Gitlab::Database::BatchCounter::DEFAULT_BATCH_SIZE}" do min_id = model.minimum(:id) + relation = instance_double(ActiveRecord::Relation) + allow(model).to receive_message_chain(:select, public_send: relation) + batch_end_id = min_id + calculate_batch_size(Gitlab::Database::BatchCounter::DEFAULT_BATCH_SIZE) - expect_next_instance_of(Gitlab::Database::BatchCounter) do |batch_counter| - expect(batch_counter).to receive(:batch_fetch).with(min_id, Gitlab::Database::BatchCounter::DEFAULT_BATCH_SIZE + min_id, :itself).once.and_call_original - end + expect(relation).to receive(:where).with("id" => min_id..batch_end_id).and_return(double(send: 1)) described_class.batch_count(model) end @@ -98,6 +145,15 @@ RSpec.describe Gitlab::Database::BatchCount do subject { described_class.batch_count(model) } end + it_behaves_like 'when batch fetch query is canceled' do + let(:mode) { :itself } + let(:operation) { :count } + let(:operation_args) { nil } + let(:column) { nil } + + subject { described_class.method(:batch_count) } + end + context 'disallowed_configurations' do include_examples 'disallowed configurations', :batch_count do let(:args) { [Issue] } @@ -169,10 +225,11 @@ RSpec.describe Gitlab::Database::BatchCount do it "defaults the batch size to #{Gitlab::Database::BatchCounter::DEFAULT_DISTINCT_BATCH_SIZE}" do min_id = model.minimum(:id) + relation = instance_double(ActiveRecord::Relation) + allow(model).to receive_message_chain(:select, public_send: relation) + batch_end_id = min_id + calculate_batch_size(Gitlab::Database::BatchCounter::DEFAULT_DISTINCT_BATCH_SIZE) - expect_next_instance_of(Gitlab::Database::BatchCounter) do |batch_counter| - expect(batch_counter).to receive(:batch_fetch).with(min_id, Gitlab::Database::BatchCounter::DEFAULT_DISTINCT_BATCH_SIZE + min_id, :distinct).once.and_call_original - end + expect(relation).to receive(:where).with("id" => min_id..batch_end_id).and_return(double(send: 1)) described_class.batch_distinct_count(model) end @@ -211,6 +268,15 @@ RSpec.describe Gitlab::Database::BatchCount do end end end + + it_behaves_like 'when batch fetch query is canceled' do + let(:mode) { :distinct } + let(:operation) { :count } + let(:operation_args) { nil } + let(:column) { nil } + + subject { described_class.method(:batch_distinct_count) } + end end describe '#batch_sum' do @@ -245,10 +311,11 @@ RSpec.describe Gitlab::Database::BatchCount do it "defaults the batch size to #{Gitlab::Database::BatchCounter::DEFAULT_SUM_BATCH_SIZE}" do min_id = model.minimum(:id) + relation = instance_double(ActiveRecord::Relation) + allow(model).to receive_message_chain(:select, public_send: relation) + batch_end_id = min_id + calculate_batch_size(Gitlab::Database::BatchCounter::DEFAULT_SUM_BATCH_SIZE) - expect_next_instance_of(Gitlab::Database::BatchCounter) do |batch_counter| - expect(batch_counter).to receive(:batch_fetch).with(min_id, Gitlab::Database::BatchCounter::DEFAULT_SUM_BATCH_SIZE + min_id, :itself).once.and_call_original - end + expect(relation).to receive(:where).with("id" => min_id..batch_end_id).and_return(double(send: 1)) described_class.batch_sum(model, column) end @@ -262,5 +329,13 @@ RSpec.describe Gitlab::Database::BatchCount do let(:default_batch_size) { Gitlab::Database::BatchCounter::DEFAULT_SUM_BATCH_SIZE } let(:small_batch_size) { Gitlab::Database::BatchCounter::DEFAULT_SUM_BATCH_SIZE - 1 } end + + it_behaves_like 'when batch fetch query is canceled' do + let(:mode) { :itself } + let(:operation) { :sum } + let(:operation_args) { [column] } + + subject { described_class.method(:batch_sum) } + end end end diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb index 3d60cc93bab..21607edbc32 100644 --- a/spec/lib/gitlab/git_access_spec.rb +++ b/spec/lib/gitlab/git_access_spec.rb @@ -420,6 +420,13 @@ RSpec.describe Gitlab::GitAccess do expect { pull_access_check }.to raise_forbidden('Your account has been blocked.') end + it 'disallows users that are blocked pending approval to pull' do + project.add_maintainer(user) + user.block_pending_approval + + expect { pull_access_check }.to raise_forbidden('Your account is pending approval from your administrator and hence blocked.') + end + it 'disallows deactivated users to pull' do project.add_maintainer(user) user.deactivate! @@ -915,6 +922,12 @@ RSpec.describe Gitlab::GitAccess do project.add_developer(user) end + it 'disallows users that are blocked pending approval to push' do + user.block_pending_approval + + expect { push_access_check }.to raise_forbidden('Your account is pending approval from your administrator and hence blocked.') + end + it 'does not allow deactivated users to push' do user.deactivate! diff --git a/spec/models/alert_management/alert_spec.rb b/spec/models/alert_management/alert_spec.rb index eb9dcca842d..37d1bd7e31a 100644 --- a/spec/models/alert_management/alert_spec.rb +++ b/spec/models/alert_management/alert_spec.rb @@ -133,7 +133,7 @@ RSpec.describe AlertManagement::Alert do let(:new_alert) { build(:alert_management_alert, new_status, fingerprint: fingerprint, project: project) } before do - existing_alert.public_send(described_class::STATUS_EVENTS[existing_status]) + existing_alert.change_status_to(existing_status) end if params[:valid] @@ -453,4 +453,54 @@ RSpec.describe AlertManagement::Alert do expect { subject }.to change { alert.events }.by(1) end end + + describe '#status_event_for' do + using RSpec::Parameterized::TableSyntax + + where(:for_status, :event) do + :triggered | :trigger + 'triggered' | :trigger + :acknowledged | :acknowledge + 'acknowledged' | :acknowledge + :resolved | :resolve + 'resolved' | :resolve + :ignored | :ignore + 'ignored' | :ignore + :unknown | nil + nil | nil + '' | nil + 1 | nil + end + + with_them do + let(:alert) { build(:alert_management_alert, project: project) } + + it 'returns event by status name' do + expect(alert.status_event_for(for_status)).to eq(event) + end + end + end + + describe '#change_status_to' do + let_it_be_with_reload(:alert) { create(:alert_management_alert, project: project) } + + context 'with valid statuses' do + it 'changes the status to triggered' do + alert.acknowledge! # change to non-triggered status + expect { alert.change_status_to(:triggered) }.to change { alert.triggered? }.to(true) + end + + %i(acknowledged resolved ignored).each do |status| + it "changes the status to #{status}" do + expect { alert.change_status_to(status) }.to change { alert.public_send(:"#{status}?") }.to(true) + end + end + end + + context 'with invalid status' do + it 'does not change the current status' do + expect { alert.change_status_to(nil) }.not_to change { alert.status } + end + end + end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index af5614ba85e..0dd9349b750 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -705,6 +705,25 @@ RSpec.describe User do end describe "scopes" do + describe '.blocked' do + subject { described_class.blocked } + + it 'returns only blocked users' do + active_user = create(:user) + blocked_user = create(:user, :blocked) + blocked_pending_approval_user = create(:user, :blocked_pending_approval) + ldap_blocked_user = create(:omniauth_user, :ldap_blocked) + + expect(subject).to include( + blocked_user, + blocked_pending_approval_user, + ldap_blocked_user + ) + + expect(subject).not_to include(active_user) + end + end + describe ".with_two_factor" do it "returns users with 2fa enabled via OTP" do user_with_2fa = create(:user, :two_factor_via_otp) @@ -1694,6 +1713,24 @@ RSpec.describe User do end end + describe 'blocking a user pending approval' do + let(:user) { create(:user) } + + before do + user.block_pending_approval + end + + context 'an active user' do + it 'can be blocked pending approval' do + expect(user.blocked_pending_approval?).to eq(true) + end + + it 'behaves like a blocked user' do + expect(user.blocked?).to eq(true) + end + end + end + describe '.filter_items' do let(:user) { double } @@ -4917,6 +4954,14 @@ RSpec.describe User do it { is_expected.to be :locked } end + + context 'when user is blocked pending approval' do + before do + user.block_pending_approval! + end + + it { is_expected.to be :blocked_pending_approval } + end end describe '#password_required?' do diff --git a/spec/policies/global_policy_spec.rb b/spec/policies/global_policy_spec.rb index e483598c47a..e3fbd7116e8 100644 --- a/spec/policies/global_policy_spec.rb +++ b/spec/policies/global_policy_spec.rb @@ -187,6 +187,14 @@ RSpec.describe GlobalPolicy do it { is_expected.not_to be_allowed(:access_api) } end + context 'user blocked pending approval' do + before do + current_user.block_pending_approval + end + + it { is_expected.not_to be_allowed(:access_api) } + end + context 'when terms are enforced' do before do enforce_terms @@ -276,6 +284,14 @@ RSpec.describe GlobalPolicy do it { is_expected.not_to be_allowed(:receive_notifications) } end + + context 'user blocked pending approval' do + before do + current_user.block_pending_approval + end + + it { is_expected.not_to be_allowed(:receive_notifications) } + end end describe 'git access' do @@ -344,6 +360,14 @@ RSpec.describe GlobalPolicy do it { is_expected.to be_allowed(:access_git) } end + + context 'user blocked pending approval' do + before do + current_user.block_pending_approval + end + + it { is_expected.not_to be_allowed(:access_git) } + end end describe 'read instance metadata' do @@ -412,6 +436,14 @@ RSpec.describe GlobalPolicy do it { is_expected.not_to be_allowed(:use_slash_commands) } end + + context 'user blocked pending approval' do + before do + current_user.block_pending_approval + end + + it { is_expected.not_to be_allowed(:use_slash_commands) } + end end describe 'create_snippet' do @@ -444,5 +476,13 @@ RSpec.describe GlobalPolicy do it { is_expected.not_to be_allowed(:log_in) } end + + context 'user blocked pending approval' do + before do + current_user.block_pending_approval + end + + it { is_expected.not_to be_allowed(:log_in) } + end end end diff --git a/spec/requests/api/doorkeeper_access_spec.rb b/spec/requests/api/doorkeeper_access_spec.rb index f16cd58bb34..77f1dadff46 100644 --- a/spec/requests/api/doorkeeper_access_spec.rb +++ b/spec/requests/api/doorkeeper_access_spec.rb @@ -71,4 +71,12 @@ RSpec.describe 'doorkeeper access' do it_behaves_like 'forbidden request' end + + context 'when user is blocked pending approval' do + before do + user.block_pending_approval + end + + it_behaves_like 'forbidden request' + end end diff --git a/spec/requests/api/lint_spec.rb b/spec/requests/api/lint_spec.rb index 3892df273bd..9890cdc20c0 100644 --- a/spec/requests/api/lint_spec.rb +++ b/spec/requests/api/lint_spec.rb @@ -79,7 +79,6 @@ RSpec.describe API::Lint do describe 'GET /projects/:id/ci/lint' do subject(:ci_lint) { get api("/projects/#{project.id}/ci/lint", api_user), params: { dry_run: dry_run } } - let_it_be(:api_user) { create(:user) } let(:project) { create(:project, :repository) } let(:dry_run) { nil } @@ -111,6 +110,8 @@ RSpec.describe API::Lint do end context 'when unauthenticated' do + let_it_be(:api_user) { nil } + it 'returns authentication error' do ci_lint @@ -118,7 +119,95 @@ RSpec.describe API::Lint do end end - context 'when authenticated as project member' do + context 'when authenticated as non-member' do + let_it_be(:api_user) { create(:user) } + + let(:yaml_content) do + { include: { local: 'another-gitlab-ci.yml' }, test: { stage: 'test', script: 'echo 1' } }.to_yaml + end + + context 'when project is private' do + before do + project.update!(visibility_level: Gitlab::VisibilityLevel::PRIVATE) + stub_ci_pipeline_yaml_file(yaml_content) + end + + it 'returns authentication error' do + ci_lint + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'when project is public' do + before do + project.update!(visibility_level: Gitlab::VisibilityLevel::PUBLIC) + end + + context 'when running as dry run' do + let(:dry_run) { true } + + before do + stub_ci_pipeline_yaml_file(yaml_content) + end + + it 'returns pipeline creation error' do + ci_lint + + expect(response).to have_gitlab_http_status(:ok) + expect(json_response['merged_yaml']).to eq(nil) + expect(json_response['valid']).to eq(false) + expect(json_response['errors']).to eq(['Insufficient permissions to create a new pipeline']) + end + end + + context 'when running static validation' do + let(:dry_run) { false } + + let(:included_content) do + { another_test: { stage: 'test', script: 'echo 1' } }.to_yaml + end + + before do + project.repository.create_file( + project.creator, + '.gitlab-ci.yml', + yaml_content, + message: 'Automatically created .gitlab-ci.yml', + branch_name: 'master' + ) + + project.repository.create_file( + project.creator, + 'another-gitlab-ci.yml', + included_content, + message: 'Automatically created another-gitlab-ci.yml', + branch_name: 'master' + ) + end + + it_behaves_like 'valid config' + end + end + end + + context 'when authenticated as project guest' do + let_it_be(:api_user) { create(:user) } + + before do + project.add_guest(api_user) + end + + it 'returns authentication error' do + ci_lint + + expect(response).to have_gitlab_http_status(:forbidden) + end + end + + context 'when authenticated as project developer' do + let_it_be(:api_user) { create(:user) } + before do project.add_developer(api_user) end diff --git a/spec/rubocop/cop/migration/add_concurrent_foreign_key_spec.rb b/spec/rubocop/cop/migration/add_concurrent_foreign_key_spec.rb index b43d44dba65..aaf191a1b6b 100644 --- a/spec/rubocop/cop/migration/add_concurrent_foreign_key_spec.rb +++ b/spec/rubocop/cop/migration/add_concurrent_foreign_key_spec.rb @@ -36,5 +36,15 @@ RSpec.describe RuboCop::Cop::Migration::AddConcurrentForeignKey, type: :rubocop expect(cop.offenses).to be_empty end + + it 'does not register an offense when `add_foreign_key` is within `with_lock_retries`' do + inspect_source <<~RUBY + with_lock_retries do + add_foreign_key :key, :projects, column: :project_id, on_delete: :cascade + end + RUBY + + expect(cop.offenses).to be_empty + end end end diff --git a/spec/services/projects/operations/update_service_spec.rb b/spec/services/projects/operations/update_service_spec.rb index 8a538bc67ed..018bfa8ef61 100644 --- a/spec/services/projects/operations/update_service_spec.rb +++ b/spec/services/projects/operations/update_service_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' RSpec.describe Projects::Operations::UpdateService do + let_it_be_with_refind(:project) { create(:project) } let_it_be(:user) { create(:user) } - let_it_be(:project, refind: true) { create(:project) } let(:result) { subject.execute } @@ -12,7 +12,7 @@ RSpec.describe Projects::Operations::UpdateService do describe '#execute' do context 'alerting setting' do - before do + before_all do project.add_maintainer(user) end @@ -430,5 +430,93 @@ RSpec.describe Projects::Operations::UpdateService do end end end + + context 'tracing setting' do + context 'with valid params' do + let(:params) do + { + tracing_setting_attributes: { + external_url: 'http://some-url.com' + } + } + end + + context 'with an existing setting' do + before do + create(:project_tracing_setting, project: project) + end + + shared_examples 'setting deletion' do + let!(:original_params) { params.deep_dup } + + it 'deletes the setting' do + expect(result[:status]).to eq(:success) + expect(project.reload.tracing_setting).to be_nil + end + + it 'does not modify original params' do + subject.execute + + expect(params).to eq(original_params) + end + end + + it 'updates the setting' do + expect(project.tracing_setting).not_to be_nil + + expect(result[:status]).to eq(:success) + expect(project.reload.tracing_setting.external_url) + .to eq('http://some-url.com') + end + + context 'with missing external_url' do + before do + params[:tracing_setting_attributes].delete(:external_url) + end + + it_behaves_like 'setting deletion' + end + + context 'with empty external_url' do + before do + params[:tracing_setting_attributes][:external_url] = '' + end + + it_behaves_like 'setting deletion' + end + + context 'with blank external_url' do + before do + params[:tracing_setting_attributes][:external_url] = ' ' + end + + it_behaves_like 'setting deletion' + end + end + + context 'without an existing setting' do + it 'creates a setting' do + expect(project.tracing_setting).to be_nil + + expect(result[:status]).to eq(:success) + expect(project.reload.tracing_setting.external_url) + .to eq('http://some-url.com') + end + end + end + + context 'with empty params' do + let(:params) { {} } + + let!(:tracing_setting) do + create(:project_tracing_setting, project: project) + end + + it 'does nothing' do + expect(result[:status]).to eq(:success) + expect(project.reload.tracing_setting).to eq(tracing_setting) + end + end + end end end diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb index 27c360ee39a..ab55cf97ab4 100644 --- a/spec/support/capybara.rb +++ b/spec/support/capybara.rb @@ -50,6 +50,10 @@ Capybara.register_driver :chrome do |app| ) options = Selenium::WebDriver::Chrome::Options.new + + # Force the browser's scale factor to prevent inconsistencies on high-res devices + options.add_argument('--force-device-scale-factor=1') + options.add_argument("window-size=#{CAPYBARA_WINDOW_SIZE.join(',')}") # Chrome won't work properly in a Docker container in sandbox mode diff --git a/spec/views/groups/edit.html.haml_spec.rb b/spec/views/groups/edit.html.haml_spec.rb index 83623ea7bb4..f40b03fda2a 100644 --- a/spec/views/groups/edit.html.haml_spec.rb +++ b/spec/views/groups/edit.html.haml_spec.rb @@ -26,7 +26,7 @@ RSpec.describe 'groups/edit.html.haml' do expect(rendered).to have_content("Prevent sharing a project within #{test_group.name} with other groups") expect(rendered).to have_css('.js-descr', text: 'help text here') - expect(rendered).to have_field('group_share_with_group_lock', checkbox_options) + expect(rendered).to have_field('group_share_with_group_lock', **checkbox_options) end end diff --git a/spec/views/profiles/preferences/show.html.haml_spec.rb b/spec/views/profiles/preferences/show.html.haml_spec.rb index 1dae953227d..aab50209953 100644 --- a/spec/views/profiles/preferences/show.html.haml_spec.rb +++ b/spec/views/profiles/preferences/show.html.haml_spec.rb @@ -75,7 +75,7 @@ RSpec.describe 'profiles/preferences/show' do end def have_integrations_section - have_css('#integrations.profile-settings-sidebar', { text: 'Integrations' }) + have_css('#integrations.profile-settings-sidebar', text: 'Integrations') end before do diff --git a/yarn.lock b/yarn.lock index 005d62de35a..addc8ea928a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -848,10 +848,10 @@ resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.170.0.tgz#b40fb7a8af2545683e85c2257b34f78460ed1006" integrity sha512-f3GYf/iEcZPxRARK6ufx0m9rQSpgnYcQFYUtM5uQs+oMTse9oSSk/pQ6Vru9mgIcxw3YiYVMjP/WsP5EgVABbw== -"@gitlab/ui@21.14.0": - version "21.14.0" - resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-21.14.0.tgz#1fb4e519fe25a1ae939f42f4e247251ff160f010" - integrity sha512-SO1ugNkNvfbrIXQhfPoQEPT7KL7gFK3JKJ+W4dIzlKKdu9vp1VAbAV6hpe+FWzaNhyW0xB3dKfL5vFP3pQAeCQ== +"@gitlab/ui@21.16.0": + version "21.16.0" + resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-21.16.0.tgz#7fd11e96363c480724da1dcf0f17ab77f937cacc" + integrity sha512-SuKxCJksBHcz8omjtxbCjYBDN6rgyBuhoccF/FBEUSS88VHGR1uVMuAZ6crz5k2OxZz2x4s71sIaJA9Sa6axog== dependencies: "@babel/standalone" "^7.0.0" "@gitlab/vue-toasted" "^1.3.0" |