Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2025-01-21 16:41:13 +00:00
parent 04f4e68f19
commit a12e6607e2
52 changed files with 190 additions and 392 deletions

View File

@ -1234,7 +1234,6 @@ RSpec/FeatureCategory:
- 'spec/controllers/projects/releases/evidences_controller_spec.rb'
- 'spec/controllers/projects/releases_controller_spec.rb'
- 'spec/controllers/projects/security/configuration_controller_spec.rb'
- 'spec/controllers/projects/service_ping_controller_spec.rb'
- 'spec/controllers/projects/settings/merge_requests_controller_spec.rb'
- 'spec/controllers/projects/snippets/blobs_controller_spec.rb'
- 'spec/controllers/projects/snippets_controller_spec.rb'
@ -3044,7 +3043,6 @@ RSpec/FeatureCategory:
- 'spec/lib/gitlab/usage_data_counters/merge_request_widget_extension_counter_spec.rb'
- 'spec/lib/gitlab/usage_data_counters/quick_action_activity_unique_counter_spec.rb'
- 'spec/lib/gitlab/usage_data_counters/vscode_extension_activity_unique_counter_spec.rb'
- 'spec/lib/gitlab/usage_data_counters/web_ide_counter_spec.rb'
- 'spec/lib/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb'
- 'spec/lib/gitlab/usage_data_counters_spec.rb'
- 'spec/lib/gitlab/usage_data_non_sql_metrics_spec.rb'

View File

@ -189,7 +189,6 @@ Style/ClassAndModuleChildren:
- 'app/controllers/projects/runner_projects_controller.rb'
- 'app/controllers/projects/runners_controller.rb'
- 'app/controllers/projects/service_desk_controller.rb'
- 'app/controllers/projects/service_ping_controller.rb'
- 'app/controllers/projects/snippets/application_controller.rb'
- 'app/controllers/projects/snippets/blobs_controller.rb'
- 'app/controllers/projects/snippets_controller.rb'

View File

@ -7,7 +7,6 @@ Style/SendWithLiteralMethodName:
- 'lib/sidebars/context.rb'
- 'spec/lib/api/entities/ci/runner_manager_spec.rb'
- 'spec/lib/gitlab/ci/config/entry/retry_spec.rb'
- 'spec/lib/gitlab/usage_data_counters/web_ide_counter_spec.rb'
- 'spec/policies/project_policy_spec.rb'
- 'spec/support/helpers/javascript_fixtures_helpers.rb'
- 'spec/support/shared_examples/quick_actions/issuable/close_quick_action_shared_examples.rb'

View File

@ -34,7 +34,7 @@ export default {
return this.searchType === SEARCH_TYPE_ADVANCED;
},
shouldShowAuthorFilter() {
return this.isAdvancedSearch && this.glFeatures.searchMrFilterAuthor;
return this.isAdvancedSearch;
},
},
};

View File

@ -5,7 +5,6 @@ import dateFormat from '~/lib/dateformat';
import { formatDate, getDayDifference, fallsBefore } from '~/lib/utils/datetime_utility';
import { localeDateFormat } from '~/lib/utils/datetime/locale_dateformat';
import timeagoMixin from '~/vue_shared/mixins/timeago';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { INSTRUMENT_TODO_ITEM_FOLLOW, TODO_STATE_DONE } from '../constants';
import TodoItemTitle from './todo_item_title.vue';
import TodoItemBody from './todo_item_body.vue';
@ -28,7 +27,7 @@ export default {
TodoItemActions,
TodoItemTitleHiddenBySaml,
},
mixins: [timeagoMixin, glFeatureFlagMixin()],
mixins: [timeagoMixin],
inject: ['currentTab'],
props: {
currentUserId: {
@ -51,7 +50,7 @@ export default {
return this.todo.state === TODO_STATE_DONE;
},
isSnoozed() {
if (!this.glFeatures.todosSnoozing || this.todo.snoozedUntil == null) {
if (this.todo.snoozedUntil == null) {
return false;
}
@ -59,9 +58,6 @@ export default {
return !fallsBefore(snoozedUntil, new Date());
},
hasReachedSnoozeTimestamp() {
if (!this.glFeatures.todosSnoozing) {
return false;
}
return this.todo.snoozedUntil != null && !this.isSnoozed;
},
targetUrl() {

View File

@ -3,7 +3,6 @@ import { GlButton, GlTooltipDirective } from '@gitlab/ui';
import { reportToSentry } from '~/ci/utils';
import { s__ } from '~/locale';
import Tracking from '~/tracking';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { INSTRUMENT_TODO_ITEM_CLICK, TODO_STATE_DONE, TODO_STATE_PENDING } from '../constants';
import markAsDoneMutation from './mutations/mark_as_done.mutation.graphql';
import markAsPendingMutation from './mutations/mark_as_pending.mutation.graphql';
@ -17,7 +16,7 @@ export default {
directives: {
GlTooltip: GlTooltipDirective,
},
mixins: [Tracking.mixin(), glFeatureFlagMixin()],
mixins: [Tracking.mixin()],
props: {
todo: {
type: Object,
@ -30,9 +29,6 @@ export default {
},
computed: {
showToggleSnoozed() {
if (!this.glFeatures.todosSnoozing) {
return false;
}
return (!this.isSnoozed && this.isPending) || this.isSnoozed;
},
isDone() {
@ -113,7 +109,6 @@ export default {
<template>
<div class="gl-flex gl-gap-2">
<toggle-snoozed-status
v-if="glFeatures.todosSnoozing"
:todo="todo"
:is-snoozed="isSnoozed"
:is-pending="isPending"

View File

@ -13,14 +13,13 @@ import * as Sentry from '~/sentry/sentry_browser_wrapper';
import { createAlert } from '~/alert';
import { s__ } from '~/locale';
import Tracking from '~/tracking';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import {
DEFAULT_PAGE_SIZE,
getInstrumentTabLabels,
INSTRUMENT_TAB_LABELS,
INSTRUMENT_TODO_FILTER_CHANGE,
getStatusByTab,
STATUS_BY_TAB,
TODO_WAIT_BEFORE_RELOAD,
getTabsIndices,
TABS_INDICES,
} from '~/todos/constants';
import getTodosQuery from './queries/get_todos.query.graphql';
import getPendingTodosCount from './queries/get_pending_todos_count.query.graphql';
@ -47,7 +46,7 @@ export default {
directives: {
GlTooltip: GlTooltipDirective,
},
mixins: [Tracking.mixin(), glFeatureFlagMixin()],
mixins: [Tracking.mixin()],
provide() {
return {
currentTab: computed(() => this.currentTab),
@ -67,7 +66,7 @@ export default {
currentUserId: null,
pageInfo: {},
todos: [],
currentTab: getTabsIndices().pending,
currentTab: TABS_INDICES.pending,
pendingTodosCount: '-',
queryFilterValues: {
groupId: [],
@ -122,7 +121,7 @@ export default {
},
computed: {
statusByTab() {
return getStatusByTab()[this.currentTab];
return STATUS_BY_TAB[this.currentTab];
},
isLoading() {
return this.$apollo.queries.todos.loading;
@ -133,13 +132,13 @@ export default {
return Object.values(filters).some((value) => value.length > 0);
},
isOnSnoozedTab() {
return this.glFeatures.todosSnoozing && this.currentTab === getTabsIndices().snoozed;
return this.currentTab === TABS_INDICES.snoozed;
},
showEmptyState() {
return !this.isLoading && this.todos.length === 0;
},
showMarkAllAsDone() {
return this.currentTab === getTabsIndices().pending && !this.showEmptyState;
return this.currentTab === TABS_INDICES.pending && !this.showEmptyState;
},
},
created() {
@ -147,13 +146,13 @@ export default {
const stateFromUrl = searchParams.get('state');
switch (stateFromUrl) {
case 'snoozed':
this.currentTab = getTabsIndices().snoozed;
this.currentTab = TABS_INDICES.snoozed;
break;
case 'done':
this.currentTab = getTabsIndices().done;
this.currentTab = TABS_INDICES.done;
break;
case 'all':
this.currentTab = getTabsIndices().all;
this.currentTab = TABS_INDICES.all;
break;
default:
break;
@ -179,7 +178,7 @@ export default {
}
this.track(INSTRUMENT_TODO_FILTER_CHANGE, {
label: getInstrumentTabLabels()[tabIndex],
label: INSTRUMENT_TAB_LABELS[tabIndex],
});
this.currentTab = tabIndex;
@ -194,14 +193,12 @@ export default {
},
syncActiveTabToUrl() {
const tabIndexToUrlStateParam = {
[getTabsIndices().done]: 'done',
[getTabsIndices().all]: 'all',
[TABS_INDICES.snoozed]: 'snoozed',
[TABS_INDICES.done]: 'done',
[TABS_INDICES.all]: 'all',
};
if (this.glFeatures.todosSnoozing) {
tabIndexToUrlStateParam[getTabsIndices().snoozed] = 'snoozed';
}
const searchParams = new URLSearchParams(window.location.search);
if (this.currentTab === getTabsIndices().pending) {
if (this.currentTab === TABS_INDICES.pending) {
searchParams.delete('state');
} else {
searchParams.set('state', tabIndexToUrlStateParam[this.currentTab]);
@ -280,7 +277,7 @@ export default {
</gl-badge>
</template>
</gl-tab>
<gl-tab v-if="glFeatures.todosSnoozing">
<gl-tab>
<template #title>
<span>{{ s__('Todos|Snoozed') }}</span>
</template>

View File

@ -4,8 +4,7 @@ import emptyTodosAllDoneSvg from '@gitlab/svgs/dist/illustrations/empty-todos-al
import emptyTodosSvg from '@gitlab/svgs/dist/illustrations/empty-todos-md.svg';
import { s__ } from '~/locale';
import { helpPagePath } from '~/helpers/help_page_helper';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { TODO_EMPTY_TITLE_POOL, getTabsIndices } from '../constants';
import { TODO_EMPTY_TITLE_POOL, TABS_INDICES } from '../constants';
export default {
components: {
@ -13,7 +12,6 @@ export default {
GlLink,
GlSprintf,
},
mixins: [glFeatureFlagMixin()],
inject: {
currentTab: {
type: Number,
@ -54,10 +52,10 @@ export default {
return this.$options.emptyTodosAllDoneSvg;
},
isDoneTab() {
return this.currentTab === getTabsIndices().done;
return this.currentTab === TABS_INDICES.done;
},
isSnoozedTab() {
return this.glFeatures.todosSnoozing && this.currentTab === getTabsIndices().snoozed;
return this.currentTab === TABS_INDICES.snoozed;
},
},
methods: {

View File

@ -36,25 +36,13 @@ export const TODO_EMPTY_TITLE_POOL = [
s__('Todos|Henceforth, you shall be known as "To-Do Destroyer"'),
];
/**
* Note: This is a function so we can insert items depending on the todosSnoozing feature flag's state.
* When removing the feature flag, this can be converted back to a plain constant. Same goes for a
* couple other functions below.
*/
export const getStatusByTab = () => {
const STATUS_BY_TAB = [['pending'], ['done'], ['pending', 'done']];
if (gon.features?.todosSnoozing) {
STATUS_BY_TAB.splice(1, 0, ['pending']);
}
return STATUS_BY_TAB;
};
export const getTabsIndices = () => ({
export const STATUS_BY_TAB = [['pending'], ['pending'], ['done'], ['pending', 'done']];
export const TABS_INDICES = {
pending: 0,
snoozed: 1,
done: gon.features?.todosSnoozing ? 2 : 1,
all: gon.features?.todosSnoozing ? 3 : 2,
});
done: 2,
all: 3,
};
/**
* Instrumentation
@ -64,13 +52,12 @@ export const INSTRUMENT_TODO_ITEM_FOLLOW = 'follow_todo_link';
export const INSTRUMENT_TODO_SORT_CHANGE = 'sort_todo_list';
export const INSTRUMENT_TODO_FILTER_CHANGE = 'filter_todo_list';
export const getInstrumentTabLabels = () => {
const INSTRUMENT_TAB_LABELS = ['status_pending', 'status_done', 'status_all'];
if (gon.features?.todosSnoozing) {
INSTRUMENT_TAB_LABELS.splice(1, 0, 'status_snoozed');
}
return INSTRUMENT_TAB_LABELS;
};
export const INSTRUMENT_TAB_LABELS = [
'status_pending',
'status_snoozed',
'status_done',
'status_all',
];
export const DEFAULT_PAGE_SIZE = 20;
export const TODO_WAIT_BEFORE_RELOAD = 1 * 1000; // 1 second

View File

@ -4,9 +4,7 @@ class Dashboard::TodosController < Dashboard::ApplicationController
feature_category :notifications
urgency :low
def index
push_frontend_feature_flag(:todos_snoozing, current_user)
end
def index; end
def destroy
todo = current_user.todos.find(params[:id])

View File

@ -1,13 +0,0 @@
# frozen_string_literal: true
class Projects::ServicePingController < Projects::ApplicationController
before_action :authenticate_user!
feature_category :web_ide
def web_ide_pipelines_count
Gitlab::UsageDataCounters::WebIdeCounter.increment_pipelines_count
head(:ok)
end
end

View File

@ -38,8 +38,6 @@ class Projects::WebIdeTerminalsController < Projects::ApplicationController
current_build = pipeline.builds.last
if current_build
Gitlab::UsageDataCounters::WebIdeCounter.increment_terminals_count
render_terminal(current_build)
else
render status: :bad_request, json: pipeline.errors.full_messages

View File

@ -52,7 +52,7 @@ class TodosFinder
items = by_action(items)
items = by_author(items)
items = by_state(items)
items = by_snoozed_status(items) if Feature.enabled?(:todos_snoozing, current_user)
items = by_snoozed_status(items)
items = by_target_id(items)
items = by_types(items)
items = by_group(items)

View File

@ -20,8 +20,6 @@ module WorkItems
created_at: work_item.created_at,
updated_at: work_item.updated_at,
updated_by: work_item.updated_by,
last_edited_at: work_item.last_edited_at,
last_edited_by: work_item.last_edited_by,
closed_at: work_item.closed_at,
closed_by: work_item.closed_by,
duplicated_to_id: work_item.duplicated_to_id,

View File

@ -5,12 +5,28 @@ module WorkItems
module Widgets
class Description < Base
def before_create
# set description, e.g.
# work_item.description = target_work_item.description
return unless target_work_item.get_widget(:description)
# The service returns `description`, `description_html` and also `skip_markdown_cache_validation`.
# We need to assign all of those attributes to the target work item.
description_params = MarkdownContentRewriterService.new(
current_user,
work_item,
:description,
work_item.namespace,
target_work_item.namespace
).execute
target_work_item.assign_attributes(
description_params.merge(
last_edited_at: work_item.last_edited_at,
last_edited_by: work_item.last_edited_by
)
)
end
def post_move_cleanup
# do it
# Description is a field in the work_item record, it will be removed upon the work_item deletion
end
end
end

View File

@ -1,9 +0,0 @@
---
name: todos_snoozing
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/17712
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/175163
rollout_issue_url:
milestone: '17.7'
group: group::personal productivity
type: wip
default_enabled: false

View File

@ -6,7 +6,7 @@ product_group: remote_development
product_categories:
- web_ide
value_type: number
status: active
status: removed
time_frame: all
data_source: redis
instrumentation_class: RedisMetric
@ -24,3 +24,5 @@ tiers:
performance_indicator_type: []
milestone: "<13.9"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54332
milestone_removed: "17.9"
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/176298

View File

@ -6,7 +6,7 @@ product_group: remote_development
product_categories:
- web_ide
value_type: number
status: active
status: removed
time_frame: all
data_source: redis
instrumentation_class: RedisMetric
@ -24,3 +24,5 @@ tiers:
performance_indicator_type: []
milestone: "<13.9"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54332
milestone_removed: "17.9"
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/176298

View File

@ -6,7 +6,7 @@ product_group: remote_development
product_categories:
- web_ide
value_type: number
status: active
status: removed
time_frame: all
data_source: redis
instrumentation_class: RedisMetric
@ -24,3 +24,5 @@ tiers:
performance_indicator_type: []
milestone: "<13.9"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54332
milestone_removed: "17.9"
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/176298

View File

@ -6,7 +6,7 @@ product_group: remote_development
product_categories:
- web_ide
value_type: number
status: active
status: removed
time_frame: all
data_source: redis
instrumentation_class: RedisMetric
@ -21,3 +21,5 @@ tiers:
performance_indicator_type: []
milestone: "14.8"
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54332
milestone_removed: "17.9"
removed_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/176298

View File

@ -622,10 +622,6 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
end
scope :service_ping, controller: :service_ping do
post :web_ide_pipelines_count # rubocop:todo Cop/PutProjectRoutesUnderScope
end
resources :web_ide_terminals, path: :ide_terminals, only: [:create, :show], constraints: { id: /\d+/, format: :json } do # rubocop: disable Cop/PutProjectRoutesUnderScope
member do
post :cancel # rubocop:todo Cop/PutProjectRoutesUnderScope

View File

@ -0,0 +1,26 @@
- title: "SAST jobs no longer use global cache settings"
removal_milestone: "18.0"
announcement_milestone: "17.9"
breaking_change: true
window: 1
reporter: thiagocsf
stage: application security testing
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/512564
impact: medium
scope: instance
resolution_role: Developer
manual_task: true
body: | # (required) Don't change this line.
In GitLab 18.0, we will update SAST and IaC Scanning to explicitly [disable the use of the CI/CD job cache](https://docs.gitlab.com/ee/ci/caching/#disable-cache-for-specific-jobs) by default.
This change affects the CI/CD templates for:
- SAST: `SAST.gitlab-ci.yml`.
- IaC Scanning: `SAST-IaC.gitlab-ci.yml`.
We already updated the `latest` templates `SAST.latest.gitlab-ci.yml` and `SAST-IaC.latest.gitlab-ci.yml`. See [stable and latest templates](https://docs.gitlab.com/ee/user/application_security/sast/#stable-vs-latest-sast-templates) for more details on these template versions.
The cache directories are not in scope for scanning in most projects, so fetching the cache can cause timeouts or false-positive results.
If you need to use the cache when scanning a project, you can restore the previous behavior by [overriding](https://docs.gitlab.com/ee/user/application_security/sast/#overriding-sast-jobs) the
[`cache`](https://docs.gitlab.com/ee/ci/yaml/#cache) property in the project's CI configuration.

View File

@ -22209,6 +22209,7 @@ The currently authenticated GitLab user.
| <a id="currentuserbio"></a>`bio` | [`String`](#string) | Bio of the user. |
| <a id="currentuserbot"></a>`bot` | [`Boolean!`](#boolean) | Indicates if the user is a bot. |
| <a id="currentusercallouts"></a>`callouts` | [`UserCalloutConnection`](#usercalloutconnection) | User callouts that belong to the user. (see [Connections](#connections)) |
| <a id="currentusercodesuggestionscontexts"></a>`codeSuggestionsContexts` **{warning-solid}** | [`[String!]!`](#string) | **Introduced** in GitLab 17.9. **Status**: Experiment. List of additional contexts enabled for Code Suggestions. |
| <a id="currentusercommitemail"></a>`commitEmail` | [`String`](#string) | User's default commit email. |
| <a id="currentusercreatedat"></a>`createdAt` | [`Time`](#time) | Timestamp of when the user was created. |
| <a id="currentuserdiscord"></a>`discord` | [`String`](#string) | Discord ID of the user. |

View File

@ -45,7 +45,7 @@ Auto Build builds an application using a project's `Dockerfile` if present. If n
application into a Docker image. The feature uses the
[`pack` command](https://github.com/buildpacks/pack).
The default [builder](https://buildpacks.io/docs/for-app-developers/concepts/builder/)
is `heroku/buildpacks:18` but a different builder can be selected using
is `heroku/buildpacks:22` but a different builder can be selected using
the CI/CD variable `AUTO_DEVOPS_BUILD_IMAGE_CNB_BUILDER`.
Each buildpack requires your project's repository to contain certain files for

View File

@ -49,6 +49,7 @@ This window takes place on April 21 - 23, 2025 from 09:00 UTC to 22:00 UTC.
| [`maxHoursBeforeTermination` GraphQL field is deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/509787) | Low | Create | Project |
| [`RemoteDevelopmentAgentConfig` GraphQL type is deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/509787) | Low | Create | Project |
| [`defaultMaxHoursBeforeTermination` and `maxHoursBeforeTerminationLimit` fields are deprecated](https://gitlab.com/gitlab-org/gitlab/-/issues/509787) | Low | Create | Project |
| [SAST jobs no longer use global cache settings](https://gitlab.com/gitlab-org/gitlab/-/issues/512564) | Medium | Application security testing | Instance |
## Window 2

View File

@ -1252,6 +1252,34 @@ In GitLab 18.0, only the runner registration methods implemented in the new GitL
<div class="deprecation breaking-change" data-milestone="18.0">
### SAST jobs no longer use global cache settings
<div class="deprecation-notes">
- Announced in GitLab <span class="milestone">17.9</span>
- Removal in GitLab <span class="milestone">18.0</span> ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/gitlab-org/gitlab/-/issues/512564).
</div>
In GitLab 18.0, we will update SAST and IaC Scanning to explicitly [disable the use of the CI/CD job cache](https://docs.gitlab.com/ee/ci/caching/#disable-cache-for-specific-jobs) by default.
This change affects the CI/CD templates for:
- SAST: `SAST.gitlab-ci.yml`.
- IaC Scanning: `SAST-IaC.gitlab-ci.yml`.
We already updated the `latest` templates `SAST.latest.gitlab-ci.yml` and `SAST-IaC.latest.gitlab-ci.yml`. See [stable and latest templates](https://docs.gitlab.com/ee/user/application_security/sast/#stable-vs-latest-sast-templates) for more details on these template versions.
The cache directories are not in scope for scanning in most projects, so fetching the cache can cause timeouts or false-positive results.
If you need to use the cache when scanning a project, you can restore the previous behavior by [overriding](https://docs.gitlab.com/ee/user/application_security/sast/#overriding-sast-jobs) the
[`cache`](https://docs.gitlab.com/ee/ci/yaml/#cache) property in the project's CI configuration.
</div>
<div class="deprecation breaking-change" data-milestone="18.0">
### Support for REST API endpoints that reset runner registration tokens
<div class="deprecation-notes">

View File

@ -4,7 +4,6 @@ module Gitlab
module UsageDataCounters
COUNTERS = [
DiffsCounter,
WebIdeCounter,
MergeRequestWidgetExtensionCounter
].freeze

View File

@ -1,28 +0,0 @@
# frozen_string_literal: true
module Gitlab
module UsageDataCounters
class WebIdeCounter < BaseCounter
KNOWN_EVENTS = %w[commits views merge_requests previews previews_success terminals pipelines].freeze
PREFIX = 'web_ide'
class << self
def increment_terminals_count
count('terminals')
end
def increment_pipelines_count
count('pipelines')
end
private
def redis_key(event)
require_known_event(event)
"#{prefix}_#{event}_count".upcase
end
end
end
end
end

View File

@ -156,7 +156,7 @@ module QA
end
def running_on_release?
gitlab_host.include?('release.gitlab.net') || gitlab_host.include?('release.gke.gitlab.net')
gitlab_host.include?('release.gitlab.net')
end
def running_on_dev?

View File

@ -156,7 +156,7 @@ module QA
#
# @return [Boolean]
def create_unique_test_user?
!Env.running_on_dot_com? && !Env.personal_access_tokens_disabled? && admin_api_client
!Env.running_on_live_env? && !Env.personal_access_tokens_disabled? && admin_api_client
end
# Create api client with provided token with fallback to UI creation of token

View File

@ -45,10 +45,10 @@ tests = [
{
explanation: 'https://gitlab.com/gitlab-org/gitlab/-/issues/368628',
changed_file: 'lib/gitlab/usage_data_counters/web_ide_counter.rb',
changed_file: 'lib/gitlab/usage_data_counters/work_item_activity_unique_counter.rb',
expected: %w[
spec/lib/gitlab/usage_data_spec.rb
spec/lib/gitlab/usage_data_counters/web_ide_counter_spec.rb
spec/lib/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb
]
},

View File

@ -1,51 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Projects::ServicePingController do
let_it_be(:project) { create(:project) }
let_it_be(:user) { create(:user) }
before do
sign_in(user) if user
end
shared_examples 'counter is not increased' do
context 'when the user is not authenticated' do
let(:user) { nil }
it 'returns 302' do
subject
expect(response).to have_gitlab_http_status(:found)
end
end
context 'when the user does not have access to the project' do
it 'returns 404' do
subject
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
shared_examples 'counter is increased' do |counter|
context 'when the authenticated user has access to the project' do
let(:user) { project.first_owner }
it 'increments the usage counter' do
expect do
subject
end.to change { Gitlab::UsageDataCounters::WebIdeCounter.total_count(counter) }.by(1)
end
end
end
describe 'POST #web_ide_pipelines_count' do
subject { post :web_ide_pipelines_count, params: { namespace_id: project.namespace, project_id: project } }
it_behaves_like 'counter is not increased'
it_behaves_like 'counter is increased', 'WEB_IDE_PIPELINES_COUNT'
end
end

View File

@ -167,20 +167,6 @@ RSpec.describe Projects::WebIdeTerminalsController do
end
end
end
it 'increases the web ide terminal counter' do
expect(Gitlab::UsageDataCounters::WebIdeCounter).to receive(:increment_terminals_count)
subject
end
end
shared_examples 'web ide terminal usage counter' do
it 'does not increase', :enable_admin_mode do
expect(Gitlab::UsageDataCounters::WebIdeCounter).not_to receive(:increment_terminals_count)
subject
end
end
context 'when branch does not exist' do
@ -192,8 +178,6 @@ RSpec.describe Projects::WebIdeTerminalsController do
expect(response).to have_gitlab_http_status(:bad_request)
end
it_behaves_like 'web ide terminal usage counter'
end
context 'when there is an error creating the job' do
@ -210,8 +194,6 @@ RSpec.describe Projects::WebIdeTerminalsController do
expect(response).to have_gitlab_http_status(:bad_request)
end
it_behaves_like 'web ide terminal usage counter'
end
context 'when the current build is nil' do
@ -229,8 +211,6 @@ RSpec.describe Projects::WebIdeTerminalsController do
expect(response).to have_gitlab_http_status(:bad_request)
end
it_behaves_like 'web ide terminal usage counter'
end
end

View File

@ -230,18 +230,6 @@ RSpec.describe TodosFinder, feature_category: :notifications do
expect(todos).to match_array([todo2])
end
context 'when todos_snoozing feature flag is disabled' do
before do
stub_feature_flags(todos_snoozing: false)
end
it 'returns all pending todos' do
todos = finder.new(user, { is_snoozed: true }).execute
expect(todos).to match_array([todo1, todo2, todo3])
end
end
end
context 'by project' do

View File

@ -25,7 +25,6 @@ describe('GlobalSearch MergeRequestsFilters', () => {
provide = {
glFeatures: {
searchMrFilterSourceBranch: true,
searchMrFilterAuthor: true,
},
},
) => {
@ -115,16 +114,6 @@ describe('GlobalSearch MergeRequestsFilters', () => {
});
});
describe('When feature flag search_mr_filter_author is disabled', () => {
beforeEach(() => {
createComponent(null, { glFeatures: { searchMrFilterAuthor: false } });
});
it(`will not render AuthorFilter`, () => {
expect(findAuthorFilter().exists()).toBe(false);
});
});
describe('#hasMissingProjectContext getter', () => {
beforeEach(() => {
defaultGetters.hasMissingProjectContext = () => false;

View File

@ -36,7 +36,7 @@ describe('TodoItemActions', () => {
},
});
const createComponent = ({ props = {}, todosSnoozingEnabled = true } = {}) => {
const createComponent = ({ props = {} } = {}) => {
const mockApollo = createMockApollo([
[markAsDoneMutation, markAsDoneMutationSuccessHandler],
[markAsPendingMutation, markAsPendingMutationSuccessHandler],
@ -49,11 +49,6 @@ describe('TodoItemActions', () => {
isSnoozed: false,
...props,
},
provide: {
glFeatures: {
todosSnoozing: todosSnoozingEnabled,
},
},
mocks: {
$toast: {
show: mockToastShow,
@ -139,12 +134,4 @@ describe('TodoItemActions', () => {
},
);
});
describe('when the `todosSnoozing` feature flag is disabled', () => {
it('never renders the ToggleSnoozedStatus component', () => {
createComponent({ todosSnoozingEnabled: false, props: { isSnoozed: false } });
expect(findToggleSnoozedStatus().exists()).toBe(false);
});
});
});

View File

@ -24,7 +24,7 @@ describe('TodoItem', () => {
const findTodoItemTimestamp = () => wrapper.findComponent(TodoItemTimestamp);
const createComponent = (props = {}, todosSnoozingEnabled = true) => {
const createComponent = (props = {}) => {
wrapper = shallowMount(TodoItem, {
propsData: {
currentUserId: '1',
@ -35,7 +35,6 @@ describe('TodoItem', () => {
},
provide: {
currentTab: 0,
glFeatures: { todosSnoozing: todosSnoozingEnabled },
},
});
};
@ -133,36 +132,6 @@ describe('TodoItem', () => {
expect(icon.exists()).toBe(true);
expect(icon.props('name')).toBe('clock');
});
it('renders the TodoItemTimestamp when the `todosSnoozing` feature flag is disabled and the item is snoozed', () => {
createComponent(
{
todo: {
...MR_REVIEW_REQUEST_TODO,
snoozedUntil: mockForAnHour,
},
},
false,
);
expect(findTodoItemTimestamp().exists()).toBe(true);
expect(wrapper.text()).not.toContain('Snoozed until');
});
it('renders the TodoItemTimestamp when the `todosSnoozing` feature flag is disabled and the item was snoozed', () => {
createComponent(
{
todo: {
...MR_REVIEW_REQUEST_TODO,
snoozedUntil: mockYesterday,
},
},
false,
);
expect(findTodoItemTimestamp().exists()).toBe(true);
expect(wrapper.text()).not.toContain('First sent 4 months ago');
});
});
describe('isSnoozed status', () => {

View File

@ -12,7 +12,7 @@ import TodosFilterBar from '~/todos/components/todos_filter_bar.vue';
import TodosMarkAllDoneButton from '~/todos/components/todos_mark_all_done_button.vue';
import TodosPagination, { CURSOR_CHANGED_EVENT } from '~/todos/components/todos_pagination.vue';
import getTodosQuery from '~/todos/components/queries/get_todos.query.graphql';
import { getInstrumentTabLabels, getStatusByTab, TODO_WAIT_BEFORE_RELOAD } from '~/todos/constants';
import { INSTRUMENT_TAB_LABELS, STATUS_BY_TAB, TODO_WAIT_BEFORE_RELOAD } from '~/todos/constants';
import { mockTracking, unmockTracking } from 'jest/__helpers__/tracking_helper';
import getPendingTodosCount from '~/todos/components/queries/get_pending_todos_count.query.graphql';
import { todosResponse, getPendingTodosCountResponse } from '../mock_data';
@ -28,7 +28,6 @@ describe('TodosApp', () => {
const createComponent = ({
todosQueryHandler = todosQuerySuccessHandler,
todosCountsQueryHandler = todosCountsQuerySuccessHandler,
glFeatures = { todosSnoozing: true },
} = {}) => {
const mockApollo = createMockApollo();
mockApollo.defaultClient.setRequestHandler(getTodosQuery, todosQueryHandler);
@ -36,9 +35,6 @@ describe('TodosApp', () => {
wrapper = shallowMountExtended(TodosApp, {
apolloProvider: mockApollo,
provide: {
glFeatures,
},
});
};
@ -54,12 +50,8 @@ describe('TodosApp', () => {
ignoreConsoleMessages([/\[Vue warn\]: \(deprecation TRANSITION_GROUP_ROOT\)/]);
beforeEach(() => {
gon.features = { todosSnoozing: true };
});
it('should have a tracking event for each tab', () => {
expect(getStatusByTab().length).toBe(getInstrumentTabLabels().length);
expect(STATUS_BY_TAB.length).toBe(INSTRUMENT_TAB_LABELS.length);
});
it('shows a loading state while fetching todos', () => {

View File

@ -3,16 +3,12 @@ import emptyTodosAllDoneSvg from '@gitlab/svgs/dist/illustrations/empty-todos-al
import emptyTodosSvg from '@gitlab/svgs/dist/illustrations/empty-todos-md.svg';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import TodosEmptyState from '~/todos/components/todos_empty_state.vue';
import { TODO_EMPTY_TITLE_POOL, getTabsIndices } from '~/todos/constants';
import { TODO_EMPTY_TITLE_POOL, TABS_INDICES } from '~/todos/constants';
describe('TodosEmptyState', () => {
let wrapper;
const createComponent = (
props = {},
currentTab = getTabsIndices().pending,
todosSnoozingEnabled = true,
) => {
const createComponent = (props = {}, currentTab = TABS_INDICES.pending) => {
wrapper = shallowMountExtended(TodosEmptyState, {
propsData: {
isFiltered: false,
@ -22,9 +18,6 @@ describe('TodosEmptyState', () => {
issuesDashboardPath: '/dashboard/issues',
mergeRequestsDashboardPath: '/dashboard/merge_requests',
currentTab,
glFeatures: {
todosSnoozing: todosSnoozingEnabled,
},
},
stubs: {
GlSprintf,
@ -34,10 +27,6 @@ describe('TodosEmptyState', () => {
const findDocLink = () => wrapper.findByTestId('doc-link');
beforeEach(() => {
gon.features = { todosSnoozing: true };
});
it('renders the empty state component', () => {
createComponent();
expect(wrapper.findComponent(GlEmptyState).exists()).toBe(true);
@ -96,7 +85,7 @@ describe('TodosEmptyState', () => {
describe('when on "Snoozed" tab', () => {
beforeEach(() => {
createComponent({ isFiltered: false }, getTabsIndices().snoozed);
createComponent({ isFiltered: false }, TABS_INDICES.snoozed);
});
it('renders the correct title', () => {
@ -118,7 +107,7 @@ describe('TodosEmptyState', () => {
describe('when on "Done" tab', () => {
beforeEach(() => {
createComponent({ isFiltered: false }, getTabsIndices().done);
createComponent({ isFiltered: false }, TABS_INDICES.done);
});
it('renders the correct title', () => {
@ -135,20 +124,4 @@ describe('TodosEmptyState', () => {
expect(wrapper.findComponent(GlEmptyState).props('svgPath')).toBe(emptyTodosSvg);
});
});
describe('when the todosSnoozing feature flag is diabled', () => {
const todosSnoozingEnabled = false;
beforeEach(() => {
gon.features = { todosSnoozing: todosSnoozingEnabled };
});
it('renders the "Done" tab at the "Snoozed" tab\'s index', () => {
createComponent({ isFiltered: false }, getTabsIndices().snoozed, todosSnoozingEnabled);
expect(wrapper.findComponent(GlEmptyState).props('title')).toBe(
'There are no done to-do items yet.',
);
});
});
});

View File

@ -133,18 +133,6 @@ RSpec.describe Resolvers::TodosResolver, feature_category: :notifications do
expect(todos.items).to eq([todo2, todo3])
end
context 'when todos_snoozing feature flag is disabled' do
before do
stub_feature_flags(todos_snoozing: false)
end
it 'ignores the is_snoozed filter' do
todos = resolve_todos(args: { is_snoozed: true, sort: 'CREATED_ASC' }, context: { current_user: new_user })
expect(todos.items).to eq([todo1, todo2, todo3])
end
end
end
end

View File

@ -2,7 +2,7 @@
require "fast_spec_helper"
RSpec.describe Gitlab::Fp::Settings::PublicApi, :web_ide_fast, feature_category: :web_ide do
RSpec.describe Gitlab::Fp::Settings::PublicApi, feature_category: :web_ide do
let(:settings_module) { Module.new { extend Gitlab::Fp::Settings::PublicApi } }
let(:settings_main_class) { double(Class.new) } # rubocop:disable RSpec/VerifiedDoubles -- we want to use 'fast_spec_helper' so we don't want to refer to a concrete class
let(:options) { {} }

View File

@ -1,40 +0,0 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::UsageDataCounters::WebIdeCounter, :clean_gitlab_redis_shared_state do
shared_examples 'counter examples' do |event|
it 'increments counter and return the total count' do
expect(described_class.public_send(:total_count, event)).to eq(0)
2.times { described_class.public_send(:"increment_#{event}_count") }
redis_key = "web_ide_#{event}_count".upcase
expect(described_class.public_send(:total_count, redis_key)).to eq(2)
end
end
describe 'terminals counter' do
it_behaves_like 'counter examples', 'terminals'
end
describe 'pipelines counter' do
it_behaves_like 'counter examples', 'pipelines'
end
describe '.totals' do
terminals = 1
pipelines = 2
before do
terminals.times { described_class.increment_terminals_count }
pipelines.times { described_class.increment_pipelines_count }
end
it 'can report all totals' do
expect(described_class.totals).to include(
web_ide_terminals: terminals
)
end
end
end

View File

@ -13,10 +13,10 @@ RSpec.describe Gitlab::UsageDataCounters do
describe '.count' do
subject { described_class.count(event_name) }
let(:event_name) { 'web_ide_views' }
let(:event_name) { 'diff_searches' }
it 'increases a view counter' do
expect(Gitlab::UsageDataCounters::WebIdeCounter).to receive(:count).with('views')
it 'increases a searches counter' do
expect(Gitlab::UsageDataCounters::DiffsCounter).to receive(:count).with('searches')
subject
end

View File

@ -2,7 +2,7 @@
require "fast_spec_helper"
RSpec.describe WebIde::Settings::ExtensionsGalleryMetadataGenerator, :web_ide_fast, feature_category: :web_ide do
RSpec.describe WebIde::Settings::ExtensionsGalleryMetadataGenerator, feature_category: :web_ide do
using RSpec::Parameterized::TableSyntax
let(:input_context) do

View File

@ -2,7 +2,7 @@
require "fast_spec_helper"
RSpec.describe WebIde::Settings::ExtensionsGalleryMetadataValidator, :web_ide_fast, feature_category: :web_ide do
RSpec.describe WebIde::Settings::ExtensionsGalleryMetadataValidator, feature_category: :web_ide do
include ResultMatchers
let(:context) do

View File

@ -2,7 +2,7 @@
require "fast_spec_helper"
RSpec.describe WebIde::Settings::ExtensionsGalleryValidator, :web_ide_fast, feature_category: :web_ide do
RSpec.describe WebIde::Settings::ExtensionsGalleryValidator, feature_category: :web_ide do
include ResultMatchers
let(:service_url) { "https://open-vsx.org/vscode/gallery" }

View File

@ -2,7 +2,7 @@
require "fast_spec_helper"
RSpec.describe WebIde::Settings::Main, :web_ide_fast, feature_category: :web_ide do
RSpec.describe WebIde::Settings::Main, feature_category: :web_ide do
let(:settings) { 'some settings' }
let(:context_passed_along_steps) { { settings: settings } }

View File

@ -2,7 +2,7 @@
require "fast_spec_helper"
RSpec.describe WebIde::Settings::SettingsInitializer, :web_ide_fast, feature_category: :web_ide do
RSpec.describe WebIde::Settings::SettingsInitializer, feature_category: :web_ide do
let(:all_possible_requested_setting_names) { WebIde::Settings::DefaultSettings.default_settings.keys }
let(:context) do
{ requested_setting_names: all_possible_requested_setting_names }

View File

@ -950,12 +950,6 @@ RSpec.describe 'project routing', feature_category: :groups_and_projects do
end
end
describe Projects::ServicePingController, 'routing' do
it 'routes to service_ping#web_ide_pipelines_count' do
expect(post('/gitlab/gitlabhq/service_ping/web_ide_pipelines_count')).to route_to('projects/service_ping#web_ide_pipelines_count', namespace_id: 'gitlab', project_id: 'gitlabhq')
end
end
describe Projects::EnvironmentsController, 'routing' do
describe 'legacy routing' do
it_behaves_like 'redirecting a legacy path', "/gitlab/gitlabhq/environments", "/gitlab/gitlabhq/-/environments"

View File

@ -0,0 +1,44 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe WorkItems::DataSync::Widgets::Description, feature_category: :team_planning do
let_it_be(:current_user) { create(:user) }
let_it_be(:last_edited_at) { DateTime.now }
let_it_be(:work_item) do
create(:work_item, description: "Move weight widget data", last_edited_at: last_edited_at,
last_edited_by: current_user)
end
let_it_be(:target_work_item) { create(:work_item) }
let(:params) { {} }
subject(:callback) do
described_class.new(
work_item: work_item, target_work_item: target_work_item, current_user: current_user, params: params
)
end
describe '#before_create' do
context 'when target work item does not have description widget' do
before do
allow(target_work_item).to receive(:get_widget).with(:description).and_return(false)
end
it 'does not copy any description data' do
expect { callback.before_create }.to not_change { target_work_item.description }
.and not_change { target_work_item.description_html }
.and not_change { target_work_item.last_edited_at }
.and not_change { target_work_item.last_edited_by }
end
end
it 'copies all the description data' do
expect { callback.before_create }.to change { target_work_item.description }.from(nil).to(work_item.description)
.and change { target_work_item.description_html }.from("").to(work_item.description_html)
.and change { target_work_item.last_edited_at }.from(nil).to(last_edited_at)
.and change { target_work_item.last_edited_by }.from(nil).to(current_user)
end
end
end

View File

@ -160,7 +160,6 @@
- :use_sql_query_cache
- :use_sql_query_cache_for_tracking_db
- :uses_fast_spec_helper_but_runs_slow
- :web_ide_fast
- :with_clean_rails_cache
- :with_cloud_connector
- :with_current_organization

View File

@ -2629,7 +2629,6 @@
- './spec/controllers/projects/releases/evidences_controller_spec.rb'
- './spec/controllers/projects/repositories_controller_spec.rb'
- './spec/controllers/projects/security/configuration_controller_spec.rb'
- './spec/controllers/projects/service_ping_controller_spec.rb'
- './spec/controllers/projects/settings/ci_cd_controller_spec.rb'
- './spec/controllers/projects/settings/integration_hook_logs_controller_spec.rb'
- './spec/controllers/projects/settings/integrations_controller_spec.rb'
@ -5609,7 +5608,6 @@
- './spec/lib/gitlab/usage_data_counters/redis_counter_spec.rb'
- './spec/lib/gitlab/usage_data_counters_spec.rb'
- './spec/lib/gitlab/usage_data_counters/vscode_extension_activity_unique_counter_spec.rb'
- './spec/lib/gitlab/usage_data_counters/web_ide_counter_spec.rb'
- './spec/lib/gitlab/usage_data_counters/work_item_activity_unique_counter_spec.rb'
- './spec/lib/gitlab/usage_data_metrics_spec.rb'
- './spec/lib/gitlab/usage_data_non_sql_metrics_spec.rb'