diff options
50 files changed, 315 insertions, 462 deletions
diff --git a/.rubocop.yml b/.rubocop.yml index dd43221d20e..571946be462 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -837,8 +837,6 @@ Rails/SaveBang: Include: - 'spec/**/*.rb' - 'ee/spec/**/*.rb' - - 'qa/spec/**/*.rb' - - 'qa/qa/specs/**/*.rb' Exclude: - spec/models/wiki_page/**/* - spec/models/wiki_page_spec.rb diff --git a/.rubocop_todo/rspec/feature_category.yml b/.rubocop_todo/rspec/feature_category.yml index 1ae169a437a..aed72849075 100644 --- a/.rubocop_todo/rspec/feature_category.yml +++ b/.rubocop_todo/rspec/feature_category.yml @@ -1688,7 +1688,6 @@ RSpec/FeatureCategory: - 'spec/dependencies/omniauth_saml_spec.rb' - 'spec/docs_screenshots/container_registry_docs.rb' - 'spec/docs_screenshots/wiki_docs.rb' - - 'spec/experiments/in_product_guidance_environments_webide_experiment_spec.rb' - 'spec/features/admin/dashboard_spec.rb' - 'spec/features/groups/integrations/group_integrations_spec.rb' - 'spec/features/milestones/user_views_milestones_spec.rb' diff --git a/.rubocop_todo/rspec/named_subject.yml b/.rubocop_todo/rspec/named_subject.yml index 2c77a52579c..02da5b59f7f 100644 --- a/.rubocop_todo/rspec/named_subject.yml +++ b/.rubocop_todo/rspec/named_subject.yml @@ -1412,7 +1412,6 @@ RSpec/NamedSubject: - 'spec/controllers/uploads_controller_spec.rb' - 'spec/controllers/users/callouts_controller_spec.rb' - 'spec/experiments/application_experiment_spec.rb' - - 'spec/experiments/in_product_guidance_environments_webide_experiment_spec.rb' - 'spec/features/admin/users/admin_impersonates_user_spec.rb' - 'spec/features/groups/clusters/user_spec.rb' - 'spec/features/merge_request/user_sees_merge_widget_spec.rb' diff --git a/GITLAB_PAGES_VERSION b/GITLAB_PAGES_VERSION index f02cef6123f..3fdecc0cc06 100644 --- a/GITLAB_PAGES_VERSION +++ b/GITLAB_PAGES_VERSION @@ -1 +1 @@ -bf6cd6ddf529f8958adee206ac0f93953e9ac39c +852bde8a974154b34f8c3f0bbf42014e69f5a240 diff --git a/app/assets/javascripts/groups/components/app.vue b/app/assets/javascripts/groups/components/app.vue index 3440bd87e6b..4ede8fda01d 100644 --- a/app/assets/javascripts/groups/components/app.vue +++ b/app/assets/javascripts/groups/components/app.vue @@ -22,6 +22,7 @@ export default { GlLoadingIcon, GlEmptyState, }, + inject: ['emptySearchIllustration'], props: { action: { type: String, @@ -245,6 +246,7 @@ export default { <groups-component v-if="hasGroups" :groups="groups" :page-info="pageInfo" :action="action" /> <gl-empty-state v-else-if="fromSearch" + :svg-path="emptySearchIllustration" :title="$options.i18n.searchEmptyState.title" :description="$options.i18n.searchEmptyState.description" data-testid="search-empty-state" diff --git a/app/assets/javascripts/groups/init_overview_tabs.js b/app/assets/javascripts/groups/init_overview_tabs.js index 80dd1d36734..2f03705b453 100644 --- a/app/assets/javascripts/groups/init_overview_tabs.js +++ b/app/assets/javascripts/groups/init_overview_tabs.js @@ -47,6 +47,7 @@ export const initGroupOverviewTabs = () => { newProjectIllustration, emptyProjectsIllustration, emptySubgroupIllustration, + emptySearchIllustration, canCreateSubgroups, canCreateProjects, currentGroupVisibility, @@ -67,6 +68,7 @@ export const initGroupOverviewTabs = () => { newProjectIllustration, emptyProjectsIllustration, emptySubgroupIllustration, + emptySearchIllustration, canCreateSubgroups: parseBoolean(canCreateSubgroups), canCreateProjects: parseBoolean(canCreateProjects), currentGroupVisibility, diff --git a/app/assets/javascripts/ide/components/file_alert.vue b/app/assets/javascripts/ide/components/file_alert.vue deleted file mode 100644 index 2a894596bf4..00000000000 --- a/app/assets/javascripts/ide/components/file_alert.vue +++ /dev/null @@ -1,26 +0,0 @@ -<script> -import { GlAlert } from '@gitlab/ui'; -import { getAlert } from '../lib/alerts'; - -export default { - components: { - GlAlert, - }, - props: { - alertKey: { - type: Symbol, - required: true, - }, - }, - computed: { - alert() { - return getAlert(this.alertKey); - }, - }, -}; -</script> -<template> - <gl-alert v-bind="alert.props" @dismiss="alert.dismiss($store)"> - <component :is="alert.message" /> - </gl-alert> -</template> diff --git a/app/assets/javascripts/ide/components/repo_editor.vue b/app/assets/javascripts/ide/components/repo_editor.vue index 8f4f777d396..d2375078820 100644 --- a/app/assets/javascripts/ide/components/repo_editor.vue +++ b/app/assets/javascripts/ide/components/repo_editor.vue @@ -1,6 +1,5 @@ <script> import { GlTabs, GlTab } from '@gitlab/ui'; -import { debounce } from 'lodash'; // eslint-disable-next-line no-restricted-imports import { mapState, mapGetters, mapActions } from 'vuex'; import { @@ -29,7 +28,7 @@ import { viewerInformationForPath } from '~/vue_shared/components/content_viewer import DiffViewer from '~/vue_shared/components/diff_viewer/diff_viewer.vue'; import { markRaw } from '~/lib/utils/vue3compat/mark_raw'; import { readFileAsDataURL } from '~/lib/utils/file_utility'; -import { isDefaultCiConfig, hasCiConfigExtension } from '~/lib/utils/common_utils'; +import { hasCiConfigExtension } from '~/lib/utils/common_utils'; import { leftSidebarViews, @@ -43,7 +42,6 @@ import mapRulesToMonaco from '../lib/editorconfig/rules_mapper'; import { getFileEditorOrDefault } from '../stores/modules/editor/utils'; import { extractMarkdownImagesFromEntries } from '../stores/utils'; import { getPathParent, registerSchema, isTextFile } from '../utils'; -import FileAlert from './file_alert.vue'; import FileTemplatesBar from './file_templates/bar.vue'; const MARKDOWN_FILE_TYPE = 'markdown'; @@ -53,7 +51,6 @@ export default { components: { GlTabs, GlTab, - FileAlert, ContentViewer, DiffViewer, FileTemplatesBar, @@ -93,7 +90,6 @@ export default { 'previewMarkdownPath', ]), ...mapGetters([ - 'getAlert', 'currentMergeRequest', 'getStagedFile', 'isEditModeActive', @@ -102,9 +98,6 @@ export default { 'getJsonSchemaForPath', ]), ...mapGetters('fileTemplates', ['showFileTemplatesBar']), - alertKey() { - return this.getAlert(this.file); - }, fileEditor() { return getFileEditorOrDefault(this.fileEditors, this.file.path); }, @@ -159,16 +152,6 @@ export default { }, }, watch: { - 'file.name': { - handler() { - this.stopWatchingCiYaml(); - - if (isDefaultCiConfig(this.file.name)) { - this.startWatchingCiYaml(); - } - }, - immediate: true, - }, file(newVal, oldVal) { if (oldVal.pending) { this.removePendingTab(oldVal); @@ -235,7 +218,6 @@ export default { 'removePendingTab', 'triggerFilesChange', 'addTempImage', - 'detectGitlabCiFileAlerts', ]), ...mapActions('editor', ['updateFileEditor']), initEditor() { @@ -498,18 +480,6 @@ export default { this.updateFileEditor({ path: this.file.path, data }); }, - startWatchingCiYaml() { - this.unwatchCiYaml = this.$watch( - 'file.content', - debounce(this.detectGitlabCiFileAlerts, 500), - ); - }, - stopWatchingCiYaml() { - if (this.unwatchCiYaml) { - this.unwatchCiYaml(); - this.unwatchCiYaml = null; - } - }, }, viewerTypes, FILE_VIEW_MODE_EDITOR, @@ -531,7 +501,6 @@ export default { @click="updateEditor({ viewMode: $options.FILE_VIEW_MODE_PREVIEW })" /> </gl-tabs> - <file-alert v-if="alertKey" :alert-key="alertKey" /> <file-templates-bar v-else-if="showFileTemplatesBar(file.name)" /> <div v-show="showEditor" diff --git a/app/assets/javascripts/ide/index.js b/app/assets/javascripts/ide/index.js index b09cd7f6643..51c7e69449b 100644 --- a/app/assets/javascripts/ide/index.js +++ b/app/assets/javascripts/ide/index.js @@ -70,7 +70,6 @@ export const initLegacyWebIDE = (el, options = {}) => { this.init({ renderWhitespaceInCode: parseBoolean(el.dataset.renderWhitespaceInCode), editorTheme: window.gon?.user_color_scheme || DEFAULT_THEME, - environmentsGuidanceAlertDismissed: !parseBoolean(el.dataset.enableEnvironmentsGuidance), previewMarkdownPath: el.dataset.previewMarkdownPath, userPreferencesPath: el.dataset.userPreferencesPath, }); diff --git a/app/assets/javascripts/ide/lib/alerts/environments.vue b/app/assets/javascripts/ide/lib/alerts/environments.vue deleted file mode 100644 index bfe101bc7e7..00000000000 --- a/app/assets/javascripts/ide/lib/alerts/environments.vue +++ /dev/null @@ -1,33 +0,0 @@ -<!-- eslint-disable vue/multi-word-component-names --> -<script> -import { GlSprintf, GlLink } from '@gitlab/ui'; -import { helpPagePath } from '~/helpers/help_page_helper'; -import { __ } from '~/locale'; - -export default { - components: { GlSprintf, GlLink }, - message: __( - "No deployments detected. Use environments to control your software's continuous deployment. %{linkStart}Learn more about deployment jobs.%{linkEnd}", - ), - computed: { - helpLink() { - return helpPagePath('ci/environments/index.md'); - }, - }, -}; -</script> -<template> - <span> - <gl-sprintf :message="$options.message"> - <template #link="{ content }"> - <gl-link - :href="helpLink" - target="_blank" - data-track-action="click_link" - data-track-experiment="in_product_guidance_environments_webide" - >{{ content }}</gl-link - > - </template> - </gl-sprintf> - </span> -</template> diff --git a/app/assets/javascripts/ide/lib/alerts/index.js b/app/assets/javascripts/ide/lib/alerts/index.js deleted file mode 100644 index ac4eeb0386f..00000000000 --- a/app/assets/javascripts/ide/lib/alerts/index.js +++ /dev/null @@ -1,21 +0,0 @@ -import { isDefaultCiConfig } from '~/lib/utils/common_utils'; -import { leftSidebarViews } from '../../constants'; -import EnvironmentsMessage from './environments.vue'; - -const alerts = [ - { - key: Symbol('ALERT_ENVIRONMENT'), - show: (state, file) => - state.currentActivityView === leftSidebarViews.commit.name && - isDefaultCiConfig(file.path) && - state.environmentsGuidanceAlertDetected && - !state.environmentsGuidanceAlertDismissed, - props: { variant: 'tip' }, - dismiss: ({ dispatch }) => dispatch('dismissEnvironmentsGuidance'), - message: EnvironmentsMessage, - }, -]; - -export const findAlertKeyToShow = (...args) => alerts.find((x) => x.show(...args))?.key; - -export const getAlert = (key) => alerts.find((x) => x.key === key); diff --git a/app/assets/javascripts/ide/services/index.js b/app/assets/javascripts/ide/services/index.js index 1f9bc834140..01e1fd50bcc 100644 --- a/app/assets/javascripts/ide/services/index.js +++ b/app/assets/javascripts/ide/services/index.js @@ -1,11 +1,9 @@ import Api from '~/api'; import getIdeProject from 'ee_else_ce/ide/queries/get_ide_project.query.graphql'; -import dismissUserCallout from '~/graphql_shared/mutations/dismiss_user_callout.mutation.graphql'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import axios from '~/lib/utils/axios_utils'; import { joinPaths, escapeFileUrl } from '~/lib/utils/url_utility'; -import ciConfig from '~/ci/pipeline_editor/graphql/queries/ci_config.query.graphql'; -import { query, mutate } from './gql'; +import { query } from './gql'; export default { getFileData(endpoint) { @@ -84,18 +82,6 @@ export default { const url = `${gon.relative_url_root}/${projectPath}/service_ping/web_ide_pipelines_count`; return axios.post(url); }, - getCiConfig(projectPath, content) { - return query({ - query: ciConfig, - variables: { projectPath, content }, - }).then(({ data }) => data.ciConfig); - }, - dismissUserCallout(name) { - return mutate({ - mutation: dismissUserCallout, - variables: { input: { featureName: name } }, - }).then(({ data }) => data); - }, getProjectPermissionsData(projectPath) { return query({ query: getIdeProject, diff --git a/app/assets/javascripts/ide/stores/actions.js b/app/assets/javascripts/ide/stores/actions.js index 0106eeae162..bb4b181c56d 100644 --- a/app/assets/javascripts/ide/stores/actions.js +++ b/app/assets/javascripts/ide/stores/actions.js @@ -311,4 +311,3 @@ export * from './actions/tree'; export * from './actions/file'; export * from './actions/project'; export * from './actions/merge_request'; -export * from './actions/alert'; diff --git a/app/assets/javascripts/ide/stores/actions/alert.js b/app/assets/javascripts/ide/stores/actions/alert.js deleted file mode 100644 index 4c33dc19520..00000000000 --- a/app/assets/javascripts/ide/stores/actions/alert.js +++ /dev/null @@ -1,18 +0,0 @@ -import service from '../../services'; -import { - DETECT_ENVIRONMENTS_GUIDANCE_ALERT, - DISMISS_ENVIRONMENTS_GUIDANCE_ALERT, -} from '../mutation_types'; - -export const detectGitlabCiFileAlerts = ({ dispatch }, content) => - dispatch('detectEnvironmentsGuidance', content); - -export const detectEnvironmentsGuidance = ({ commit, state }, content) => - service.getCiConfig(state.currentProjectId, content).then((data) => { - commit(DETECT_ENVIRONMENTS_GUIDANCE_ALERT, data?.stages); - }); - -export const dismissEnvironmentsGuidance = ({ commit }) => - service.dismissUserCallout('web_ide_ci_environments_guidance').then(() => { - commit(DISMISS_ENVIRONMENTS_GUIDANCE_ALERT); - }); diff --git a/app/assets/javascripts/ide/stores/getters.js b/app/assets/javascripts/ide/stores/getters.js index 74fe61b6e2f..0f4dbb56e04 100644 --- a/app/assets/javascripts/ide/stores/getters.js +++ b/app/assets/javascripts/ide/stores/getters.js @@ -260,5 +260,3 @@ export const getJsonSchemaForPath = (state, getters) => (path) => { fileMatch: [`*${path}`], }; }; - -export * from './getters/alert'; diff --git a/app/assets/javascripts/ide/stores/getters/alert.js b/app/assets/javascripts/ide/stores/getters/alert.js deleted file mode 100644 index 714e2d89b4f..00000000000 --- a/app/assets/javascripts/ide/stores/getters/alert.js +++ /dev/null @@ -1,3 +0,0 @@ -import { findAlertKeyToShow } from '../../lib/alerts'; - -export const getAlert = (state) => (file) => findAlertKeyToShow(state, file); diff --git a/app/assets/javascripts/ide/stores/mutation_types.js b/app/assets/javascripts/ide/stores/mutation_types.js index 13f338c4a48..ae6588f948f 100644 --- a/app/assets/javascripts/ide/stores/mutation_types.js +++ b/app/assets/javascripts/ide/stores/mutation_types.js @@ -71,8 +71,3 @@ export const RENAME_ENTRY = 'RENAME_ENTRY'; export const REVERT_RENAME_ENTRY = 'REVERT_RENAME_ENTRY'; export const RESTORE_TREE = 'RESTORE_TREE'; - -// Alert mutation types - -export const DETECT_ENVIRONMENTS_GUIDANCE_ALERT = 'DETECT_ENVIRONMENTS_GUIDANCE_ALERT'; -export const DISMISS_ENVIRONMENTS_GUIDANCE_ALERT = 'DISMISS_ENVIRONMENTS_GUIDANCE_ALERT'; diff --git a/app/assets/javascripts/ide/stores/mutations.js b/app/assets/javascripts/ide/stores/mutations.js index d11fc388d5e..300d352f81c 100644 --- a/app/assets/javascripts/ide/stores/mutations.js +++ b/app/assets/javascripts/ide/stores/mutations.js @@ -1,6 +1,5 @@ import Vue from 'vue'; import * as types from './mutation_types'; -import alertMutations from './mutations/alert'; import branchMutations from './mutations/branch'; import fileMutations from './mutations/file'; import mergeRequestMutation from './mutations/merge_request'; @@ -247,5 +246,4 @@ export default { ...fileMutations, ...treeMutations, ...branchMutations, - ...alertMutations, }; diff --git a/app/assets/javascripts/ide/stores/mutations/alert.js b/app/assets/javascripts/ide/stores/mutations/alert.js deleted file mode 100644 index bb2d33a836b..00000000000 --- a/app/assets/javascripts/ide/stores/mutations/alert.js +++ /dev/null @@ -1,21 +0,0 @@ -import { - DETECT_ENVIRONMENTS_GUIDANCE_ALERT, - DISMISS_ENVIRONMENTS_GUIDANCE_ALERT, -} from '../mutation_types'; - -export default { - [DETECT_ENVIRONMENTS_GUIDANCE_ALERT](state, stages) { - if (!stages) { - return; - } - const hasEnvironments = stages?.nodes?.some((stage) => - stage.groups.nodes.some((group) => group.jobs.nodes.some((job) => job.environment)), - ); - const hasParsedCi = Array.isArray(stages.nodes); - - state.environmentsGuidanceAlertDetected = !hasEnvironments && hasParsedCi; - }, - [DISMISS_ENVIRONMENTS_GUIDANCE_ALERT](state) { - state.environmentsGuidanceAlertDismissed = true; - }, -}; diff --git a/app/assets/javascripts/ide/stores/state.js b/app/assets/javascripts/ide/stores/state.js index 356bbf28a48..6297231e252 100644 --- a/app/assets/javascripts/ide/stores/state.js +++ b/app/assets/javascripts/ide/stores/state.js @@ -28,8 +28,6 @@ export default () => ({ }, renderWhitespaceInCode: false, editorTheme: DEFAULT_THEME, - environmentsGuidanceAlertDismissed: false, - environmentsGuidanceAlertDetected: false, previewMarkdownPath: '', userPreferencesPath: '', }); diff --git a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue index 2607d8e4bb7..af7453d84d6 100644 --- a/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue +++ b/app/assets/javascripts/vue_merge_request_widget/components/states/ready_to_merge.vue @@ -281,10 +281,7 @@ export default { return __('Merge'); }, showAutoMergeHelperText() { - return ( - !(this.status === PIPELINE_FAILED_STATE || this.isPipelineFailed) && - this.isAutoMergeAvailable - ); + return this.isAutoMergeAvailable; }, hasPipelineMustSucceedConflict() { return !this.hasCI && this.state.onlyAllowMergeIfPipelineSucceeds; diff --git a/app/events/ci/job_artifacts_deleted_event.rb b/app/events/ci/job_artifacts_deleted_event.rb index 2972342cae6..4d85c0cfbee 100644 --- a/app/events/ci/job_artifacts_deleted_event.rb +++ b/app/events/ci/job_artifacts_deleted_event.rb @@ -9,8 +9,8 @@ module Ci 'properties' => { 'job_ids' => { 'type' => 'array', - 'properties' => { - 'job_id' => { 'type' => 'integer' } + 'items' => { + 'type' => 'integer' } } } diff --git a/app/experiments/in_product_guidance_environments_webide_experiment.rb b/app/experiments/in_product_guidance_environments_webide_experiment.rb deleted file mode 100644 index 78602874cb7..00000000000 --- a/app/experiments/in_product_guidance_environments_webide_experiment.rb +++ /dev/null @@ -1,13 +0,0 @@ -# frozen_string_literal: true - -class InProductGuidanceEnvironmentsWebideExperiment < ApplicationExperiment - control { false } - - exclude :has_environments? - - private - - def has_environments? - !context.project.environments.empty? - end -end diff --git a/app/helpers/groups_helper.rb b/app/helpers/groups_helper.rb index 8b5d05b6408..55857d40698 100644 --- a/app/helpers/groups_helper.rb +++ b/app/helpers/groups_helper.rb @@ -160,6 +160,7 @@ module GroupsHelper new_project_illustration: image_path('illustrations/project-create-new-sm.svg'), empty_projects_illustration: image_path('illustrations/empty-state/empty-projects-md.svg'), empty_subgroup_illustration: image_path('illustrations/empty-state/empty-subgroup-md.svg'), + empty_search_illustration: image_path('illustrations/empty-state/empty-search-md.svg'), render_empty_state: 'true', can_create_subgroups: can?(current_user, :create_subgroup, group).to_s, can_create_projects: can?(current_user, :create_projects, group).to_s diff --git a/app/helpers/ide_helper.rb b/app/helpers/ide_helper.rb index 2ec11b8a9ed..312807c004a 100644 --- a/app/helpers/ide_helper.rb +++ b/app/helpers/ide_helper.rb @@ -88,7 +88,6 @@ module IdeHelper 'render-whitespace-in-code': current_user.render_whitespace_in_code.to_s, 'default-branch' => project && project.default_branch, 'project' => convert_to_project_entity_json(project), - 'enable-environments-guidance' => enable_environments_guidance?(project).to_s, 'preview-markdown-path' => project && preview_markdown_path(project), 'web-terminal-svg-path' => image_path('illustrations/web-ide_promotion.svg'), 'web-terminal-help-path' => help_page_path('user/project/web_ide/index', anchor: 'interactive-web-terminals-for-the-web-ide'), @@ -103,14 +102,6 @@ module IdeHelper API::Entities::Project.represent(project, current_user: current_user).to_json end - def enable_environments_guidance?(project) - experiment(:in_product_guidance_environments_webide, project: project) do |e| - e.candidate { !has_dismissed_ide_environments_callout? } - - e.run - end - end - def has_dismissed_ide_environments_callout? current_user.dismissed_callout?(feature_name: 'web_ide_ci_environments_guidance') end diff --git a/config/feature_flags/development/compliance_pipeline_in_policies.yml b/config/feature_flags/development/compliance_pipeline_in_policies.yml index 97432fe2872..427f3dde4b4 100644 --- a/config/feature_flags/development/compliance_pipeline_in_policies.yml +++ b/config/feature_flags/development/compliance_pipeline_in_policies.yml @@ -5,4 +5,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/424185 milestone: '16.4' type: development group: group::security policies -default_enabled: false +default_enabled: true diff --git a/config/feature_flags/experiment/in_product_guidance_environments_webide.yml b/config/feature_flags/experiment/in_product_guidance_environments_webide.yml deleted file mode 100644 index 167a70747a0..00000000000 --- a/config/feature_flags/experiment/in_product_guidance_environments_webide.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -name: in_product_guidance_environments_webide -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/57160 -rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/330390 -milestone: '13.12' -type: experiment -group: group::environments -default_enabled: false diff --git a/doc/install/cloud_providers.md b/doc/install/cloud_providers.md index 407c2152569..ecec2250e11 100644 --- a/doc/install/cloud_providers.md +++ b/doc/install/cloud_providers.md @@ -5,7 +5,7 @@ description: AWS, Google Cloud Platform, Azure. info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments --- -# Installing GitLab on a cloud provider **(FREE SELF)** +# Install GitLab on a cloud provider **(FREE SELF)** You can install GitLab on several cloud providers. diff --git a/doc/topics/git/index.md b/doc/topics/git/index.md index b8740414faa..17321591e87 100644 --- a/doc/topics/git/index.md +++ b/doc/topics/git/index.md @@ -5,7 +5,7 @@ description: Common commands and workflows. info: "To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments" --- -# Use Git **(FREE ALL)** +# Learn Git **(FREE ALL)** Git is a [free and open source](https://git-scm.com/about/free-and-open-source) distributed version control system. It handles projects of all sizes quickly and diff --git a/doc/update/index.md b/doc/update/index.md index 2ad2ee58e9a..d62c4cf90f4 100644 --- a/doc/update/index.md +++ b/doc/update/index.md @@ -5,7 +5,7 @@ description: Latest version instructions. info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments --- -# Upgrading GitLab **(FREE SELF)** +# Upgrade GitLab **(FREE SELF)** Upgrading GitLab is a relatively straightforward process, but the complexity can increase based on the installation method you have used, how old your diff --git a/doc/user/application_security/policies/scan-execution-policies.md b/doc/user/application_security/policies/scan-execution-policies.md index de36cb30257..08477619894 100644 --- a/doc/user/application_security/policies/scan-execution-policies.md +++ b/doc/user/application_security/policies/scan-execution-policies.md @@ -337,10 +337,9 @@ These experimental features have limitations: > The `custom` scan action type was [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/126457) in GitLab 16.4 [with a flag](../../../administration/feature_flags.md) named `compliance_pipeline_in_policies`. FLAG: -On self-managed GitLab, by default this feature is not available. To make it available, -an administrator can [enable the feature flag](../../../administration/feature_flags.md) -named `compliance_pipeline_in_policies`. -On GitLab.com, this feature is not available. +On self-managed GitLab, by default this feature is available. +To hide the feature, an administrator can [disable the feature flag](../../../administration/feature_flags.md) named `compliance_pipeline_in_policies`. +On GitLab.com, this feature is available. The pipeline execution policy action introduces a new scan action type into scan execution policies for creating and enforcing custom CI in your target diff --git a/doc/user/infrastructure/index.md b/doc/user/infrastructure/index.md index 327b6743d01..6662f6a9dcb 100644 --- a/doc/user/infrastructure/index.md +++ b/doc/user/infrastructure/index.md @@ -5,7 +5,7 @@ description: Terraform and Kubernetes deployments. info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments --- -# Infrastructure management **(FREE ALL)** +# Manage your infrastructure **(FREE ALL)** With the rise of DevOps and SRE approaches, infrastructure management becomes codified, automatable, and software development best practices gain their place around infrastructure diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 36c98f8e6fd..55739eae24b 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -32375,9 +32375,6 @@ msgstr "" msgid "No data available" msgstr "" -msgid "No deployments detected. Use environments to control your software's continuous deployment. %{linkStart}Learn more about deployment jobs.%{linkEnd}" -msgstr "" - msgid "No deployments found" msgstr "" diff --git a/qa/qa/fixtures/files/one_b b/qa/qa/fixtures/files/one_b Binary files differnew file mode 100644 index 00000000000..ddd224c7520 --- /dev/null +++ b/qa/qa/fixtures/files/one_b diff --git a/qa/qa/page/alert/storage_limit.rb b/qa/qa/page/alert/storage_limit.rb new file mode 100644 index 00000000000..31f4bd249fb --- /dev/null +++ b/qa/qa/page/alert/storage_limit.rb @@ -0,0 +1,11 @@ +# frozen_string_literal: true + +module QA + module Page + module Alert + class StorageLimit < Chemlab::Page + element :storage_limit_message + end + end + end +end diff --git a/qa/qa/resource/group.rb b/qa/qa/resource/group.rb index c88cf4aca10..689570cde36 100644 --- a/qa/qa/resource/group.rb +++ b/qa/qa/resource/group.rb @@ -66,6 +66,24 @@ module QA end end + # Fabricate a Group using the UI from the Groups Dashboard page + # @param [String] group_name + # @return [Page::Group::New] + def fabricate_group!(group_name: nil) + Page::Main::Menu.perform(&:go_to_groups) + Page::Dashboard::Groups.perform do |groups| + groups.click_new_group + + Page::Group::New.perform do |group_new| + group_new.click_create_group + + group_new.set_path(group_name) + + group_new.create + end + end + end + def fabricate_via_api! resource_web_url(api_get) rescue ResourceNotFoundError diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/cells/demo2_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/cells/demo2_spec.rb new file mode 100644 index 00000000000..2ba368ff353 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/9_data_stores/cells/demo2_spec.rb @@ -0,0 +1,98 @@ +# frozen_string_literal: true + +# version of the login test that only runs against GDK +# implements functionality in https://gitlab.com/gitlab-org/gitlab/-/issues/415207 + +module QA + RSpec.describe 'Data Stores', :skip_live_env, :requires_admin, product_group: :tenant_scale do + describe 'Demo 2' do + let(:cell1_url) { ENV.fetch('CELL1_URL', 'http://gdk.test:3000/') } + let(:cell2_url) { ENV.fetch('CELL2_URL', 'http://gdk.test:3001/') } + let(:cell1_group_name) { "cell1-group-#{SecureRandom.hex(8)}" } + let(:cell2_group_name) { "cell2-group-#{SecureRandom.hex(8)}" } + + before do + ENV['PERSONAL_ACCESS_TOKENS_DISABLED'] = 'true' # force off creating by api so walk through demo + end + + it('walkthrough', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/434421', + only: { condition: -> { !Runtime::Env.running_in_ci? } } + ) do + # Sign in Cell 1 + Runtime::Scenario.define(:gitlab_address, cell1_url) + Flow::Login.sign_in + Page::Main::Menu.perform(&:go_to_groups) + # Create Group on Cell 1 + Resource::Group.new.fabricate_group!(group_name: cell1_group_name) + + # Cell 1 Group exists on Cell 1 + Page::Group::Show.perform do |group_show| + # Ensure that the group was actually created + group_show.wait_until(sleep_interval: 1) do + expect(group_show).to have_text(cell1_group_name) + end + end + + # Visit Cell 2 + page.visit cell2_url + Runtime::Scenario.define(:gitlab_address, cell2_url) + Page::Main::Menu.perform(&:go_to_groups) + + # Cell 1 group does not show + Page::Dashboard::Groups.perform do |group_dashboard| + group_dashboard.wait_until(sleep_interval: 1) do + expect(group_dashboard).not_to have_group(cell1_group_name) + end + end + + # Create Group on Cell 2 + Resource::Group.new.fabricate_group!(group_name: cell2_group_name) + + # Cell 2 Group exists on Cell 2 + Page::Group::Show.perform do |group_show| + # Ensure that the group was actually created + group_show.wait_until(sleep_interval: 1) do + expect(group_show).to have_text(cell2_group_name) + end + end + + # Visit Cell 1 + page.visit cell1_url + Page::Main::Menu.perform(&:go_to_groups) + + # Cell 1 group appears + Page::Dashboard::Groups.perform do |group_dashboard| + group_dashboard.wait_until(sleep_interval: 1) do + expect(group_dashboard).to have_group(cell1_group_name) + end + end + + # Cell 2 group does not appear + Page::Dashboard::Groups.perform do |group_dashboard| + group_dashboard.wait_until(sleep_interval: 1) do + expect(group_dashboard).not_to have_group(cell2_group_name) + end + end + + # Visit Cell 2 + page.visit cell2_url + Page::Main::Menu.perform(&:go_to_groups) + + # Cell 1 group does not shows + Page::Dashboard::Groups.perform do |group_dashboard| + group_dashboard.wait_until(sleep_interval: 1) do + expect(group_dashboard).not_to have_group(cell1_group_name) + end + end + + # Cell 2 group does show + Page::Dashboard::Groups.perform do |group_dashboard| + group_dashboard.wait_until(sleep_interval: 1) do + expect(group_dashboard).to have_group(cell2_group_name) + end + end + end + end + end +end diff --git a/qa/qa/specs/features/browser_ui/9_data_stores/cells/demo3_spec.rb b/qa/qa/specs/features/browser_ui/9_data_stores/cells/demo3_spec.rb new file mode 100644 index 00000000000..ee6fe03f935 --- /dev/null +++ b/qa/qa/specs/features/browser_ui/9_data_stores/cells/demo3_spec.rb @@ -0,0 +1,150 @@ +# frozen_string_literal: true + +# version of the login test that only runs against GDK +# implements functionality in https://gitlab.com/gitlab-org/gitlab/-/issues/420118 + +module QA + RSpec.describe 'Data Stores', :skip_live_env, :requires_admin, product_group: :tenant_scale do + describe 'Demo 3' do + let(:debug) { false } + let(:cell1_url) { ENV.fetch('CELL1_URL', 'http://gdk.test:3000/') } + let(:cell2_url) { ENV.fetch('CELL2_URL', 'http://gdk.test:3001/') } + let(:cell1_group_name) { "cell1-group-#{SecureRandom.hex(8)}" } + let(:cell2_group_name) { "cell2-group-#{SecureRandom.hex(8)}" } + let(:cell1_project_name) { "cell1-project-#{SecureRandom.hex(8)}" } + let(:cell2_project_name) { "cell2-project-#{SecureRandom.hex(8)}" } + + def create_group(name) + Resource::Group.new.fabricate_group!(group_name: name) + + Page::Group::Show.perform do |group_show| + # Ensure that the group was actually created + group_show.wait_until(sleep_interval: 1) do + expect(group_show).to have_text(name) + end + end + end + + def create_project(group_name, project_name) + Page::Main::Menu.perform(&:go_to_create_project) + Page::Project::New.perform(&:click_blank_project_link) + Page::Project::New.perform do |project_page| + project_page.choose_namespace(group_name) + project_page.choose_name(project_name) + project_page.create_new_project + end + end + + it('walkthrough', + testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/434422', + only: { condition: -> { !Runtime::Env.running_in_ci? } } + ) do + Runtime::Scenario.define(:gitlab_address, cell1_url) + # Sign in Cell 1 + Flow::Login.sign_in + Page::Main::Menu.perform(&:go_to_groups) + # Create Group on Cell 1 + create_group(cell1_group_name) + + # Create a Project in that group on Cell 1 + create_project(cell1_group_name, cell1_project_name) + + # Cell 1 Project shows + page.visit "#{cell1_url}#{cell1_group_name}/#{cell1_project_name}" + Page::Project::Show.perform do |project| + expect(project.has_name?(cell1_project_name)).to be true + end + + # Visit Cell 2 + page.visit cell2_url + Page::Main::Menu.perform(&:go_to_groups) + + # Cell 1 group does not show + Page::Dashboard::Groups.perform do |group_dashboard| + group_dashboard.wait_until(sleep_interval: 1) do + expect(group_dashboard.has_group?(cell1_group_name)).to be(false) + end + end + + # Cell 1 project does not show + page.visit "#{cell2_url}#{cell1_group_name}/#{cell1_project_name}" + expect(page).to have_text('Page Not Found') + + page.visit cell2_url + Page::Main::Menu.perform(&:go_to_groups) + # Create Group on Cell 2 + create_group(cell2_group_name) + + # Create a Project in that group on Cell 2 + # TODO: this functionality is under development, uncomment when complete + # create_project(cell2_group_name,cell2_project_name) + + # Cell 2 Project shows + # page.visit "#{cell2_url}#{cell2_group_name}/#{cell2_project_name}" + # Page::Project::Show.perform do |project| + # expect(project.has_name?(cell2_project_name)).to be true + # end + + # Visit Cell 1 + page.visit cell1_url + Page::Main::Menu.perform(&:go_to_groups) + + # Cell 1 group does shows + Page::Dashboard::Groups.perform do |group_dashboard| + group_dashboard.wait_until(sleep_interval: 1) do + expect(group_dashboard).to have_group(cell1_group_name) + end + end + + # Cell 1 Project shows + page.visit "#{cell1_url}#{cell1_group_name}/#{cell1_project_name}" + Page::Project::Show.perform do |project| + expect(project).to have_name(cell1_project_name) + end + + # Cell 2 group does not shows + # TODO: this functionality is under development, uncomment when complete + # Page::Dashboard::Groups.perform do |group_dashboard| + # group_dashboard.wait_until(sleep_interval: 1) do + # expect(group_dashboard.has_group?(cell2_group_name)).to be(false) + # end + # end + + # Cell 2 Project does not show + page.visit "#{cell1_url}#{cell2_group_name}/#{cell2_project_name}" + expect(page).to have_text('Page Not Found') + + # Visit Cell 2 + page.visit cell2_url + Page::Main::Menu.perform(&:go_to_groups) + + # Cell 1 group does not shows + Page::Dashboard::Groups.perform do |group_dashboard| + group_dashboard.wait_until(sleep_interval: 1) do + expect(group_dashboard).not_to have_group(cell1_group_name) + end + end + + # Cell 1 project does not show + page.visit "#{cell2_url}#{cell1_group_name}/#{cell1_project_name}" + expect(page).to have_text('Page Not Found') + + # Cell 2 group does show + page.visit cell2_url + Page::Main::Menu.perform(&:go_to_groups) + Page::Dashboard::Groups.perform do |group_dashboard| + group_dashboard.wait_until(sleep_interval: 1) do + expect(group_dashboard).to have_group(cell2_group_name) + end + end + + # Cell 2 project does show + # TODO: this functionality is under development, uncomment when complete + # page.visit "#{cell2_url}#{cell2_group_name}/#{cell2_project_name}" + # Page::Project::Show.perform do |project| + # expect(project.has_name?(cell2_project_name)).to be true + # end + end + end + end +end diff --git a/spec/experiments/in_product_guidance_environments_webide_experiment_spec.rb b/spec/experiments/in_product_guidance_environments_webide_experiment_spec.rb deleted file mode 100644 index d616672173e..00000000000 --- a/spec/experiments/in_product_guidance_environments_webide_experiment_spec.rb +++ /dev/null @@ -1,22 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe InProductGuidanceEnvironmentsWebideExperiment, :experiment do - subject { described_class.new(project: project) } - - let(:project) { create(:project, :repository) } - - before do - stub_experiments(in_product_guidance_environments_webide: :candidate) - end - - it 'excludes projects with environments' do - create(:environment, project: project) - expect(subject).to exclude(project: project) - end - - it 'does not exlude projects without environments' do - expect(subject).not_to exclude(project: project) - end -end diff --git a/spec/frontend/groups/components/app_spec.js b/spec/frontend/groups/components/app_spec.js index 8ac410c87b1..027c1709e0b 100644 --- a/spec/frontend/groups/components/app_spec.js +++ b/spec/frontend/groups/components/app_spec.js @@ -58,6 +58,9 @@ describe('AppComponent', () => { mocks: { $toast, }, + provide: { + emptySearchIllustration: '/assets/illustrations/empty-state/empty-search-md.svg', + }, }); vm = wrapper.vm; }; diff --git a/spec/frontend/groups/components/overview_tabs_spec.js b/spec/frontend/groups/components/overview_tabs_spec.js index 6bed744685f..0ca59e9c6bf 100644 --- a/spec/frontend/groups/components/overview_tabs_spec.js +++ b/spec/frontend/groups/components/overview_tabs_spec.js @@ -44,6 +44,7 @@ describe('OverviewTabs', () => { newProjectIllustration: '', emptyProjectsIllustration: '', emptySubgroupIllustration: '', + emptySearchIllustration: '', canCreateSubgroups: false, canCreateProjects: false, initialSort: 'name_asc', diff --git a/spec/frontend/ide/lib/alerts/environment_spec.js b/spec/frontend/ide/lib/alerts/environment_spec.js deleted file mode 100644 index d645209345c..00000000000 --- a/spec/frontend/ide/lib/alerts/environment_spec.js +++ /dev/null @@ -1,21 +0,0 @@ -import { GlLink } from '@gitlab/ui'; -import { mount } from '@vue/test-utils'; -import Environments from '~/ide/lib/alerts/environments.vue'; - -describe('~/ide/lib/alerts/environment.vue', () => { - let wrapper; - - beforeEach(() => { - wrapper = mount(Environments); - }); - - it('shows a message regarding environments', () => { - expect(wrapper.text()).toBe( - "No deployments detected. Use environments to control your software's continuous deployment. Learn more about deployment jobs.", - ); - }); - - it('links to the help page on environments', () => { - expect(wrapper.findComponent(GlLink).attributes('href')).toBe('/help/ci/environments/index.md'); - }); -}); diff --git a/spec/frontend/ide/services/index_spec.js b/spec/frontend/ide/services/index_spec.js index cd099e60070..8e63b5801e8 100644 --- a/spec/frontend/ide/services/index_spec.js +++ b/spec/frontend/ide/services/index_spec.js @@ -2,12 +2,10 @@ import axios from 'axios'; import MockAdapter from 'axios-mock-adapter'; import getIdeProject from 'ee_else_ce/ide/queries/get_ide_project.query.graphql'; import Api from '~/api'; -import dismissUserCallout from '~/graphql_shared/mutations/dismiss_user_callout.mutation.graphql'; import services from '~/ide/services'; -import { query, mutate } from '~/ide/services/gql'; +import { query } from '~/ide/services/gql'; import { HTTP_STATUS_OK } from '~/lib/utils/http_status'; import { escapeFileUrl } from '~/lib/utils/url_utility'; -import ciConfig from '~/ci/pipeline_editor/graphql/queries/ci_config.query.graphql'; import { projectData } from '../mock_data'; jest.mock('~/api'); @@ -276,35 +274,6 @@ describe('IDE services', () => { }); }); }); - describe('getCiConfig', () => { - const TEST_PROJECT_PATH = 'foo/bar'; - const TEST_CI_CONFIG = 'test config'; - - it('queries with the given CI config and project', () => { - const result = { data: { ciConfig: { test: 'data' } } }; - query.mockResolvedValue(result); - return services.getCiConfig(TEST_PROJECT_PATH, TEST_CI_CONFIG).then((data) => { - expect(data).toEqual(result.data.ciConfig); - expect(query).toHaveBeenCalledWith({ - query: ciConfig, - variables: { projectPath: TEST_PROJECT_PATH, content: TEST_CI_CONFIG }, - }); - }); - }); - }); - describe('dismissUserCallout', () => { - it('mutates the callout to dismiss', () => { - const result = { data: { callouts: { test: 'data' } } }; - mutate.mockResolvedValue(result); - return services.dismissUserCallout('test').then((data) => { - expect(data).toEqual(result.data); - expect(mutate).toHaveBeenCalledWith({ - mutation: dismissUserCallout, - variables: { input: { featureName: 'test' } }, - }); - }); - }); - }); describe('getProjectPermissionsData', () => { const TEST_PROJECT_PATH = 'foo/bar'; diff --git a/spec/frontend/ide/stores/actions/alert_spec.js b/spec/frontend/ide/stores/actions/alert_spec.js deleted file mode 100644 index 1321c402ebb..00000000000 --- a/spec/frontend/ide/stores/actions/alert_spec.js +++ /dev/null @@ -1,46 +0,0 @@ -import testAction from 'helpers/vuex_action_helper'; -import service from '~/ide/services'; -import { - detectEnvironmentsGuidance, - dismissEnvironmentsGuidance, -} from '~/ide/stores/actions/alert'; -import * as types from '~/ide/stores/mutation_types'; - -jest.mock('~/ide/services'); - -describe('~/ide/stores/actions/alert', () => { - describe('detectEnvironmentsGuidance', () => { - it('should try to fetch CI info', () => { - const stages = ['a', 'b', 'c']; - service.getCiConfig.mockResolvedValue({ stages }); - - return testAction( - detectEnvironmentsGuidance, - 'the content', - { currentProjectId: 'gitlab/test' }, - [{ type: types.DETECT_ENVIRONMENTS_GUIDANCE_ALERT, payload: stages }], - [], - () => expect(service.getCiConfig).toHaveBeenCalledWith('gitlab/test', 'the content'), - ); - }); - }); - describe('dismissCallout', () => { - it('should try to dismiss the given callout', () => { - const callout = { featureName: 'test', dismissedAt: 'now' }; - - service.dismissUserCallout.mockResolvedValue({ userCalloutCreate: { userCallout: callout } }); - - return testAction( - dismissEnvironmentsGuidance, - undefined, - {}, - [{ type: types.DISMISS_ENVIRONMENTS_GUIDANCE_ALERT }], - [], - () => - expect(service.dismissUserCallout).toHaveBeenCalledWith( - 'web_ide_ci_environments_guidance', - ), - ); - }); - }); -}); diff --git a/spec/frontend/ide/stores/getters/alert_spec.js b/spec/frontend/ide/stores/getters/alert_spec.js deleted file mode 100644 index 7068b8e637f..00000000000 --- a/spec/frontend/ide/stores/getters/alert_spec.js +++ /dev/null @@ -1,46 +0,0 @@ -import { getAlert } from '~/ide/lib/alerts'; -import EnvironmentsMessage from '~/ide/lib/alerts/environments.vue'; -import { createStore } from '~/ide/stores'; -import * as getters from '~/ide/stores/getters/alert'; -import { file } from '../../helpers'; - -describe('IDE store alert getters', () => { - let localState; - let localStore; - - beforeEach(() => { - localStore = createStore(); - localState = localStore.state; - }); - - describe('alerts', () => { - describe('shows an alert about environments', () => { - let alert; - - beforeEach(() => { - const f = file('.gitlab-ci.yml'); - localState.openFiles.push(f); - localState.currentActivityView = 'repo-commit-section'; - localState.environmentsGuidanceAlertDetected = true; - localState.environmentsGuidanceAlertDismissed = false; - - const alertKey = getters.getAlert(localState)(f); - alert = getAlert(alertKey); - }); - - it('has a message suggesting to use environments', () => { - expect(alert.message).toEqual(EnvironmentsMessage); - }); - - it('dispatches to dismiss the callout on dismiss', () => { - jest.spyOn(localStore, 'dispatch').mockImplementation(); - alert.dismiss(localStore); - expect(localStore.dispatch).toHaveBeenCalledWith('dismissEnvironmentsGuidance'); - }); - - it('should be a tip alert', () => { - expect(alert.props).toEqual({ variant: 'tip' }); - }); - }); - }); -}); diff --git a/spec/frontend/ide/stores/mutations/alert_spec.js b/spec/frontend/ide/stores/mutations/alert_spec.js deleted file mode 100644 index 2840ec4ebb7..00000000000 --- a/spec/frontend/ide/stores/mutations/alert_spec.js +++ /dev/null @@ -1,26 +0,0 @@ -import * as types from '~/ide/stores/mutation_types'; -import mutations from '~/ide/stores/mutations/alert'; - -describe('~/ide/stores/mutations/alert', () => { - const state = {}; - - describe(types.DETECT_ENVIRONMENTS_GUIDANCE_ALERT, () => { - it('checks the stages for any that configure environments', () => { - mutations[types.DETECT_ENVIRONMENTS_GUIDANCE_ALERT](state, { - nodes: [{ groups: { nodes: [{ jobs: { nodes: [{}] } }] } }], - }); - expect(state.environmentsGuidanceAlertDetected).toBe(true); - mutations[types.DETECT_ENVIRONMENTS_GUIDANCE_ALERT](state, { - nodes: [{ groups: { nodes: [{ jobs: { nodes: [{ environment: {} }] } }] } }], - }); - expect(state.environmentsGuidanceAlertDetected).toBe(false); - }); - }); - - describe(types.DISMISS_ENVIRONMENTS_GUIDANCE_ALERT, () => { - it('stops environments guidance', () => { - mutations[types.DISMISS_ENVIRONMENTS_GUIDANCE_ALERT](state); - expect(state.environmentsGuidanceAlertDismissed).toBe(true); - }); - }); -}); diff --git a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_ready_to_merge_spec.js b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_ready_to_merge_spec.js index adbf4e1d371..c9cc34e2cfc 100644 --- a/spec/frontend/vue_merge_request_widget/components/states/mr_widget_ready_to_merge_spec.js +++ b/spec/frontend/vue_merge_request_widget/components/states/mr_widget_ready_to_merge_spec.js @@ -212,6 +212,19 @@ describe('ReadyToMerge', () => { expect(findMergeButton().text()).toBe('Set to auto-merge'); expect(findMergeHelperText().text()).toBe('Merge when pipeline succeeds'); }); + + it('should show merge help text when pipeline has failed and has an auto merge strategy', () => { + createComponent({ + mr: { + pipeline: { status: 'FAILED' }, + availableAutoMergeStrategies: MWPS_MERGE_STRATEGY, + hasCI: true, + }, + }); + + expect(findMergeButton().text()).toBe('Set to auto-merge'); + expect(findMergeHelperText().text()).toBe('Merge when pipeline succeeds'); + }); }); describe('merge immediately dropdown', () => { diff --git a/spec/helpers/groups_helper_spec.rb b/spec/helpers/groups_helper_spec.rb index 5f192701b33..807898884a1 100644 --- a/spec/helpers/groups_helper_spec.rb +++ b/spec/helpers/groups_helper_spec.rb @@ -490,6 +490,7 @@ RSpec.describe GroupsHelper, feature_category: :groups_and_projects do new_project_illustration: including('illustrations/project-create-new-sm'), empty_projects_illustration: including('illustrations/empty-state/empty-projects-md'), empty_subgroup_illustration: including('illustrations/empty-state/empty-subgroup-md'), + empty_search_illustration: including('illustrations/empty-state/empty-search-md'), render_empty_state: 'true', can_create_subgroups: 'true', can_create_projects: 'true' diff --git a/spec/helpers/ide_helper_spec.rb b/spec/helpers/ide_helper_spec.rb index d5d7f8f72b3..99ef0998fda 100644 --- a/spec/helpers/ide_helper_spec.rb +++ b/spec/helpers/ide_helper_spec.rb @@ -61,39 +61,6 @@ RSpec.describe IdeHelper, feature_category: :web_ide do end end - context 'with environments guidance experiment', :experiment do - before do - stub_experiments(in_product_guidance_environments_webide: :candidate) - end - - context 'when project has no enviornments' do - it 'enables environment guidance' do - expect(helper.ide_data(project: project, fork_info: fork_info, params: params)) - .to include('enable-environments-guidance' => 'true') - end - - context 'and the callout has been dismissed' do - it 'disables environment guidance' do - callout = create(:callout, feature_name: :web_ide_ci_environments_guidance, user: user) - callout.update!(dismissed_at: Time.now - 1.week) - allow(helper).to receive(:current_user).and_return(User.find(user.id)) - - expect(helper.ide_data(project: project, fork_info: fork_info, params: params)) - .to include('enable-environments-guidance' => 'false') - end - end - end - - context 'when the project has environments' do - it 'disables environment guidance' do - create(:environment, project: project) - - expect(helper.ide_data(project: project, fork_info: fork_info, params: params)) - .to include('enable-environments-guidance' => 'false') - end - end - end - context 'with vscode_web_ide=true' do let(:base_data) do { diff --git a/spec/support/rspec_order_todo.yml b/spec/support/rspec_order_todo.yml index cb6cffd064f..b93442a87a9 100644 --- a/spec/support/rspec_order_todo.yml +++ b/spec/support/rspec_order_todo.yml @@ -3338,7 +3338,6 @@ - './spec/db/schema_spec.rb' - './spec/dependencies/omniauth_saml_spec.rb' - './spec/experiments/application_experiment_spec.rb' -- './spec/experiments/in_product_guidance_environments_webide_experiment_spec.rb' - './spec/features/abuse_report_spec.rb' - './spec/features/action_cable_logging_spec.rb' - './spec/features/admin/admin_abuse_reports_spec.rb' |