Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/diffs/components/tree_list.vue106
-rw-r--r--app/assets/javascripts/editor/schema/ci.json10
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js2
-rw-r--r--app/assets/javascripts/vue_shared/components/file_row.vue2
-rw-r--r--app/assets/javascripts/vue_shared/components/file_row_header.vue2
-rw-r--r--app/assets/stylesheets/framework/diffs.scss2
-rw-r--r--app/assets/stylesheets/page_bundles/merge_requests.scss11
-rw-r--r--app/assets/stylesheets/page_bundles/project_quality.scss15
-rw-r--r--app/controllers/concerns/observability/content_security_policy.rb2
-rw-r--r--app/controllers/concerns/product_analytics_tracking.rb45
-rw-r--r--app/controllers/groups/observability_controller.rb2
-rw-r--r--app/controllers/ide_controller.rb5
-rw-r--r--app/controllers/search_controller.rb5
-rw-r--r--app/graphql/mutations/alert_management/base.rb2
-rw-r--r--app/mailers/emails/profile.rb2
-rw-r--r--app/models/integrations/base_slack_notification.rb2
-rw-r--r--app/models/integrations/jira.rb2
-rw-r--r--app/policies/group_policy.rb8
-rw-r--r--app/services/concerns/incident_management/usage_data.rb2
-rw-r--r--app/services/event_create_service.rb2
-rw-r--r--app/services/import_csv/base_service.rb3
-rw-r--r--app/services/incident_management/timeline_events/base_service.rb2
-rw-r--r--app/services/issuable/import_csv/base_service.rb2
-rw-r--r--app/services/todo_service.rb2
-rw-r--r--app/services/work_items/import_csv_service.rb50
-rw-r--r--app/views/admin/sessions/_two_factor_otp.html.haml6
-rw-r--r--app/views/devise/sessions/two_factor.html.haml6
-rw-r--r--app/views/notify/two_factor_otp_attempt_failed_email.html.haml4
-rw-r--r--app/views/notify/two_factor_otp_attempt_failed_email.text.haml4
-rw-r--r--app/views/profiles/two_factor_auths/show.html.haml4
-rw-r--r--app/views/projects/pipelines/charts.html.haml1
-rw-r--r--app/views/projects/settings/integrations/index.html.haml2
-rw-r--r--app/views/shared/integrations/_slack_notifications_deprecation_alert.html.haml10
-rw-r--r--app/workers/post_receive.rb2
34 files changed, 238 insertions, 89 deletions
diff --git a/app/assets/javascripts/diffs/components/tree_list.vue b/app/assets/javascripts/diffs/components/tree_list.vue
index 8bb1872567c..4748c587b8e 100644
--- a/app/assets/javascripts/diffs/components/tree_list.vue
+++ b/app/assets/javascripts/diffs/components/tree_list.vue
@@ -2,9 +2,10 @@
import { GlTooltipDirective, GlIcon } from '@gitlab/ui';
import { mapActions, mapGetters, mapState } from 'vuex';
import micromatch from 'micromatch';
+import { debounce } from 'lodash';
import { getModifierKey } from '~/constants';
import { s__, sprintf } from '~/locale';
-import FileTree from '~/vue_shared/components/file_tree.vue';
+import { RecycleScroller } from 'vendor/vue-virtual-scroller';
import DiffFileRow from './diff_file_row.vue';
const MODIFIER_KEY = getModifierKey();
@@ -15,7 +16,8 @@ export default {
},
components: {
GlIcon,
- FileTree,
+ DiffFileRow,
+ RecycleScroller,
},
props: {
hideFileStats: {
@@ -26,6 +28,10 @@ export default {
data() {
return {
search: '',
+ scrollerHeight: 0,
+ resizeObserver: null,
+ rowHeight: 0,
+ debouncedHeightCalc: null,
};
},
computed: {
@@ -61,12 +67,51 @@ export default {
return acc;
}, []);
},
+ // Flatten the treeList so there's no nested trees
+ // This gives us fixed row height for virtual scrolling
+ // in: [{ path: 'a', tree: [{ path: 'b' }] }, { path: 'c' }]
+ // out: [{ path: 'a', tree: [{ path: 'b' }] }, { path: 'b' }, { path: 'c' }]
+ flatFilteredTreeList() {
+ const result = [];
+ const createFlatten = (level) => (item) => {
+ result.push({
+ ...item,
+ level: item.isHeader ? 0 : level,
+ key: item.key || item.path,
+ });
+ if (item.opened || item.isHeader) {
+ item.tree.forEach(createFlatten(level + 1));
+ }
+ };
+
+ this.filteredTreeList.forEach(createFlatten(0));
+
+ return result;
+ },
+ },
+ created() {
+ this.debouncedHeightCalc = debounce(this.calculateScrollerHeight, 50);
+ },
+ mounted() {
+ const heightProp = getComputedStyle(this.$refs.wrapper).getPropertyValue('--file-row-height');
+ this.rowHeight = parseInt(heightProp, 10);
+ this.calculateScrollerHeight();
+ this.resizeObserver = new ResizeObserver(() => {
+ this.debouncedHeightCalc();
+ });
+ this.resizeObserver.observe(this.$refs.scrollRoot);
+ },
+ beforeDestroy() {
+ this.resizeObserver.disconnect();
},
methods: {
...mapActions('diffs', ['toggleTreeOpen', 'scrollToFile']),
clearSearch() {
this.search = '';
},
+ calculateScrollerHeight() {
+ this.scrollerHeight = this.$refs.scrollRoot.clientHeight;
+ },
},
searchPlaceholder: sprintf(s__('MergeRequest|Search (e.g. *.vue) (%{MODIFIER_KEY}P)'), {
MODIFIER_KEY,
@@ -76,8 +121,12 @@ export default {
</script>
<template>
- <div class="tree-list-holder d-flex flex-column" data-qa-selector="file_tree_container">
- <div class="gl-mb-3 position-relative tree-list-search d-flex">
+ <div
+ ref="wrapper"
+ class="tree-list-holder d-flex flex-column"
+ data-qa-selector="file_tree_container"
+ >
+ <div class="gl-pb-3 position-relative tree-list-search d-flex">
<div class="flex-fill d-flex">
<gl-icon name="search" class="position-absolute tree-list-icon" />
<label for="diff-tree-search" class="sr-only">{{ $options.searchPlaceholder }}</label>
@@ -101,24 +150,37 @@ export default {
</button>
</div>
</div>
- <div :class="{ 'pt-0 tree-list-blobs': !renderTreeList || search }" class="tree-list-scroll">
- <template v-if="filteredTreeList.length">
- <file-tree
- v-for="file in filteredTreeList"
- :key="file.key"
- :file="file"
- :level="0"
- :viewed-files="viewedDiffFileIds"
- :hide-file-stats="hideFileStats"
- :file-row-component="$options.DiffFileRow"
- :current-diff-file-id="currentDiffFileId"
- :style="{ '--level': 0 }"
- :class="{ 'tree-list-parent': file.tree.length }"
- class="gl-relative"
- @toggleTreeOpen="toggleTreeOpen"
- @clickFile="(path) => scrollToFile({ path })"
- />
- </template>
+ <div
+ ref="scrollRoot"
+ :class="{ 'tree-list-blobs': !renderTreeList || search }"
+ class="gl-flex-grow-1"
+ >
+ <recycle-scroller
+ v-if="flatFilteredTreeList.length"
+ :style="{ height: `${scrollerHeight}px` }"
+ :items="flatFilteredTreeList"
+ :item-size="rowHeight"
+ :buffer="100"
+ key-field="key"
+ >
+ <template #default="{ item }">
+ <diff-file-row
+ :file="item"
+ :level="item.level"
+ :viewed-files="viewedDiffFileIds"
+ :hide-file-stats="hideFileStats"
+ :current-diff-file-id="currentDiffFileId"
+ :style="{ '--level': item.level }"
+ :class="{ 'tree-list-parent': item.tree.length }"
+ class="gl-relative"
+ @toggleTreeOpen="toggleTreeOpen"
+ @clickFile="(path) => scrollToFile({ path })"
+ />
+ </template>
+ <template #after>
+ <div class="tree-list-gutter"></div>
+ </template>
+ </recycle-scroller>
<p v-else class="prepend-top-20 append-bottom-20 text-center">
{{ s__('MergeRequest|No files found') }}
</p>
diff --git a/app/assets/javascripts/editor/schema/ci.json b/app/assets/javascripts/editor/schema/ci.json
index 57477a993c5..701b40b1021 100644
--- a/app/assets/javascripts/editor/schema/ci.json
+++ b/app/assets/javascripts/editor/schema/ci.json
@@ -537,7 +537,7 @@
},
"entrypoint": {
"type": "array",
- "description": "Command or script that should be executed as the container's entrypoint. It will be translated to Docker's --entrypoint option while creating the container. The syntax is similar to Dockerfile's ENTRYPOINT directive, where each shell token is a separate string in the array.",
+ "markdownDescription": "Command or script that should be executed as the container's entrypoint. It will be translated to Docker's --entrypoint option while creating the container. The syntax is similar to Dockerfile's ENTRYPOINT directive, where each shell token is a separate string in the array. [Learn More](https://docs.gitlab.com/ee/ci/services/index.html#available-settings-for-services)",
"minItems": 1,
"items": {
"type": "string"
@@ -572,7 +572,7 @@
},
"command": {
"type": "array",
- "description": "Command or script that should be used as the container's command. It will be translated to arguments passed to Docker after the image's name. The syntax is similar to Dockerfile's CMD directive, where each shell token is a separate string in the array.",
+ "markdownDescription": "Command or script that should be used as the container's command. It will be translated to arguments passed to Docker after the image's name. The syntax is similar to Dockerfile's CMD directive, where each shell token is a separate string in the array. [Learn More](https://docs.gitlab.com/ee/ci/services/index.html#available-settings-for-services)",
"minItems": 1,
"items": {
"type": "string"
@@ -580,8 +580,12 @@
},
"alias": {
"type": "string",
- "description": "Additional alias that can be used to access the service from the job's container. Read Accessing the services for more information.",
+ "markdownDescription": "Additional alias that can be used to access the service from the job's container. Read Accessing the services for more information. [Learn More](https://docs.gitlab.com/ee/ci/services/index.html#available-settings-for-services)",
"minLength": 1
+ },
+ "variables": {
+ "$ref": "#/definitions/jobVariables",
+ "markdownDescription": "Additional environment variables that are passed exclusively to the service. Service variables cannot reference themselves. [Learn More](https://docs.gitlab.com/ee/ci/services/index.html#available-settings-for-services)"
}
},
"required": [
diff --git a/app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js b/app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js
index 81cb20475cc..cead42b12ae 100644
--- a/app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js
+++ b/app/assets/javascripts/vue_merge_request_widget/stores/get_state_key.js
@@ -32,5 +32,5 @@ export default function deviseState() {
) {
return stateKey.readyToMerge;
}
- return null;
+ return stateKey.checking;
}
diff --git a/app/assets/javascripts/vue_shared/components/file_row.vue b/app/assets/javascripts/vue_shared/components/file_row.vue
index dfeb12d5cf5..721f87ff4d6 100644
--- a/app/assets/javascripts/vue_shared/components/file_row.vue
+++ b/app/assets/javascripts/vue_shared/components/file_row.vue
@@ -168,7 +168,7 @@ export default {
.file-row {
display: flex;
align-items: center;
- height: 32px;
+ height: var(--file-row-height, 32px);
padding: 4px 8px;
margin-left: -8px;
margin-right: -8px;
diff --git a/app/assets/javascripts/vue_shared/components/file_row_header.vue b/app/assets/javascripts/vue_shared/components/file_row_header.vue
index 5afb2408c7e..b436872e463 100644
--- a/app/assets/javascripts/vue_shared/components/file_row_header.vue
+++ b/app/assets/javascripts/vue_shared/components/file_row_header.vue
@@ -15,7 +15,7 @@ export default {
</script>
<template>
- <div class="file-row-header bg-white sticky-top p-2 js-file-row-header" :title="path">
+ <div class="file-row-header bg-white sticky-top gl-px-2 js-file-row-header" :title="path">
<gl-truncate :text="path" position="middle" class="bold" />
</div>
</template>
diff --git a/app/assets/stylesheets/framework/diffs.scss b/app/assets/stylesheets/framework/diffs.scss
index 4eb26d533c2..742d0e39dda 100644
--- a/app/assets/stylesheets/framework/diffs.scss
+++ b/app/assets/stylesheets/framework/diffs.scss
@@ -999,7 +999,7 @@ table.code {
}
// Note: Prevents tall files from appearing above sticky tabs
-.diffs .vue-recycle-scroller__item-view > div:not(.active) {
+.diff-files-holder .vue-recycle-scroller__item-view > div:not(.active) {
position: absolute;
bottom: 100vh;
}
diff --git a/app/assets/stylesheets/page_bundles/merge_requests.scss b/app/assets/stylesheets/page_bundles/merge_requests.scss
index fe64e4f2fe8..4caaeeb647e 100644
--- a/app/assets/stylesheets/page_bundles/merge_requests.scss
+++ b/app/assets/stylesheets/page_bundles/merge_requests.scss
@@ -282,6 +282,7 @@ $tabs-holder-z-index: 250;
}
.tree-list-holder {
+ --file-row-height: 32px;
height: 100%;
.file-row {
@@ -297,6 +298,10 @@ $tabs-holder-z-index: 250;
overflow-x: auto;
}
+.tree-list-gutter {
+ height: $grid-size;
+}
+
.tree-list-search {
flex: 0 0 34px;
@@ -322,6 +327,12 @@ $tabs-holder-z-index: 250;
line-height: 0;
}
+.file-row-header {
+ display: flex;
+ align-items: center;
+ height: var(--file-row-height);
+}
+
@media (max-width: map-get($grid-breakpoints, lg)-1) {
.diffs .files {
.diff-tree-list {
diff --git a/app/assets/stylesheets/page_bundles/project_quality.scss b/app/assets/stylesheets/page_bundles/project_quality.scss
new file mode 100644
index 00000000000..425b9544235
--- /dev/null
+++ b/app/assets/stylesheets/page_bundles/project_quality.scss
@@ -0,0 +1,15 @@
+@import 'page_bundles/mixins_and_variables_and_functions';
+
+/*
+When the single-stat component of gitlab UI adds the props of the title icon color,
+remove this file and use the props of gitlab UI to set the color
+Gitlab UI issue: https://gitlab.com/gitlab-org/gitlab-ui/-/issues/2157
+*/
+
+.code-quality-blocker .gl-icon {
+ @include gl-text-red-800;
+}
+
+.code-quality-critical .gl-icon {
+ @include gl-text-red-600;
+}
diff --git a/app/controllers/concerns/observability/content_security_policy.rb b/app/controllers/concerns/observability/content_security_policy.rb
index 14e9217fe02..1e25dc492a0 100644
--- a/app/controllers/concerns/observability/content_security_policy.rb
+++ b/app/controllers/concerns/observability/content_security_policy.rb
@@ -12,7 +12,7 @@ module Observability
defined?(project) ? project&.group : nil
end
- next if p.directives.blank? || !Gitlab::Observability.observability_enabled?(current_user, current_group)
+ next if p.directives.blank? || !Feature.enabled?(:observability_group_tab, current_group)
default_frame_src = p.directives['frame-src'] || p.directives['default-src']
diff --git a/app/controllers/concerns/product_analytics_tracking.rb b/app/controllers/concerns/product_analytics_tracking.rb
index 5696e441ad0..223b200f3b5 100644
--- a/app/controllers/concerns/product_analytics_tracking.rb
+++ b/app/controllers/concerns/product_analytics_tracking.rb
@@ -5,7 +5,29 @@ module ProductAnalyticsTracking
include RedisTracking
extend ActiveSupport::Concern
- MIGRATED_EVENTS = ['g_analytics_valuestream'].freeze
+ MIGRATED_EVENTS = %w[
+ g_analytics_valuestream
+ i_search_paid
+ i_search_total
+ i_search_advanced
+ i_ecosystem_jira_service_list_issues
+ users_viewing_analytics_group_devops_adoption
+ i_analytics_dev_ops_adoption
+ i_analytics_dev_ops_score
+ p_analytics_merge_request
+ i_analytics_instance_statistics
+ g_analytics_contribution
+ p_analytics_pipelines
+ p_analytics_code_reviews
+ p_analytics_valuestream
+ p_analytics_insights
+ p_analytics_issues
+ p_analytics_repo
+ g_analytics_insights
+ g_analytics_issues
+ g_analytics_productivity
+ i_analytics_cohorts
+ ].freeze
class_methods do
# TODO: Remove once all the events are migrated to #track_custom_event
@@ -68,27 +90,6 @@ module ProductAnalyticsTracking
return true if MIGRATED_EVENTS.include?(event)
events_to_ff = {
- i_search_paid: :_phase2,
- i_search_total: :_phase2,
- i_search_advanced: :_phase2,
- i_ecosystem_jira_service_list_issues: :_phase2,
- users_viewing_analytics_group_devops_adoption: :_phase2,
- i_analytics_dev_ops_adoption: :_phase2,
- i_analytics_dev_ops_score: :_phase2,
- p_analytics_merge_request: :_phase2,
- i_analytics_instance_statistics: :_phase2,
- g_analytics_contribution: :_phase2,
- p_analytics_pipelines: :_phase2,
- p_analytics_code_reviews: :_phase2,
- p_analytics_valuestream: :_phase2,
- p_analytics_insights: :_phase2,
- p_analytics_issues: :_phase2,
- p_analytics_repo: :_phase2,
- g_analytics_insights: :_phase2,
- g_analytics_issues: :_phase2,
- g_analytics_productivity: :_phase2,
- i_analytics_cohorts: :_phase2,
-
g_compliance_dashboard: :_phase4
}
diff --git a/app/controllers/groups/observability_controller.rb b/app/controllers/groups/observability_controller.rb
index 726af00a10e..525407f5849 100644
--- a/app/controllers/groups/observability_controller.rb
+++ b/app/controllers/groups/observability_controller.rb
@@ -30,7 +30,7 @@ module Groups
end
def check_observability_allowed
- render_404 unless Gitlab::Observability.observability_enabled?(current_user, group)
+ render_404 unless Gitlab::Observability.allowed_for_action?(current_user, group, params[:action])
end
end
end
diff --git a/app/controllers/ide_controller.rb b/app/controllers/ide_controller.rb
index d0e14000d8e..b61e2318cea 100644
--- a/app/controllers/ide_controller.rb
+++ b/app/controllers/ide_controller.rb
@@ -20,9 +20,8 @@ class IdeController < ApplicationController
def index
Gitlab::UsageDataCounters::WebIdeCounter.increment_views_count
- if project && Feature.enabled?(:route_hll_to_snowplow_phase2, project&.namespace)
- Gitlab::Tracking.event(self.class.to_s, 'web_ide_views',
- namespace: project&.namespace, user: current_user)
+ if project
+ Gitlab::Tracking.event(self.class.to_s, 'web_ide_views', namespace: project.namespace, user: current_user)
end
render layout: 'fullscreen', locals: { minimal: helpers.use_new_web_ide? }
diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb
index 8796fda572f..9df86e2c702 100644
--- a/app/controllers/search_controller.rb
+++ b/app/controllers/search_controller.rb
@@ -24,7 +24,7 @@ class SearchController < ApplicationController
before_action :block_anonymous_global_searches, :check_scope_global_search_enabled, except: :opensearch
skip_before_action :authenticate_user!
- skip_before_action :default_cache_headers, only: :count
+ skip_before_action :default_cache_headers, only: [:count, :autocomplete]
requires_cross_project_access if: -> do
search_term_present = params[:search].present? || params[:term].present?
@@ -116,6 +116,9 @@ class SearchController < ApplicationController
@ref = params[:project_ref] if params[:project_ref].present?
@filter = params[:filter]
+ # Cache the response on the frontend
+ expires_in 1.minute
+
render json: Gitlab::Json.dump(search_autocomplete_opts(term, filter: @filter))
end
diff --git a/app/graphql/mutations/alert_management/base.rb b/app/graphql/mutations/alert_management/base.rb
index 2eef6bb9db7..771ace5510f 100644
--- a/app/graphql/mutations/alert_management/base.rb
+++ b/app/graphql/mutations/alert_management/base.rb
@@ -45,8 +45,6 @@ module Mutations
namespace = project.namespace
track_usage_event(event, current_user.id)
- return unless Feature.enabled?(:route_hll_to_snowplow_phase2, namespace)
-
Gitlab::Tracking.event(
self.class.to_s,
event,
diff --git a/app/mailers/emails/profile.rb b/app/mailers/emails/profile.rb
index 5b1750400d8..a191bd4a8f6 100644
--- a/app/mailers/emails/profile.rb
+++ b/app/mailers/emails/profile.rb
@@ -153,7 +153,7 @@ module Emails
Gitlab::I18n.with_locale(@user.preferred_language) do
email_with_layout(
to: @user.notification_email_or_default,
- subject: subject(_("Attempted sign in to %{host} using a wrong two-factor authentication code") % { host: Gitlab.config.gitlab.host }))
+ subject: subject(_("Attempted sign in to %{host} using an incorrect verification code") % { host: Gitlab.config.gitlab.host }))
end
end
diff --git a/app/models/integrations/base_slack_notification.rb b/app/models/integrations/base_slack_notification.rb
index 7a2a91aa0d2..c83a559e0da 100644
--- a/app/models/integrations/base_slack_notification.rb
+++ b/app/models/integrations/base_slack_notification.rb
@@ -44,8 +44,6 @@ module Integrations
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(key, values: user_id)
- return unless Feature.enabled?(:route_hll_to_snowplow_phase2)
-
optional_arguments = {
project: project,
namespace: group || project&.namespace
diff --git a/app/models/integrations/jira.rb b/app/models/integrations/jira.rb
index d96a848c72e..a1cdd55ceae 100644
--- a/app/models/integrations/jira.rb
+++ b/app/models/integrations/jira.rb
@@ -391,8 +391,6 @@ module Integrations
Gitlab::UsageDataCounters::HLLRedisCounter.track_event(key, values: user.id)
- return unless Feature.enabled?(:route_hll_to_snowplow_phase2)
-
optional_arguments = {
project: project,
namespace: group || project&.namespace
diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb
index 6cc65248914..b560a5d914a 100644
--- a/app/policies/group_policy.rb
+++ b/app/policies/group_policy.rb
@@ -246,7 +246,9 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
rule { ~can?(:view_globally) }.prevent :request_access
rule { has_access }.prevent :request_access
- rule { owner & (~share_with_group_locked | ~has_parent | ~parent_share_with_group_locked | can_change_parent_share_with_group_lock) }.enable :change_share_with_group_lock
+ rule do
+ owner & (~share_with_group_locked | ~has_parent | ~parent_share_with_group_locked | can_change_parent_share_with_group_lock)
+ end.enable :change_share_with_group_lock
rule { developer & developer_maintainer_access }.enable :create_projects
rule { create_projects_disabled }.prevent :create_projects
@@ -325,6 +327,10 @@ class GroupPolicy < Namespaces::GroupProjectNamespaceSharedPolicy
enable :read_observability
end
+ rule { can?(:maintainer_access) & observability_enabled }.policy do
+ enable :admin_observability
+ end
+
rule { ~create_runner_workflow_enabled }.policy do
prevent :create_group_runners
end
diff --git a/app/services/concerns/incident_management/usage_data.rb b/app/services/concerns/incident_management/usage_data.rb
index 40183085344..775dea9b949 100644
--- a/app/services/concerns/incident_management/usage_data.rb
+++ b/app/services/concerns/incident_management/usage_data.rb
@@ -13,8 +13,6 @@ module IncidentManagement
namespace = target.try(:namespace)
project = target.try(:project)
- return unless Feature.enabled?(:route_hll_to_snowplow_phase2, target.try(:namespace))
-
Gitlab::Tracking.event(
self.class.to_s,
event,
diff --git a/app/services/event_create_service.rb b/app/services/event_create_service.rb
index d848f694598..c941febad57 100644
--- a/app/services/event_create_service.rb
+++ b/app/services/event_create_service.rb
@@ -278,8 +278,6 @@ class EventCreateService
end
def track_snowplow_event(action:, project:, user:, label:, property:)
- return unless Feature.enabled?(:route_hll_to_snowplow_phase2)
-
Gitlab::Tracking.event(
self.class.to_s,
action.to_s,
diff --git a/app/services/import_csv/base_service.rb b/app/services/import_csv/base_service.rb
index feb76425fb4..628c322db13 100644
--- a/app/services/import_csv/base_service.rb
+++ b/app/services/import_csv/base_service.rb
@@ -46,8 +46,9 @@ module ImportCsv
results[:error_lines].push(line_no)
end
end
- rescue ArgumentError, CSV::MalformedCSVError
+ rescue ArgumentError, CSV::MalformedCSVError => e
results[:parse_error] = true
+ results[:error_lines].push(e.line_number) if e.respond_to?(:line_number)
end
def with_csv_lines
diff --git a/app/services/incident_management/timeline_events/base_service.rb b/app/services/incident_management/timeline_events/base_service.rb
index e997d940ed4..75a3811af2d 100644
--- a/app/services/incident_management/timeline_events/base_service.rb
+++ b/app/services/incident_management/timeline_events/base_service.rb
@@ -29,8 +29,6 @@ module IncidentManagement
namespace = project.namespace
track_usage_event(event, user.id)
- return unless Feature.enabled?(:route_hll_to_snowplow_phase2, namespace)
-
Gitlab::Tracking.event(
self.class.to_s,
event,
diff --git a/app/services/issuable/import_csv/base_service.rb b/app/services/issuable/import_csv/base_service.rb
index 83cf5a67453..9ef9fb76e3c 100644
--- a/app/services/issuable/import_csv/base_service.rb
+++ b/app/services/issuable/import_csv/base_service.rb
@@ -21,7 +21,7 @@ module Issuable
headers.downcase! if headers
return if headers && headers.include?('title') && headers.include?('description')
- raise CSV::MalformedCSVError
+ raise CSV::MalformedCSVError.new('Invalid CSV format - missing required headers.', 1)
end
end
end
diff --git a/app/services/todo_service.rb b/app/services/todo_service.rb
index 42a8aca17d3..2025d438ae7 100644
--- a/app/services/todo_service.rb
+++ b/app/services/todo_service.rb
@@ -428,8 +428,6 @@ class TodoService
event = "incident_management_incident_todo"
track_usage_event(event, user.id)
- return unless Feature.enabled?(:route_hll_to_snowplow_phase2, namespace)
-
Gitlab::Tracking.event(
self.class.to_s,
event,
diff --git a/app/services/work_items/import_csv_service.rb b/app/services/work_items/import_csv_service.rb
new file mode 100644
index 00000000000..e93905b8ca5
--- /dev/null
+++ b/app/services/work_items/import_csv_service.rb
@@ -0,0 +1,50 @@
+# frozen_string_literal: true
+
+module WorkItems
+ class ImportCsvService < ImportCsv::BaseService
+ extend ::Gitlab::Utils::Override
+
+ NotAvailableError = StandardError.new('This feature is currently behind a feature flag and it is not available.')
+
+ def execute
+ raise NotAvailableError if ::Feature.disabled?(:import_export_work_items_csv, project)
+
+ super
+ end
+
+ def email_results_to_user
+ # todo as part of https://gitlab.com/gitlab-org/gitlab/-/issues/379153
+ end
+
+ private
+
+ def create_object(attributes)
+ super[:work_item]
+ end
+
+ def create_object_class
+ ::WorkItems::CreateService
+ end
+
+ override :attributes_for
+ def attributes_for(row)
+ {
+ title: row[:title],
+ work_item_type: WorkItems::Type.default_issue_type
+ }
+ end
+
+ override :validate_headers_presence!
+ def validate_headers_presence!(headers)
+ headers.downcase! if headers
+ return if headers && required_headers.all? { |rh| headers.include?(rh) }
+
+ required_headers_message = "Required headers are missing. Required headers are #{required_headers.join(', ')}"
+ raise CSV::MalformedCSVError.new(required_headers_message, 1)
+ end
+
+ def required_headers
+ %w[title].freeze
+ end
+ end
+end
diff --git a/app/views/admin/sessions/_two_factor_otp.html.haml b/app/views/admin/sessions/_two_factor_otp.html.haml
index 40ba79d1a65..037f0d5ecb1 100644
--- a/app/views/admin/sessions/_two_factor_otp.html.haml
+++ b/app/views/admin/sessions/_two_factor_otp.html.haml
@@ -1,9 +1,9 @@
= form_tag(admin_session_path, { method: :post, class: "edit_user gl-show-field-errors js-2fa-form #{'hidden' if current_user.two_factor_webauthn_u2f_enabled?}" }) do
.form-group
- = label_tag :user_otp_attempt, _('Two-Factor Authentication code')
- = text_field_tag 'user[otp_attempt]', nil, class: 'form-control', required: true, autofocus: true, autocomplete: 'off', title: _('This field is required.')
+ = label_tag :user_otp_attempt, _('Enter verification code')
+ = text_field_tag 'user[otp_attempt]', nil, class: 'form-control', required: true, autofocus: true, autocomplete: 'off', inputmode: 'numeric', title: _('This field is required.')
%p.form-text.text-muted.hint
- = _("Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes.")
+ = _("Enter the code from your two-factor authenticator app. If you've lost your device, you can enter one of your recovery codes.")
.submit-container.move-submit-down
= submit_tag 'Verify code', class: 'gl-button btn btn-confirm'
diff --git a/app/views/devise/sessions/two_factor.html.haml b/app/views/devise/sessions/two_factor.html.haml
index f63f1aa9197..25aeb25994e 100644
--- a/app/views/devise/sessions/two_factor.html.haml
+++ b/app/views/devise/sessions/two_factor.html.haml
@@ -7,9 +7,9 @@
- resource_params = params[resource_name].presence || params
= f.hidden_field :remember_me, value: resource_params.fetch(:remember_me, 0)
%div
- = f.label _('Two-Factor Authentication code'), name: :otp_attempt, class: Feature.enabled?(:restyle_login_page, @project) ? 'gl-mb-1' : ''
- = f.text_field :otp_attempt, class: 'form-control gl-form-input', required: true, autofocus: true, autocomplete: 'off', title: _('This field is required.'), data: { qa_selector: 'two_fa_code_field' }
- %p.form-text.text-muted.hint= _("Enter the code from the two-factor app on your mobile device. If you've lost your device, you may enter one of your recovery codes.")
+ = f.label _('Enter verification code'), name: :otp_attempt, class: Feature.enabled?(:restyle_login_page, @project) ? 'gl-mb-1' : ''
+ = f.text_field :otp_attempt, class: 'form-control gl-form-input', required: true, autofocus: true, autocomplete: 'off', inputmode: 'numeric', title: _('This field is required.'), data: { qa_selector: 'two_fa_code_field' }
+ %p.form-text.text-muted.hint= _("Enter the code from your two-factor authenticator app. If you've lost your device, you can enter one of your recovery codes.")
.prepend-top-20
= f.submit _("Verify code"), pajamas_button: true, data: { qa_selector: 'verify_code_button' }
- if @user.two_factor_webauthn_u2f_enabled?
diff --git a/app/views/notify/two_factor_otp_attempt_failed_email.html.haml b/app/views/notify/two_factor_otp_attempt_failed_email.html.haml
index 83f028af500..968d84f700d 100644
--- a/app/views/notify/two_factor_otp_attempt_failed_email.html.haml
+++ b/app/views/notify/two_factor_otp_attempt_failed_email.html.haml
@@ -9,7 +9,7 @@
%tr
%td{ style: "#{default_font}vertical-align:middle;color:#ffffff;text-align:center;" }
%span
- = _("We detected an attempt to sign in to your %{host} account using a wrong two-factor authentication code") % { host: Gitlab.config.gitlab.host }
+ = _("GitLab detected an attempt to sign in to your %{host} account using an incorrect verification code") % { host: Gitlab.config.gitlab.host }
%tr.spacer
%td{ style: spacer_style }
&nbsp;
@@ -43,7 +43,7 @@
%tr{ style: 'width:100%;' }
%td{ style: "#{default_style}text-align:center;" }
- password_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_url('user/profile/user_passwords', anchor: 'change-your-password') }
- = _('If you recently tried to sign in, but mistakenly entered a wrong two-factor authentication code, you may ignore this email.')
+ = _('If you recently tried to sign in, but mistakenly entered an incorrect verification code, you can ignore this email.')
- if password_authentication_enabled_for_web?
%p
diff --git a/app/views/notify/two_factor_otp_attempt_failed_email.text.haml b/app/views/notify/two_factor_otp_attempt_failed_email.text.haml
index 8718ab034ff..9760dd3d985 100644
--- a/app/views/notify/two_factor_otp_attempt_failed_email.text.haml
+++ b/app/views/notify/two_factor_otp_attempt_failed_email.text.haml
@@ -1,7 +1,7 @@
= _('Hi %{username}!') % { username: sanitize_name(@user.name) }
-= _('We detected an attempt to sign in to your %{host} account using a wrong two-factor authentication code, from the following IP address: %{ip}, at %{time}') % { host: Gitlab.config.gitlab.host, ip: @ip, time: @time }
+= _('GitLab detected an attempt to sign in to your %{host} account using an incorrect verification code from the following IP address: %{ip}, at %{time}') % { host: Gitlab.config.gitlab.host, ip: @ip, time: @time }
-= _('If you recently tried to sign in, but mistakenly entered a wrong two-factor authentication code, you may ignore this email.')
+= _('If you recently tried to sign in, but mistakenly entered an incorrect verification code, you can ignore this email.')
= _('If you did not recently try to sign in, you should immediately change your password: %{password_link}.') % { password_link: help_page_url('user/profile/user_passwords', anchor: 'change-your-password') }
= _('Make sure you choose a strong, unique password.')
diff --git a/app/views/profiles/two_factor_auths/show.html.haml b/app/views/profiles/two_factor_auths/show.html.haml
index 3add3af3c65..2d40a566608 100644
--- a/app/views/profiles/two_factor_auths/show.html.haml
+++ b/app/views/profiles/two_factor_auths/show.html.haml
@@ -59,8 +59,8 @@
= link_to _('Try the troubleshooting steps here.'), help_page_path('user/profile/account/two_factor_authentication.md', anchor: 'troubleshooting'), target: '_blank', rel: 'noopener noreferrer'
.form-group
- = label_tag :pin_code, _('Pin code'), class: "label-bold"
- = text_field_tag :pin_code, nil, class: "form-control gl-form-input", required: true, data: { qa_selector: 'pin_code_field' }
+ = label_tag :pin_code, _('Enter verification code'), class: "label-bold"
+ = text_field_tag :pin_code, nil, autocomplete: 'off', inputmode: 'numeric', class: "form-control gl-form-input", required: true, data: { qa_selector: 'pin_code_field' }
- if current_password_required?
.form-group
= label_tag :current_password, _('Current password'), class: 'label-bold'
diff --git a/app/views/projects/pipelines/charts.html.haml b/app/views/projects/pipelines/charts.html.haml
index e16a2235e53..968189ab310 100644
--- a/app/views/projects/pipelines/charts.html.haml
+++ b/app/views/projects/pipelines/charts.html.haml
@@ -1,4 +1,5 @@
- page_title _('CI/CD Analytics')
+- add_page_specific_style 'page_bundles/project_quality'
#js-project-pipelines-charts-app{ data: { project_path: @project.full_path,
should_render_dora_charts: should_render_dora_charts.to_s,
diff --git a/app/views/projects/settings/integrations/index.html.haml b/app/views/projects/settings/integrations/index.html.haml
index 2077d244b24..c316b4e9cac 100644
--- a/app/views/projects/settings/integrations/index.html.haml
+++ b/app/views/projects/settings/integrations/index.html.haml
@@ -2,6 +2,8 @@
- breadcrumb_title _('Integration Settings')
- page_title _('Integrations')
+= render 'shared/integrations/slack_notifications_deprecation_alert'
+
%section.js-search-settings-section
%h3= _('Integrations')
- integrations_link_start = '<a href="%{url}">'.html_safe % { url: help_page_url('user/project/integrations/index') }
diff --git a/app/views/shared/integrations/_slack_notifications_deprecation_alert.html.haml b/app/views/shared/integrations/_slack_notifications_deprecation_alert.html.haml
new file mode 100644
index 00000000000..1e19d74df4c
--- /dev/null
+++ b/app/views/shared/integrations/_slack_notifications_deprecation_alert.html.haml
@@ -0,0 +1,10 @@
+- if Gitlab.com? && Feature.enabled?(:integration_slack_app_notifications)
+ = render Pajamas::AlertComponent.new(title: _('Slack notifications integration is deprecated'),
+ variant: :warning,
+ dismissible: false,
+ alert_options: { class: 'gl-mt-5', data: { testid: "slack-notifications-deprecation" } }) do |c|
+ = c.body do
+ - help_page_link = help_page_url('user/project/integrations/gitlab_slack_application')
+ - learn_more_link = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: help_page_link }
+
+ = html_escape(s_('The Slack notifications integration is deprecated and will be removed in a future release. To continue to receive notifications from Slack, use the GitLab for Slack app instead. %{learn_more_link_start}Learn more%{link_end}.')) % { learn_more_link_start: learn_more_link, link_end: '</a>'.html_safe }
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index f95176da252..676a834d79d 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -140,8 +140,6 @@ class PostReceive
end
def emit_snowplow_event(project, user)
- return unless Feature.enabled?(:route_hll_to_snowplow_phase2, project.namespace)
-
metric_path = 'counts.source_code_pushes'
Gitlab::Tracking.event(
'PostReceive',