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:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-10-18 14:11:44 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-10-18 14:11:44 +0300
commit25989ab7ef1a444ed2abd5479f176d58e1d9462a (patch)
tree271bb24f3c7178f320cb9de0be0833a285327d09 /app
parent9bbb32b29703f3ce33dd35d5101145774b793a6d (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/monitoring/components/dashboard.vue71
-rw-r--r--app/assets/javascripts/monitoring/components/date_time_picker/date_time_picker.vue151
-rw-r--r--app/assets/javascripts/monitoring/components/date_time_picker/date_time_picker_input.vue77
-rw-r--r--app/assets/javascripts/monitoring/constants.js10
-rw-r--r--app/assets/javascripts/monitoring/utils.js47
-rw-r--r--app/assets/stylesheets/pages/prometheus.scss14
-rw-r--r--app/finders/issuable_finder.rb9
-rw-r--r--app/models/ci/pipeline.rb2
-rw-r--r--app/models/concerns/issuable.rb28
-rw-r--r--app/models/concerns/issuable_states.rb22
-rw-r--r--app/models/concerns/milestoneish.rb6
-rw-r--r--app/models/concerns/versioned_description.rb31
-rw-r--r--app/models/concerns/worker_attributes.rb48
-rw-r--r--app/models/description_version.rb22
-rw-r--r--app/models/issue.rb13
-rw-r--r--app/models/merge_request.rb27
-rw-r--r--app/models/merge_request_diff.rb4
-rw-r--r--app/models/project_services/hipchat_service.rb2
-rw-r--r--app/models/push_event.rb2
-rw-r--r--app/models/system_note_metadata.rb1
-rw-r--r--app/serializers/projects/serverless/service_entity.rb2
-rw-r--r--app/services/issuable/clone/content_rewriter.rb4
-rw-r--r--app/services/note_summary.rb4
-rw-r--r--app/uploaders/object_storage.rb9
-rw-r--r--app/views/projects/issues/index.html.haml3
-rw-r--r--app/views/shared/empty_states/_issues.html.haml3
-rw-r--r--app/workers/admin_email_worker.rb2
-rw-r--r--app/workers/authorized_projects_worker.rb2
-rw-r--r--app/workers/auto_merge_process_worker.rb1
-rw-r--r--app/workers/background_migration_worker.rb2
-rw-r--r--app/workers/build_hooks_worker.rb1
-rw-r--r--app/workers/build_queue_worker.rb1
-rw-r--r--app/workers/chat_notification_worker.rb2
-rw-r--r--app/workers/ci/archive_traces_cron_worker.rb2
-rw-r--r--app/workers/ci/build_prepare_worker.rb1
-rw-r--r--app/workers/ci/build_schedule_worker.rb1
-rw-r--r--app/workers/cleanup_container_repository_worker.rb1
-rw-r--r--app/workers/concerns/application_worker.rb1
-rw-r--r--app/workers/concerns/auto_devops_queue.rb1
-rw-r--r--app/workers/concerns/chaos_queue.rb1
-rw-r--r--app/workers/concerns/cluster_queue.rb1
-rw-r--r--app/workers/concerns/gitlab/github_import/object_importer.rb2
-rw-r--r--app/workers/concerns/gitlab/github_import/queue.rb1
-rw-r--r--app/workers/concerns/object_pool_queue.rb1
-rw-r--r--app/workers/concerns/pipeline_background_queue.rb1
-rw-r--r--app/workers/concerns/pipeline_queue.rb1
-rw-r--r--app/workers/concerns/repository_check_queue.rb2
-rw-r--r--app/workers/concerns/todos_destroyer_queue.rb1
-rw-r--r--app/workers/create_evidence_worker.rb2
-rw-r--r--app/workers/create_gpg_signature_worker.rb2
-rw-r--r--app/workers/create_note_diff_file_worker.rb2
-rw-r--r--app/workers/create_pipeline_worker.rb1
-rw-r--r--app/workers/delete_container_repository_worker.rb1
-rw-r--r--app/workers/delete_diff_files_worker.rb2
-rw-r--r--app/workers/delete_merged_branches_worker.rb2
-rw-r--r--app/workers/delete_stored_files_worker.rb2
-rw-r--r--app/workers/delete_user_worker.rb2
-rw-r--r--app/workers/deployments/finished_worker.rb1
-rw-r--r--app/workers/deployments/success_worker.rb1
-rw-r--r--app/workers/detect_repository_languages_worker.rb1
-rw-r--r--app/workers/email_receiver_worker.rb2
-rw-r--r--app/workers/emails_on_push_worker.rb2
-rw-r--r--app/workers/expire_build_artifacts_worker.rb2
-rw-r--r--app/workers/expire_build_instance_artifacts_worker.rb2
-rw-r--r--app/workers/git_garbage_collect_worker.rb1
-rw-r--r--app/workers/gitlab/github_import/advance_stage_worker.rb1
-rw-r--r--app/workers/gitlab_shell_worker.rb2
-rw-r--r--app/workers/gitlab_usage_ping_worker.rb2
-rw-r--r--app/workers/group_destroy_worker.rb2
-rw-r--r--app/workers/hashed_storage/base_worker.rb3
-rw-r--r--app/workers/hashed_storage/migrator_worker.rb1
-rw-r--r--app/workers/hashed_storage/rollbacker_worker.rb1
-rw-r--r--app/workers/import_export_project_cleanup_worker.rb2
-rw-r--r--app/workers/import_issues_csv_worker.rb2
-rw-r--r--app/workers/invalid_gpg_signature_update_worker.rb2
-rw-r--r--app/workers/irker_worker.rb2
-rw-r--r--app/workers/issue_due_scheduler_worker.rb2
-rw-r--r--app/workers/mail_scheduler/issue_due_worker.rb2
-rw-r--r--app/workers/mail_scheduler/notification_service_worker.rb2
-rw-r--r--app/workers/merge_worker.rb2
-rw-r--r--app/workers/migrate_external_diffs_worker.rb2
-rw-r--r--app/workers/namespaceless_project_destroy_worker.rb4
-rw-r--r--app/workers/namespaces/prune_aggregation_schedules_worker.rb2
-rw-r--r--app/workers/namespaces/root_statistics_worker.rb1
-rw-r--r--app/workers/namespaces/schedule_aggregation_worker.rb1
-rw-r--r--app/workers/new_issue_worker.rb2
-rw-r--r--app/workers/new_merge_request_worker.rb2
-rw-r--r--app/workers/new_note_worker.rb2
-rw-r--r--app/workers/new_release_worker.rb1
-rw-r--r--app/workers/object_storage/background_move_worker.rb1
-rw-r--r--app/workers/object_storage/migrate_uploads_worker.rb2
-rw-r--r--app/workers/pages_domain_removal_cron_worker.rb2
-rw-r--r--app/workers/pages_domain_ssl_renewal_cron_worker.rb2
-rw-r--r--app/workers/pages_domain_ssl_renewal_worker.rb2
-rw-r--r--app/workers/pages_domain_verification_cron_worker.rb2
-rw-r--r--app/workers/pages_domain_verification_worker.rb2
-rw-r--r--app/workers/pages_worker.rb1
-rw-r--r--app/workers/pipeline_process_worker.rb1
-rw-r--r--app/workers/pipeline_schedule_worker.rb2
-rw-r--r--app/workers/plugin_worker.rb1
-rw-r--r--app/workers/post_receive.rb2
-rw-r--r--app/workers/process_commit_worker.rb2
-rw-r--r--app/workers/project_cache_worker.rb2
-rw-r--r--app/workers/project_daily_statistics_worker.rb2
-rw-r--r--app/workers/project_destroy_worker.rb2
-rw-r--r--app/workers/project_export_worker.rb1
-rw-r--r--app/workers/project_service_worker.rb1
-rw-r--r--app/workers/propagate_service_template_worker.rb2
-rw-r--r--app/workers/prune_old_events_worker.rb2
-rw-r--r--app/workers/prune_web_hook_logs_worker.rb2
-rw-r--r--app/workers/reactive_caching_worker.rb2
-rw-r--r--app/workers/rebase_worker.rb2
-rw-r--r--app/workers/remote_mirror_notification_worker.rb2
-rw-r--r--app/workers/remove_expired_group_links_worker.rb2
-rw-r--r--app/workers/remove_expired_members_worker.rb2
-rw-r--r--app/workers/remove_unreferenced_lfs_objects_worker.rb2
-rw-r--r--app/workers/repository_archive_cache_worker.rb2
-rw-r--r--app/workers/repository_check/dispatch_worker.rb2
-rw-r--r--app/workers/repository_cleanup_worker.rb1
-rw-r--r--app/workers/repository_fork_worker.rb2
-rw-r--r--app/workers/repository_import_worker.rb2
-rw-r--r--app/workers/repository_remove_remote_worker.rb2
-rw-r--r--app/workers/repository_update_remote_mirror_worker.rb1
-rw-r--r--app/workers/requests_profiles_worker.rb2
-rw-r--r--app/workers/run_pipeline_schedule_worker.rb1
-rw-r--r--app/workers/schedule_migrate_external_diffs_worker.rb2
-rw-r--r--app/workers/stuck_ci_jobs_worker.rb2
-rw-r--r--app/workers/stuck_import_jobs_worker.rb2
-rw-r--r--app/workers/stuck_merge_jobs_worker.rb4
-rw-r--r--app/workers/system_hook_push_worker.rb2
-rw-r--r--app/workers/trending_projects_worker.rb2
-rw-r--r--app/workers/update_external_pull_requests_worker.rb2
-rw-r--r--app/workers/update_head_pipeline_for_merge_request_worker.rb1
-rw-r--r--app/workers/update_merge_requests_worker.rb2
-rw-r--r--app/workers/update_project_statistics_worker.rb2
-rw-r--r--app/workers/upload_checksum_worker.rb2
-rw-r--r--app/workers/web_hook_worker.rb1
137 files changed, 706 insertions, 95 deletions
diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue
index 2e35ef8d4b0..b4ea415bb51 100644
--- a/app/assets/javascripts/monitoring/components/dashboard.vue
+++ b/app/assets/javascripts/monitoring/components/dashboard.vue
@@ -12,23 +12,19 @@ import {
GlTooltipDirective,
} from '@gitlab/ui';
import { __, s__ } from '~/locale';
+import createFlash from '~/flash';
import Icon from '~/vue_shared/components/icon.vue';
-import { getParameterValues, mergeUrlParams } from '~/lib/utils/url_utility';
+import { getParameterValues, mergeUrlParams, redirectTo } from '~/lib/utils/url_utility';
import invalidUrl from '~/lib/utils/invalid_url';
import PanelType from 'ee_else_ce/monitoring/components/panel_type.vue';
+import DateTimePicker from './date_time_picker/date_time_picker.vue';
import MonitorTimeSeriesChart from './charts/time_series.vue';
import MonitorSingleStatChart from './charts/single_stat.vue';
import GraphGroup from './graph_group.vue';
import EmptyState from './empty_state.vue';
-import { sidebarAnimationDuration, timeWindows } from '../constants';
+import { sidebarAnimationDuration } from '../constants';
import TrackEventDirective from '~/vue_shared/directives/track_event';
-
-import {
- getTimeDiff,
- getTimeWindow,
- downloadCSVOptions,
- generateLinkToChartOptions,
-} from '../utils';
+import { getTimeDiff, isValidDate, downloadCSVOptions, generateLinkToChartOptions } from '../utils';
let sidebarMutationObserver;
@@ -46,6 +42,7 @@ export default {
GlDropdownItem,
GlFormGroup,
GlModal,
+ DateTimePicker,
},
directives: {
GlModal: GlModalDirective,
@@ -171,10 +168,8 @@ export default {
return {
state: 'gettingStarted',
elWidth: 0,
- selectedTimeWindow: '',
- selectedTimeWindowKey: '',
formIsValid: null,
- timeWindows: {},
+ selectedTimeWindow: {},
isRearrangingPanels: false,
};
},
@@ -237,11 +232,13 @@ export default {
end,
};
- this.timeWindows = timeWindows;
- this.selectedTimeWindowKey = getTimeWindow(range);
- this.selectedTimeWindow = this.timeWindows[this.selectedTimeWindowKey];
+ this.selectedTimeWindow = range;
- this.fetchData(range);
+ if (!isValidDate(start) || !isValidDate(end)) {
+ this.showInvalidDateError();
+ } else {
+ this.fetchData(range);
+ }
sidebarMutationObserver = new MutationObserver(this.onSidebarMutation);
sidebarMutationObserver.observe(document.querySelector('.layout-page'), {
@@ -298,6 +295,9 @@ export default {
// See https://gitlab.com/gitlab-org/gitlab/issues/27835
metrics.splice(graphIndex, 1);
},
+ showInvalidDateError() {
+ createFlash(s__('Metrics|Link contains an invalid time window.'));
+ },
generateLink(group, title, yLabel) {
const dashboard = this.currentDashboard || this.firstDashboard.path;
const params = _.pick({ dashboard, group, title, y_label: yLabel }, value => value != null);
@@ -320,16 +320,12 @@ export default {
submitCustomMetricsForm() {
this.$refs.customMetricsForm.submit();
},
- activeTimeWindow(key) {
- return this.timeWindows[key] === this.selectedTimeWindow;
- },
- setTimeWindowParameter(key) {
- const { start, end } = getTimeDiff(key);
- return `?start=${encodeURIComponent(start)}&end=${encodeURIComponent(end)}`;
- },
groupHasData(group) {
return this.chartsWithData(group.metrics).length > 0;
},
+ onDateTimePickerApply(timeWindowUrlParams) {
+ return redirectTo(mergeUrlParams(timeWindowUrlParams, window.location.href));
+ },
downloadCSVOptions,
generateLinkToChartOptions,
},
@@ -342,14 +338,14 @@ export default {
<template>
<div class="prometheus-graphs">
- <div class="gl-p-3 pb-0 border-bottom bg-gray-light">
+ <div class="prometheus-graphs-header gl-p-3 pb-0 border-bottom bg-gray-light">
<div class="row">
<template v-if="environmentsEndpoint">
<gl-form-group
:label="__('Dashboard')"
label-size="sm"
label-for="monitor-dashboards-dropdown"
- class="col-sm-12 col-md-4 col-lg-2"
+ class="col-sm-12 col-md-6 col-lg-2"
>
<gl-dropdown
id="monitor-dashboards-dropdown"
@@ -372,7 +368,7 @@ export default {
:label="s__('Metrics|Environment')"
label-size="sm"
label-for="monitor-environments-dropdown"
- class="col-sm-6 col-md-4 col-lg-2"
+ class="col-sm-6 col-md-6 col-lg-2"
>
<gl-dropdown
id="monitor-environments-dropdown"
@@ -397,30 +393,19 @@ export default {
:label="s__('Metrics|Show last')"
label-size="sm"
label-for="monitor-time-window-dropdown"
- class="col-sm-6 col-md-4 col-lg-2"
+ class="col-sm-6 col-md-6 col-lg-4"
>
- <gl-dropdown
- id="monitor-time-window-dropdown"
- class="mb-0 d-flex js-time-window-dropdown"
- toggle-class="dropdown-menu-toggle"
- :text="selectedTimeWindow"
- >
- <gl-dropdown-item
- v-for="(value, key) in timeWindows"
- :key="key"
- :active="activeTimeWindow(key)"
- :href="setTimeWindowParameter(key)"
- active-class="active"
- >{{ value }}</gl-dropdown-item
- >
- </gl-dropdown>
+ <date-time-picker
+ :selected-time-window="selectedTimeWindow"
+ @onApply="onDateTimePickerApply"
+ />
</gl-form-group>
</template>
<gl-form-group
v-if="addingMetricsAvailable || showRearrangePanelsBtn || externalDashboardUrl.length"
label-for="prometheus-graphs-dropdown-buttons"
- class="dropdown-buttons col-lg d-lg-flex align-items-end"
+ class="dropdown-buttons col-md d-md-flex col-lg d-lg-flex align-items-end"
>
<div id="prometheus-graphs-dropdown-buttons">
<gl-button
diff --git a/app/assets/javascripts/monitoring/components/date_time_picker/date_time_picker.vue b/app/assets/javascripts/monitoring/components/date_time_picker/date_time_picker.vue
new file mode 100644
index 00000000000..4616a767295
--- /dev/null
+++ b/app/assets/javascripts/monitoring/components/date_time_picker/date_time_picker.vue
@@ -0,0 +1,151 @@
+<script>
+import { GlButton, GlDropdown, GlDropdownItem, GlFormGroup } from '@gitlab/ui';
+import { s__, sprintf } from '~/locale';
+import Icon from '~/vue_shared/components/icon.vue';
+import DateTimePickerInput from './date_time_picker_input.vue';
+import {
+ getTimeDiff,
+ getTimeWindow,
+ stringToISODate,
+ ISODateToString,
+ truncateZerosInDateTime,
+ isDateTimePickerInputValid,
+} from '~/monitoring/utils';
+import { timeWindows } from '~/monitoring/constants';
+
+export default {
+ components: {
+ Icon,
+ DateTimePickerInput,
+ GlFormGroup,
+ GlButton,
+ GlDropdown,
+ GlDropdownItem,
+ },
+ props: {
+ timeWindows: {
+ type: Object,
+ required: false,
+ default: () => timeWindows,
+ },
+ selectedTimeWindow: {
+ type: Object,
+ required: false,
+ default: () => {},
+ },
+ },
+ data() {
+ return {
+ selectedTimeWindowText: '',
+ customTime: {
+ from: null,
+ to: null,
+ },
+ };
+ },
+ computed: {
+ applyEnabled() {
+ return Boolean(this.inputState.from && this.inputState.to);
+ },
+ inputState() {
+ const { from, to } = this.customTime;
+ return {
+ from: from && isDateTimePickerInputValid(from),
+ to: to && isDateTimePickerInputValid(to),
+ };
+ },
+ },
+ mounted() {
+ const range = getTimeWindow(this.selectedTimeWindow);
+ if (range) {
+ this.selectedTimeWindowText = this.timeWindows[range];
+ } else {
+ this.customTime = {
+ from: truncateZerosInDateTime(ISODateToString(this.selectedTimeWindow.start)),
+ to: truncateZerosInDateTime(ISODateToString(this.selectedTimeWindow.end)),
+ };
+ this.selectedTimeWindowText = sprintf(s__('%{from} to %{to}'), this.customTime);
+ }
+ },
+ methods: {
+ activeTimeWindow(key) {
+ return this.timeWindows[key] === this.selectedTimeWindowText;
+ },
+ setCustomTimeWindowParameter() {
+ this.$emit('onApply', {
+ start: stringToISODate(this.customTime.from),
+ end: stringToISODate(this.customTime.to),
+ });
+ },
+ setTimeWindowParameter(key) {
+ const { start, end } = getTimeDiff(key);
+ this.$emit('onApply', {
+ start,
+ end,
+ });
+ },
+ closeDropdown() {
+ this.$refs.dropdown.hide();
+ },
+ },
+};
+</script>
+<template>
+ <gl-dropdown
+ ref="dropdown"
+ :text="selectedTimeWindowText"
+ menu-class="time-window-dropdown-menu"
+ class="js-time-window-dropdown"
+ >
+ <div class="d-flex justify-content-between time-window-dropdown-menu-container">
+ <gl-form-group
+ :label="__('Custom range')"
+ label-for="custom-from-time"
+ class="custom-time-range-form-group col-md-7 p-0 m-0"
+ >
+ <date-time-picker-input
+ id="custom-time-from"
+ v-model="customTime.from"
+ :label="__('From')"
+ :state="inputState.from"
+ />
+ <date-time-picker-input
+ id="custom-time-to"
+ v-model="customTime.to"
+ :label="__('To')"
+ :state="inputState.to"
+ />
+ <gl-form-group>
+ <gl-button @click="closeDropdown">{{ __('Cancel') }}</gl-button>
+ <gl-button
+ variant="success"
+ :disabled="!applyEnabled"
+ @click="setCustomTimeWindowParameter"
+ >{{ __('Apply') }}</gl-button
+ >
+ </gl-form-group>
+ </gl-form-group>
+ <gl-form-group
+ :label="__('Quick range')"
+ label-for="group-id-dropdown"
+ label-align="center"
+ class="col-md-4 p-0 m-0"
+ >
+ <gl-dropdown-item
+ v-for="(value, key) in timeWindows"
+ :key="key"
+ :active="activeTimeWindow(key)"
+ active-class="active"
+ @click="setTimeWindowParameter(key)"
+ >
+ <icon
+ name="mobile-issue-close"
+ class="align-bottom"
+ :class="{ invisible: !activeTimeWindow(key) }"
+ />
+ {{ value }}
+ </gl-dropdown-item>
+ </gl-form-group>
+ </div>
+ </gl-dropdown>
+</template>
diff --git a/app/assets/javascripts/monitoring/components/date_time_picker/date_time_picker_input.vue b/app/assets/javascripts/monitoring/components/date_time_picker/date_time_picker_input.vue
new file mode 100644
index 00000000000..0388a6190d9
--- /dev/null
+++ b/app/assets/javascripts/monitoring/components/date_time_picker/date_time_picker_input.vue
@@ -0,0 +1,77 @@
+<script>
+import _ from 'underscore';
+import { s__, sprintf } from '~/locale';
+import { GlFormGroup, GlFormInput } from '@gitlab/ui';
+import { dateFormats } from '~/monitoring/constants';
+
+const inputGroupText = {
+ invalidFeedback: sprintf(s__('Format: %{dateFormat}'), {
+ dateFormat: dateFormats.dateTimePicker.format,
+ }),
+ placeholder: dateFormats.dateTimePicker.format,
+};
+
+export default {
+ components: {
+ GlFormGroup,
+ GlFormInput,
+ },
+ props: {
+ state: {
+ default: null,
+ required: true,
+ validator: prop => typeof prop === 'boolean' || prop === null,
+ },
+ value: {
+ default: null,
+ required: false,
+ validator: prop => typeof prop === 'string' || prop === null,
+ },
+ label: {
+ type: String,
+ default: '',
+ required: true,
+ },
+ id: {
+ type: String,
+ required: false,
+ default: () => _.uniqueId('dateTimePicker_'),
+ },
+ },
+ data() {
+ return {
+ inputGroupText,
+ };
+ },
+ computed: {
+ invalidFeedback() {
+ return this.state ? '' : this.inputGroupText.invalidFeedback;
+ },
+ inputState() {
+ // When the state is valid we want to show no
+ // green outline. Hence passing null and not true.
+ if (this.state === true) {
+ return null;
+ }
+ return this.state;
+ },
+ },
+ methods: {
+ onInputBlur(e) {
+ this.$emit('input', e.target.value.trim() || null);
+ },
+ },
+};
+</script>
+
+<template>
+ <gl-form-group :label="label" label-size="sm" :label-for="id" :invalid-feedback="invalidFeedback">
+ <gl-form-input
+ :id="id"
+ :value="value"
+ :state="inputState"
+ :placeholder="inputGroupText.placeholder"
+ @blur="onInputBlur"
+ />
+ </gl-form-group>
+</template>
diff --git a/app/assets/javascripts/monitoring/constants.js b/app/assets/javascripts/monitoring/constants.js
index 13aba3d9f44..2836fe4fc26 100644
--- a/app/assets/javascripts/monitoring/constants.js
+++ b/app/assets/javascripts/monitoring/constants.js
@@ -3,6 +3,11 @@ import { __ } from '~/locale';
export const sidebarAnimationDuration = 300; // milliseconds.
export const chartHeight = 300;
+/**
+ * Valid strings for this regex are
+ * 2019-10-01 and 2019-10-01 01:02:03
+ */
+export const dateTimePickerRegex = /^(\d{4})-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])(?: (0[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]))?$/;
export const graphTypes = {
deploymentData: 'scatter',
@@ -28,6 +33,11 @@ export const timeWindows = {
export const dateFormats = {
timeOfDay: 'h:MM TT',
default: 'dd mmm yyyy, h:MMTT',
+ dateTimePicker: {
+ format: 'yyyy-mm-dd hh:mm:ss',
+ ISODate: "yyyy-mm-dd'T'HH:MM:ss'Z'",
+ stringDate: 'yyyy-mm-dd HH:MM:ss',
+ },
};
export const secondsIn = {
diff --git a/app/assets/javascripts/monitoring/utils.js b/app/assets/javascripts/monitoring/utils.js
index 9049695b992..4c72f5226b7 100644
--- a/app/assets/javascripts/monitoring/utils.js
+++ b/app/assets/javascripts/monitoring/utils.js
@@ -1,4 +1,5 @@
-import { secondsIn, timeWindowsKeyNames } from './constants';
+import dateformat from 'dateformat';
+import { secondsIn, dateTimePickerRegex, dateFormats } from './constants';
const secondsToMilliseconds = seconds => seconds * 1000;
@@ -19,7 +20,49 @@ export const getTimeWindow = ({ start, end }) =>
return timeRange;
}
return acc;
- }, timeWindowsKeyNames.eightHours);
+ }, null);
+
+export const isDateTimePickerInputValid = val => dateTimePickerRegex.test(val);
+
+export const truncateZerosInDateTime = datetime => datetime.replace(' 00:00:00', '');
+
+/**
+ * The URL params start and end need to be validated
+ * before passing them down to other components.
+ *
+ * @param {string} dateString
+ */
+export const isValidDate = dateString => {
+ try {
+ // dateformat throws error that can be caught.
+ // This is better than using `new Date()`
+ if (dateString && dateString.trim()) {
+ dateformat(dateString, 'isoDateTime');
+ return true;
+ }
+ return false;
+ } catch {
+ return false;
+ }
+};
+
+/**
+ * Convert the input in Time picker component to ISO date.
+ *
+ * @param {string} val
+ * @returns {string}
+ */
+export const stringToISODate = val =>
+ dateformat(new Date(val.replace(/-/g, '/')), dateFormats.dateTimePicker.ISODate, true);
+
+/**
+ * Convert the ISO date received from the URL to string
+ * for the Time picker component.
+ *
+ * @param {Date} date
+ * @returns {string}
+ */
+export const ISODateToString = date => dateformat(date, dateFormats.dateTimePicker.stringDate);
/**
* This method is used to validate if the graph data format for a chart component
diff --git a/app/assets/stylesheets/pages/prometheus.scss b/app/assets/stylesheets/pages/prometheus.scss
index ceafff94719..154e505f7a4 100644
--- a/app/assets/stylesheets/pages/prometheus.scss
+++ b/app/assets/stylesheets/pages/prometheus.scss
@@ -46,6 +46,20 @@
}
}
+.prometheus-graphs-header {
+ .time-window-dropdown-menu {
+ padding: $gl-padding $gl-padding 0 $gl-padding-12;
+ }
+
+ .time-window-dropdown-menu-container {
+ width: 360px;
+ }
+
+ .custom-time-range-form-group > label {
+ padding-bottom: $gl-padding;
+ }
+}
+
.prometheus-panel {
margin-top: 20px;
}
diff --git a/app/finders/issuable_finder.rb b/app/finders/issuable_finder.rb
index 2364777cdc5..477093ddadf 100644
--- a/app/finders/issuable_finder.rb
+++ b/app/finders/issuable_finder.rb
@@ -161,7 +161,7 @@ class IssuableFinder
labels_count = label_names.any? ? label_names.count : 1
labels_count = 1 if use_cte_for_search?
- finder.execute.reorder(nil).group(:state).count.each do |key, value|
+ finder.execute.reorder(nil).group(:state_id).count.each do |key, value|
counts[count_key(key)] += value / labels_count
end
@@ -385,7 +385,8 @@ class IssuableFinder
end
def count_key(value)
- Array(value).last.to_sym
+ value = Array(value).last
+ klass.available_states.key(value)
end
# Negates all params found in `negatable_params`
@@ -444,7 +445,6 @@ class IssuableFinder
items
end
- # rubocop: disable CodeReuse/ActiveRecord
def by_state(items)
case params[:state].to_s
when 'closed'
@@ -454,12 +454,11 @@ class IssuableFinder
when 'opened'
items.opened
when 'locked'
- items.where(state: 'locked')
+ items.with_state(:locked)
else
items
end
end
- # rubocop: enable CodeReuse/ActiveRecord
def by_group(items)
# Selection by group is already covered by `by_project` and `projects`
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 5e52062ef40..3bf19399cec 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -217,6 +217,8 @@ module Ci
scope :for_sha, -> (sha) { where(sha: sha) }
scope :for_source_sha, -> (source_sha) { where(source_sha: source_sha) }
scope :for_sha_or_source_sha, -> (sha) { for_sha(sha).or(for_source_sha(sha)) }
+ scope :for_ref, -> (ref) { where(ref: ref) }
+ scope :for_id, -> (id) { where(id: id) }
scope :created_after, -> (time) { where('ci_pipelines.created_at > ?', time) }
scope :triggered_by_merge_request, -> (merge_request) do
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index 94a0de556f4..852576dbbc2 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -25,12 +25,20 @@ module Issuable
include UpdatedAtFilterable
include IssuableStates
include ClosedAtFilterable
+ include VersionedDescription
TITLE_LENGTH_MAX = 255
TITLE_HTML_LENGTH_MAX = 800
DESCRIPTION_LENGTH_MAX = 1.megabyte
DESCRIPTION_HTML_LENGTH_MAX = 5.megabytes
+ STATE_ID_MAP = {
+ opened: 1,
+ closed: 2,
+ merged: 3,
+ locked: 4
+ }.with_indifferent_access.freeze
+
# This object is used to gather issuable meta data for displaying
# upvotes, downvotes, notes and closing merge requests count for issues and merge requests
# lists avoiding n+1 queries and improving performance.
@@ -172,13 +180,17 @@ module Issuable
fuzzy_search(query, [:title])
end
- # Available state values persisted in state_id column using state machine
+ def available_states
+ @available_states ||= STATE_ID_MAP.slice(*available_state_names)
+ end
+
+ # Available state names used to persist state_id column using state machine
#
# Override this on subclasses if different states are needed
#
- # Check MergeRequest.available_states for example
- def available_states
- @available_states ||= { opened: 1, closed: 2 }.with_indifferent_access
+ # Check MergeRequest.available_states_names for example
+ def available_state_names
+ [:opened, :closed]
end
# Searches for records with a matching title or description.
@@ -297,6 +309,14 @@ module Issuable
end
end
+ def state
+ self.class.available_states.key(state_id)
+ end
+
+ def state=(value)
+ self.state_id = self.class.available_states[value]
+ end
+
def resource_parent
project
end
diff --git a/app/models/concerns/issuable_states.rb b/app/models/concerns/issuable_states.rb
index 33bc41d7f44..f0b9f0d1f3a 100644
--- a/app/models/concerns/issuable_states.rb
+++ b/app/models/concerns/issuable_states.rb
@@ -4,22 +4,20 @@ module IssuableStates
extend ActiveSupport::Concern
# The state:string column is being migrated to state_id:integer column
- # This is a temporary hook to populate state_id column with new values
- # and should be removed after the state column is removed.
- # Check https://gitlab.com/gitlab-org/gitlab-foss/issues/51789 for more information
+ # This is a temporary hook to keep state column in sync until it is removed.
+ # Check https: https://gitlab.com/gitlab-org/gitlab/issues/33814 for more information
+ # The state column can be safely removed after 2019-10-27
included do
- before_save :set_state_id
+ before_save :sync_issuable_deprecated_state
end
- def set_state_id
- return if state.nil? || state.empty?
+ def sync_issuable_deprecated_state
+ return if self.is_a?(Epic)
+ return unless respond_to?(:state)
+ return if state_id.nil?
- # Needed to prevent breaking some migration specs that
- # rollback database to a point where state_id does not exist.
- # We can use this guard clause for now since this file will
- # be removed in the next release.
- return unless self.has_attribute?(:state_id)
+ deprecated_state = self.class.available_states.key(state_id)
- self.state_id = self.class.available_states[state]
+ self.write_attribute(:state, deprecated_state)
end
end
diff --git a/app/models/concerns/milestoneish.rb b/app/models/concerns/milestoneish.rb
index 3deb86da6cf..42b370990ac 100644
--- a/app/models/concerns/milestoneish.rb
+++ b/app/models/concerns/milestoneish.rb
@@ -6,7 +6,9 @@ module Milestoneish
end
def closed_issues_count(user)
- count_issues_by_state(user)['closed'].to_i
+ closed_state_id = Issue.available_states[:closed]
+
+ count_issues_by_state(user)[closed_state_id].to_i
end
def complete?(user)
@@ -117,7 +119,7 @@ module Milestoneish
def count_issues_by_state(user)
memoize_per_user(user, :count_issues_by_state) do
- issues_visible_to_user(user).reorder(nil).group(:state).count
+ issues_visible_to_user(user).reorder(nil).group(:state_id).count
end
end
diff --git a/app/models/concerns/versioned_description.rb b/app/models/concerns/versioned_description.rb
new file mode 100644
index 00000000000..63a24aadc8a
--- /dev/null
+++ b/app/models/concerns/versioned_description.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+module VersionedDescription
+ extend ActiveSupport::Concern
+
+ included do
+ attr_accessor :saved_description_version
+
+ has_many :description_versions
+
+ after_update :save_description_version
+ end
+
+ private
+
+ def save_description_version
+ self.saved_description_version = nil
+
+ return unless Feature.enabled?(:save_description_versions, issuing_parent)
+ return unless saved_change_to_description?
+
+ unless description_versions.exists?
+ description_versions.create!(
+ description: description_before_last_save,
+ created_at: created_at
+ )
+ end
+
+ self.saved_description_version = description_versions.create!(description: description)
+ end
+end
diff --git a/app/models/concerns/worker_attributes.rb b/app/models/concerns/worker_attributes.rb
new file mode 100644
index 00000000000..af40e9e3b19
--- /dev/null
+++ b/app/models/concerns/worker_attributes.rb
@@ -0,0 +1,48 @@
+# frozen_string_literal: true
+
+module WorkerAttributes
+ extend ActiveSupport::Concern
+
+ class_methods do
+ def feature_category(value)
+ raise "Invalid category. Use `feature_category_not_owned!` to mark a worker as not owned" if value == :not_owned
+
+ worker_attributes[:feature_category] = value
+ end
+
+ # Special case: mark this work as not associated with a feature category
+ # this should be used for cross-cutting concerns, such as mailer workers.
+ def feature_category_not_owned!
+ worker_attributes[:feature_category] = :not_owned
+ end
+
+ def get_feature_category
+ get_worker_attribute(:feature_category)
+ end
+
+ def feature_category_not_owned?
+ get_worker_attribute(:feature_category) == :not_owned
+ end
+
+ protected
+
+ # Returns a worker attribute declared on this class or its parent class.
+ # This approach allows declared attributes to be inherited by
+ # child classes.
+ def get_worker_attribute(name)
+ worker_attributes[name] || superclass_worker_attributes(name)
+ end
+
+ private
+
+ def worker_attributes
+ @attributes ||= {}
+ end
+
+ def superclass_worker_attributes(name)
+ return unless superclass.include? WorkerAttributes
+
+ superclass.get_worker_attribute(name)
+ end
+ end
+end
diff --git a/app/models/description_version.rb b/app/models/description_version.rb
new file mode 100644
index 00000000000..abab7f94212
--- /dev/null
+++ b/app/models/description_version.rb
@@ -0,0 +1,22 @@
+# frozen_string_literal: true
+
+class DescriptionVersion < ApplicationRecord
+ belongs_to :issue
+ belongs_to :merge_request
+
+ validate :exactly_one_issuable
+
+ def self.issuable_attrs
+ %i(issue merge_request).freeze
+ end
+
+ private
+
+ def exactly_one_issuable
+ issuable_count = self.class.issuable_attrs.count { |attr| self["#{attr}_id"] }
+
+ errors.add(:base, "Exactly one of #{self.class.issuable_attrs.join(', ')} is required") if issuable_count != 1
+ end
+end
+
+DescriptionVersion.prepend_if_ee('EE::DescriptionVersion')
diff --git a/app/models/issue.rb b/app/models/issue.rb
index d0b2165fcc7..b9b481ac29b 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -71,7 +71,7 @@ class Issue < ApplicationRecord
attr_spammable :title, spam_title: true
attr_spammable :description, spam_description: true
- state_machine :state, initial: :opened do
+ state_machine :state_id, initial: :opened do
event :close do
transition [:opened] => :closed
end
@@ -80,8 +80,8 @@ class Issue < ApplicationRecord
transition closed: :opened
end
- state :opened
- state :closed
+ state :opened, value: Issue.available_states[:opened]
+ state :closed, value: Issue.available_states[:closed]
before_transition any => :closed do |issue|
issue.closed_at = issue.system_note_timestamp
@@ -93,6 +93,13 @@ class Issue < ApplicationRecord
end
end
+ # Alias to state machine .with_state_id method
+ # This needs to be defined after the state machine block to avoid errors
+ class << self
+ alias_method :with_state, :with_state_id
+ alias_method :with_states, :with_state_ids
+ end
+
def self.relative_positioning_query_base(issue)
in_projects(issue.parent_ids)
end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 50efe5d6aa0..7cdaa3e3ca7 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -85,7 +85,13 @@ class MergeRequest < ApplicationRecord
# when creating new merge request
attr_accessor :can_be_created, :compare_commits, :diff_options, :compare
- state_machine :state, initial: :opened do
+ # Keep states definition to be evaluated before the state_machine block to avoid spec failures.
+ # If this gets evaluated after, the `merged` and `locked` states which are overrided can be nil.
+ def self.available_state_names
+ super + [:merged, :locked]
+ end
+
+ state_machine :state_id, initial: :opened do
event :close do
transition [:opened] => :closed
end
@@ -116,10 +122,17 @@ class MergeRequest < ApplicationRecord
end
end
- state :opened
- state :closed
- state :merged
- state :locked
+ state :opened, value: MergeRequest.available_states[:opened]
+ state :closed, value: MergeRequest.available_states[:closed]
+ state :merged, value: MergeRequest.available_states[:merged]
+ state :locked, value: MergeRequest.available_states[:locked]
+ end
+
+ # Alias to state machine .with_state_id method
+ # This needs to be defined after the state machine block to avoid errors
+ class << self
+ alias_method :with_state, :with_state_id
+ alias_method :with_states, :with_state_ids
end
state_machine :merge_status, initial: :unchecked do
@@ -211,10 +224,6 @@ class MergeRequest < ApplicationRecord
'!'
end
- def self.available_states
- @available_states ||= super.merge(merged: 3, locked: 4)
- end
-
# Returns the top 100 target branches
#
# The returned value is a Array containing branch names
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index fe8ba9765b7..735ad046f22 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -83,7 +83,7 @@ class MergeRequestDiff < ApplicationRecord
metrics_join = mr_diffs.join(mr_metrics).on(metrics_join_condition)
- condition = MergeRequest.arel_table[:state].eq(:merged)
+ condition = MergeRequest.arel_table[:state_id].eq(MergeRequest.available_states[:merged])
.and(MergeRequest::Metrics.arel_table[:merged_at].lteq(before))
.and(MergeRequest::Metrics.arel_table[:merged_at].not_eq(nil))
@@ -91,7 +91,7 @@ class MergeRequestDiff < ApplicationRecord
end
scope :old_closed_diffs, -> (before) do
- condition = MergeRequest.arel_table[:state].eq(:closed)
+ condition = MergeRequest.arel_table[:state_id].eq(MergeRequest.available_states[:closed])
.and(MergeRequest::Metrics.arel_table[:latest_closed_at].lteq(before))
joins(merge_request: :metrics).where(condition)
diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb
index 1d0b37abf72..019bd54f48c 100644
--- a/app/models/project_services/hipchat_service.rb
+++ b/app/models/project_services/hipchat_service.rb
@@ -161,7 +161,7 @@ class HipchatService < Service
obj_attr = data[:object_attributes]
obj_attr = HashWithIndifferentAccess.new(obj_attr)
title = render_line(obj_attr[:title])
- state = obj_attr[:state]
+ state = Issue.available_states.key(obj_attr[:state_id])
issue_iid = obj_attr[:iid]
issue_url = obj_attr[:url]
description = obj_attr[:description]
diff --git a/app/models/push_event.rb b/app/models/push_event.rb
index 6f7365a2763..5cab686f20b 100644
--- a/app/models/push_event.rb
+++ b/app/models/push_event.rb
@@ -54,7 +54,7 @@ class PushEvent < Event
.select(1)
.where('merge_requests.source_project_id = events.project_id')
.where('merge_requests.source_branch = push_event_payloads.ref')
- .where(state: :opened)
+ .with_state(:opened)
# For reasons unknown the use of #eager_load will result in the
# "push_event_payload" association not being set. Because of this we're
diff --git a/app/models/system_note_metadata.rb b/app/models/system_note_metadata.rb
index 8ec90ca25d3..11cbeb60bba 100644
--- a/app/models/system_note_metadata.rb
+++ b/app/models/system_note_metadata.rb
@@ -23,6 +23,7 @@ class SystemNoteMetadata < ApplicationRecord
validates :action, inclusion: { in: :icon_types }, allow_nil: true
belongs_to :note
+ belongs_to :description_version
def icon_types
ICON_TYPES
diff --git a/app/serializers/projects/serverless/service_entity.rb b/app/serializers/projects/serverless/service_entity.rb
index 40ac52d96af..a1e0bf02d11 100644
--- a/app/serializers/projects/serverless/service_entity.rb
+++ b/app/serializers/projects/serverless/service_entity.rb
@@ -44,7 +44,7 @@ module Projects
end
expose :url do |service|
- service.dig('status', 'url')
+ service.dig('status', 'url') || "http://#{service.dig('status', 'domain')}"
end
expose :description do |service|
diff --git a/app/services/issuable/clone/content_rewriter.rb b/app/services/issuable/clone/content_rewriter.rb
index f75b51c4be3..67d2f9fd3fe 100644
--- a/app/services/issuable/clone/content_rewriter.rb
+++ b/app/services/issuable/clone/content_rewriter.rb
@@ -39,6 +39,10 @@ module Issuable
if note.system_note_metadata
new_params[:system_note_metadata] = note.system_note_metadata.dup
+
+ # TODO: Implement copying of description versions when an issue is moved
+ # https://gitlab.com/gitlab-org/gitlab/issues/32300
+ new_params[:system_note_metadata].description_version = nil
end
new_note.update(new_params)
diff --git a/app/services/note_summary.rb b/app/services/note_summary.rb
index 60a68568833..6fe14939aaa 100644
--- a/app/services/note_summary.rb
+++ b/app/services/note_summary.rb
@@ -10,6 +10,10 @@ class NoteSummary
project: project, author: author, note: body }
@metadata = { action: action, commit_count: commit_count }.compact
+ if action == 'description' && noteable.saved_description_version
+ @metadata[:description_version] = noteable.saved_description_version
+ end
+
set_commit_params if note[:noteable].is_a?(Commit)
end
diff --git a/app/uploaders/object_storage.rb b/app/uploaders/object_storage.rb
index f99ad987156..36bde629f9c 100644
--- a/app/uploaders/object_storage.rb
+++ b/app/uploaders/object_storage.rb
@@ -180,10 +180,11 @@ module ObjectStorage
end
def workhorse_authorize(has_length:, maximum_size: nil)
- {
- RemoteObject: workhorse_remote_upload_options(has_length: has_length, maximum_size: maximum_size),
- TempPath: workhorse_local_upload_path
- }.compact
+ if self.object_store_enabled? && self.direct_upload_enabled?
+ { RemoteObject: workhorse_remote_upload_options(has_length: has_length, maximum_size: maximum_size) }
+ else
+ { TempPath: workhorse_local_upload_path }
+ end
end
def workhorse_local_upload_path
diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml
index 49e482ff1df..2633a3899f7 100644
--- a/app/views/projects/issues/index.html.haml
+++ b/app/views/projects/issues/index.html.haml
@@ -20,4 +20,5 @@
- if new_issue_email
= render 'projects/issuable_by_email', email: new_issue_email, issuable_type: 'issue'
- else
- = render 'shared/empty_states/issues', button_path: new_project_issue_path(@project), show_import_button: true
+ - new_project_issue_button_path = @project.archived? ? false : new_project_issue_path(@project)
+ = render 'shared/empty_states/issues', new_project_issue_button_path: new_project_issue_button_path, show_import_button: true
diff --git a/app/views/shared/empty_states/_issues.html.haml b/app/views/shared/empty_states/_issues.html.haml
index 9173b802dd4..325e01bb5c8 100644
--- a/app/views/shared/empty_states/_issues.html.haml
+++ b/app/views/shared/empty_states/_issues.html.haml
@@ -1,4 +1,4 @@
-- button_path = local_assigns.fetch(:button_path, false)
+- button_path = local_assigns.fetch(:new_project_issue_button_path, false)
- project_select_button = local_assigns.fetch(:project_select_button, false)
- show_import_button = local_assigns.fetch(:show_import_button, false) && can?(current_user, :import_issues, @project)
- has_button = button_path || project_select_button
@@ -56,4 +56,3 @@
- if show_import_button
= render 'projects/issues/import_csv/modal'
-
diff --git a/app/workers/admin_email_worker.rb b/app/workers/admin_email_worker.rb
index f69e74b2674..be05d2a6752 100644
--- a/app/workers/admin_email_worker.rb
+++ b/app/workers/admin_email_worker.rb
@@ -4,6 +4,8 @@ class AdminEmailWorker
include ApplicationWorker
include CronjobQueue
+ feature_category_not_owned!
+
def perform
send_repository_check_mail if Gitlab::CurrentSettings.repository_checks_enabled
end
diff --git a/app/workers/authorized_projects_worker.rb b/app/workers/authorized_projects_worker.rb
index c9ddeb08613..577c439f4a2 100644
--- a/app/workers/authorized_projects_worker.rb
+++ b/app/workers/authorized_projects_worker.rb
@@ -4,6 +4,8 @@ class AuthorizedProjectsWorker
include ApplicationWorker
prepend WaitableWorker
+ feature_category :authentication_and_authorization
+
# This is a workaround for a Ruby 2.3.7 bug. rspec-mocks cannot restore the
# visibility of prepended modules. See https://github.com/rspec/rspec-mocks/issues/1231
# for more details.
diff --git a/app/workers/auto_merge_process_worker.rb b/app/workers/auto_merge_process_worker.rb
index cd81cdbc60c..e4dccb891ce 100644
--- a/app/workers/auto_merge_process_worker.rb
+++ b/app/workers/auto_merge_process_worker.rb
@@ -4,6 +4,7 @@ class AutoMergeProcessWorker
include ApplicationWorker
queue_namespace :auto_merge
+ feature_category :continuous_delivery
def perform(merge_request_id)
MergeRequest.find_by_id(merge_request_id).try do |merge_request|
diff --git a/app/workers/background_migration_worker.rb b/app/workers/background_migration_worker.rb
index b83412b5e6e..20e2cdd7f96 100644
--- a/app/workers/background_migration_worker.rb
+++ b/app/workers/background_migration_worker.rb
@@ -3,6 +3,8 @@
class BackgroundMigrationWorker
include ApplicationWorker
+ feature_category_not_owned!
+
# The minimum amount of time between processing two jobs of the same migration
# class.
#
diff --git a/app/workers/build_hooks_worker.rb b/app/workers/build_hooks_worker.rb
index b0c3676714c..15b31acf3e5 100644
--- a/app/workers/build_hooks_worker.rb
+++ b/app/workers/build_hooks_worker.rb
@@ -5,6 +5,7 @@ class BuildHooksWorker
include PipelineQueue
queue_namespace :pipeline_hooks
+ feature_category :continuous_integration
# rubocop: disable CodeReuse/ActiveRecord
def perform(build_id)
diff --git a/app/workers/build_queue_worker.rb b/app/workers/build_queue_worker.rb
index 67d5b0f5f5b..6584fba4c65 100644
--- a/app/workers/build_queue_worker.rb
+++ b/app/workers/build_queue_worker.rb
@@ -5,6 +5,7 @@ class BuildQueueWorker
include PipelineQueue
queue_namespace :pipeline_processing
+ feature_category :continuous_integration
# rubocop: disable CodeReuse/ActiveRecord
def perform(build_id)
diff --git a/app/workers/chat_notification_worker.rb b/app/workers/chat_notification_worker.rb
index 25a306e94d8..3bc2edad62c 100644
--- a/app/workers/chat_notification_worker.rb
+++ b/app/workers/chat_notification_worker.rb
@@ -3,6 +3,8 @@
class ChatNotificationWorker
include ApplicationWorker
+ feature_category :chatops
+
RESCHEDULE_INTERVAL = 2.seconds
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/workers/ci/archive_traces_cron_worker.rb b/app/workers/ci/archive_traces_cron_worker.rb
index ad7a29719ac..74f389175b9 100644
--- a/app/workers/ci/archive_traces_cron_worker.rb
+++ b/app/workers/ci/archive_traces_cron_worker.rb
@@ -5,6 +5,8 @@ module Ci
include ApplicationWorker
include CronjobQueue
+ feature_category :continuous_integration
+
# rubocop: disable CodeReuse/ActiveRecord
def perform
# Archive stale live traces which still resides in redis or database
diff --git a/app/workers/ci/build_prepare_worker.rb b/app/workers/ci/build_prepare_worker.rb
index 1a35a74ae53..20208c18d03 100644
--- a/app/workers/ci/build_prepare_worker.rb
+++ b/app/workers/ci/build_prepare_worker.rb
@@ -6,6 +6,7 @@ module Ci
include PipelineQueue
queue_namespace :pipeline_processing
+ feature_category :continuous_integration
def perform(build_id)
Ci::Build.find_by_id(build_id).try do |build|
diff --git a/app/workers/ci/build_schedule_worker.rb b/app/workers/ci/build_schedule_worker.rb
index da219adffc6..f22ec4c7810 100644
--- a/app/workers/ci/build_schedule_worker.rb
+++ b/app/workers/ci/build_schedule_worker.rb
@@ -6,6 +6,7 @@ module Ci
include PipelineQueue
queue_namespace :pipeline_processing
+ feature_category :continuous_integration
def perform(build_id)
::Ci::Build.find_by_id(build_id).try do |build|
diff --git a/app/workers/cleanup_container_repository_worker.rb b/app/workers/cleanup_container_repository_worker.rb
index 0331fc7b01c..83fb3e58d29 100644
--- a/app/workers/cleanup_container_repository_worker.rb
+++ b/app/workers/cleanup_container_repository_worker.rb
@@ -4,6 +4,7 @@ class CleanupContainerRepositoryWorker
include ApplicationWorker
queue_namespace :container_repository
+ feature_category :container_registry
attr_reader :container_repository, :current_user
diff --git a/app/workers/concerns/application_worker.rb b/app/workers/concerns/application_worker.rb
index 2b36ccb8304..62748808ff1 100644
--- a/app/workers/concerns/application_worker.rb
+++ b/app/workers/concerns/application_worker.rb
@@ -8,6 +8,7 @@ module ApplicationWorker
extend ActiveSupport::Concern
include Sidekiq::Worker # rubocop:disable Cop/IncludeSidekiqWorker
+ include WorkerAttributes
included do
set_queue
diff --git a/app/workers/concerns/auto_devops_queue.rb b/app/workers/concerns/auto_devops_queue.rb
index aba928ccaab..61e3c1544bd 100644
--- a/app/workers/concerns/auto_devops_queue.rb
+++ b/app/workers/concerns/auto_devops_queue.rb
@@ -5,5 +5,6 @@ module AutoDevopsQueue
included do
queue_namespace :auto_devops
+ feature_category :auto_devops
end
end
diff --git a/app/workers/concerns/chaos_queue.rb b/app/workers/concerns/chaos_queue.rb
index e406509d12d..c5db10491f2 100644
--- a/app/workers/concerns/chaos_queue.rb
+++ b/app/workers/concerns/chaos_queue.rb
@@ -5,5 +5,6 @@ module ChaosQueue
included do
queue_namespace :chaos
+ feature_category :chaos_engineering
end
end
diff --git a/app/workers/concerns/cluster_queue.rb b/app/workers/concerns/cluster_queue.rb
index e44b40c36c9..180b86b0124 100644
--- a/app/workers/concerns/cluster_queue.rb
+++ b/app/workers/concerns/cluster_queue.rb
@@ -8,5 +8,6 @@ module ClusterQueue
included do
queue_namespace :gcp_cluster
+ feature_category :kubernetes_configuration
end
end
diff --git a/app/workers/concerns/gitlab/github_import/object_importer.rb b/app/workers/concerns/gitlab/github_import/object_importer.rb
index eeeff6e93a0..b856a9329dd 100644
--- a/app/workers/concerns/gitlab/github_import/object_importer.rb
+++ b/app/workers/concerns/gitlab/github_import/object_importer.rb
@@ -12,6 +12,8 @@ module Gitlab
include GithubImport::Queue
include ReschedulingMethods
include NotifyUponDeath
+
+ feature_category :importers
end
# project - An instance of `Project` to import the data into.
diff --git a/app/workers/concerns/gitlab/github_import/queue.rb b/app/workers/concerns/gitlab/github_import/queue.rb
index 59b621f16ab..7cc23dd7c0b 100644
--- a/app/workers/concerns/gitlab/github_import/queue.rb
+++ b/app/workers/concerns/gitlab/github_import/queue.rb
@@ -7,6 +7,7 @@ module Gitlab
included do
queue_namespace :github_importer
+ feature_category :importers
# If a job produces an error it may block a stage from advancing
# forever. To prevent this from happening we prevent jobs from going to
diff --git a/app/workers/concerns/object_pool_queue.rb b/app/workers/concerns/object_pool_queue.rb
index 5b648df9c72..c2e84470fba 100644
--- a/app/workers/concerns/object_pool_queue.rb
+++ b/app/workers/concerns/object_pool_queue.rb
@@ -8,5 +8,6 @@ module ObjectPoolQueue
included do
queue_namespace :object_pool
+ feature_category :gitaly
end
end
diff --git a/app/workers/concerns/pipeline_background_queue.rb b/app/workers/concerns/pipeline_background_queue.rb
index bbb8ad0c982..0a23780b807 100644
--- a/app/workers/concerns/pipeline_background_queue.rb
+++ b/app/workers/concerns/pipeline_background_queue.rb
@@ -8,5 +8,6 @@ module PipelineBackgroundQueue
included do
queue_namespace :pipeline_background
+ feature_category :continuous_integration
end
end
diff --git a/app/workers/concerns/pipeline_queue.rb b/app/workers/concerns/pipeline_queue.rb
index 3aaed4669e5..27cbf6eb61c 100644
--- a/app/workers/concerns/pipeline_queue.rb
+++ b/app/workers/concerns/pipeline_queue.rb
@@ -8,5 +8,6 @@ module PipelineQueue
included do
queue_namespace :pipeline_default
+ feature_category :continuous_integration
end
end
diff --git a/app/workers/concerns/repository_check_queue.rb b/app/workers/concerns/repository_check_queue.rb
index 216d67e5dbc..76f6e1c2e91 100644
--- a/app/workers/concerns/repository_check_queue.rb
+++ b/app/workers/concerns/repository_check_queue.rb
@@ -6,7 +6,7 @@ module RepositoryCheckQueue
included do
queue_namespace :repository_check
-
sidekiq_options retry: false
+ feature_category :source_code_management
end
end
diff --git a/app/workers/concerns/todos_destroyer_queue.rb b/app/workers/concerns/todos_destroyer_queue.rb
index 8e2b1d30579..1bbccbfb1f9 100644
--- a/app/workers/concerns/todos_destroyer_queue.rb
+++ b/app/workers/concerns/todos_destroyer_queue.rb
@@ -8,5 +8,6 @@ module TodosDestroyerQueue
included do
queue_namespace :todos_destroyer
+ feature_category :issue_tracking
end
end
diff --git a/app/workers/create_evidence_worker.rb b/app/workers/create_evidence_worker.rb
index 5fc901ae514..027dbd2f101 100644
--- a/app/workers/create_evidence_worker.rb
+++ b/app/workers/create_evidence_worker.rb
@@ -3,6 +3,8 @@
class CreateEvidenceWorker
include ApplicationWorker
+ feature_category :release_governance
+
def perform(release_id)
release = Release.find_by_id(release_id)
return unless release
diff --git a/app/workers/create_gpg_signature_worker.rb b/app/workers/create_gpg_signature_worker.rb
index e3fb5d479ae..fc36a2adccd 100644
--- a/app/workers/create_gpg_signature_worker.rb
+++ b/app/workers/create_gpg_signature_worker.rb
@@ -3,6 +3,8 @@
class CreateGpgSignatureWorker
include ApplicationWorker
+ feature_category :source_code_management
+
# rubocop: disable CodeReuse/ActiveRecord
def perform(commit_shas, project_id)
# Older versions of Git::BranchPushService may push a single commit ID on
diff --git a/app/workers/create_note_diff_file_worker.rb b/app/workers/create_note_diff_file_worker.rb
index 0850250f7e3..ca200bd17b4 100644
--- a/app/workers/create_note_diff_file_worker.rb
+++ b/app/workers/create_note_diff_file_worker.rb
@@ -3,6 +3,8 @@
class CreateNoteDiffFileWorker
include ApplicationWorker
+ feature_category :source_code_management
+
def perform(diff_note_id)
diff_note = DiffNote.find(diff_note_id)
diff --git a/app/workers/create_pipeline_worker.rb b/app/workers/create_pipeline_worker.rb
index 037b4a57d4b..70412ffd095 100644
--- a/app/workers/create_pipeline_worker.rb
+++ b/app/workers/create_pipeline_worker.rb
@@ -5,6 +5,7 @@ class CreatePipelineWorker
include PipelineQueue
queue_namespace :pipeline_creation
+ feature_category :continuous_integration
def perform(project_id, user_id, ref, source, params = {})
project = Project.find(project_id)
diff --git a/app/workers/delete_container_repository_worker.rb b/app/workers/delete_container_repository_worker.rb
index 42e66513ff1..e70b4fb0a58 100644
--- a/app/workers/delete_container_repository_worker.rb
+++ b/app/workers/delete_container_repository_worker.rb
@@ -5,6 +5,7 @@ class DeleteContainerRepositoryWorker
include ExclusiveLeaseGuard
queue_namespace :container_repository
+ feature_category :container_registry
LEASE_TIMEOUT = 1.hour
diff --git a/app/workers/delete_diff_files_worker.rb b/app/workers/delete_diff_files_worker.rb
index f518dfe871c..e0c1724f1f7 100644
--- a/app/workers/delete_diff_files_worker.rb
+++ b/app/workers/delete_diff_files_worker.rb
@@ -3,6 +3,8 @@
class DeleteDiffFilesWorker
include ApplicationWorker
+ feature_category :source_code_management
+
# rubocop: disable CodeReuse/ActiveRecord
def perform(merge_request_diff_id)
merge_request_diff = MergeRequestDiff.find(merge_request_diff_id)
diff --git a/app/workers/delete_merged_branches_worker.rb b/app/workers/delete_merged_branches_worker.rb
index 017d7fd1cb0..44b3db30d0d 100644
--- a/app/workers/delete_merged_branches_worker.rb
+++ b/app/workers/delete_merged_branches_worker.rb
@@ -3,6 +3,8 @@
class DeleteMergedBranchesWorker
include ApplicationWorker
+ feature_category :source_code_management
+
def perform(project_id, user_id)
begin
project = Project.find(project_id)
diff --git a/app/workers/delete_stored_files_worker.rb b/app/workers/delete_stored_files_worker.rb
index ff7931849d8..8a693a64055 100644
--- a/app/workers/delete_stored_files_worker.rb
+++ b/app/workers/delete_stored_files_worker.rb
@@ -3,6 +3,8 @@
class DeleteStoredFilesWorker
include ApplicationWorker
+ feature_category_not_owned!
+
def perform(class_name, keys)
klass = begin
class_name.constantize
diff --git a/app/workers/delete_user_worker.rb b/app/workers/delete_user_worker.rb
index efa8794b214..0e49e787d8a 100644
--- a/app/workers/delete_user_worker.rb
+++ b/app/workers/delete_user_worker.rb
@@ -3,6 +3,8 @@
class DeleteUserWorker
include ApplicationWorker
+ feature_category :authentication_and_authorization
+
def perform(current_user_id, delete_user_id, options = {})
delete_user = User.find(delete_user_id)
current_user = User.find(current_user_id)
diff --git a/app/workers/deployments/finished_worker.rb b/app/workers/deployments/finished_worker.rb
index c9d448d5d18..79a1caccc92 100644
--- a/app/workers/deployments/finished_worker.rb
+++ b/app/workers/deployments/finished_worker.rb
@@ -5,6 +5,7 @@ module Deployments
include ApplicationWorker
queue_namespace :deployment
+ feature_category :continuous_delivery
def perform(deployment_id)
Deployment.find_by_id(deployment_id).try(:execute_hooks)
diff --git a/app/workers/deployments/success_worker.rb b/app/workers/deployments/success_worker.rb
index 3c7e384365a..f6520307186 100644
--- a/app/workers/deployments/success_worker.rb
+++ b/app/workers/deployments/success_worker.rb
@@ -5,6 +5,7 @@ module Deployments
include ApplicationWorker
queue_namespace :deployment
+ feature_category :continuous_delivery
def perform(deployment_id)
Deployment.find_by_id(deployment_id).try do |deployment|
diff --git a/app/workers/detect_repository_languages_worker.rb b/app/workers/detect_repository_languages_worker.rb
index 838c3be78f0..954d0f9336b 100644
--- a/app/workers/detect_repository_languages_worker.rb
+++ b/app/workers/detect_repository_languages_worker.rb
@@ -6,6 +6,7 @@ class DetectRepositoryLanguagesWorker
include ExclusiveLeaseGuard
sidekiq_options retry: 1
+ feature_category :source_code_management
LEASE_TIMEOUT = 300
diff --git a/app/workers/email_receiver_worker.rb b/app/workers/email_receiver_worker.rb
index e70bf17d5a9..c82728be329 100644
--- a/app/workers/email_receiver_worker.rb
+++ b/app/workers/email_receiver_worker.rb
@@ -3,6 +3,8 @@
class EmailReceiverWorker
include ApplicationWorker
+ feature_category :issue_tracking
+
def perform(raw)
return unless Gitlab::IncomingEmail.enabled?
diff --git a/app/workers/emails_on_push_worker.rb b/app/workers/emails_on_push_worker.rb
index ed3e354e4c2..2231c91a720 100644
--- a/app/workers/emails_on_push_worker.rb
+++ b/app/workers/emails_on_push_worker.rb
@@ -5,6 +5,8 @@ class EmailsOnPushWorker
attr_reader :email, :skip_premailer
+ feature_category :source_code_management
+
def perform(project_id, recipients, push_data, options = {})
options.symbolize_keys!
options.reverse_merge!(
diff --git a/app/workers/expire_build_artifacts_worker.rb b/app/workers/expire_build_artifacts_worker.rb
index 6f0e0fd33f7..9545227fa31 100644
--- a/app/workers/expire_build_artifacts_worker.rb
+++ b/app/workers/expire_build_artifacts_worker.rb
@@ -4,6 +4,8 @@ class ExpireBuildArtifactsWorker
include ApplicationWorker
include CronjobQueue
+ feature_category :continuous_integration
+
def perform
if Feature.enabled?(:ci_new_expire_job_artifacts_service, default_enabled: true)
perform_efficient_artifacts_removal
diff --git a/app/workers/expire_build_instance_artifacts_worker.rb b/app/workers/expire_build_instance_artifacts_worker.rb
index 71e61dcb878..db5240d5c8e 100644
--- a/app/workers/expire_build_instance_artifacts_worker.rb
+++ b/app/workers/expire_build_instance_artifacts_worker.rb
@@ -3,6 +3,8 @@
class ExpireBuildInstanceArtifactsWorker
include ApplicationWorker
+ feature_category :continuous_integration
+
# rubocop: disable CodeReuse/ActiveRecord
def perform(build_id)
build = Ci::Build
diff --git a/app/workers/git_garbage_collect_worker.rb b/app/workers/git_garbage_collect_worker.rb
index 5499e12e49b..ad119917774 100644
--- a/app/workers/git_garbage_collect_worker.rb
+++ b/app/workers/git_garbage_collect_worker.rb
@@ -4,6 +4,7 @@ class GitGarbageCollectWorker
include ApplicationWorker
sidekiq_options retry: false
+ feature_category :gitaly
# Timeout set to 24h
LEASE_TIMEOUT = 86400
diff --git a/app/workers/gitlab/github_import/advance_stage_worker.rb b/app/workers/gitlab/github_import/advance_stage_worker.rb
index 0b3437a8a33..44e69e48694 100644
--- a/app/workers/gitlab/github_import/advance_stage_worker.rb
+++ b/app/workers/gitlab/github_import/advance_stage_worker.rb
@@ -10,6 +10,7 @@ module Gitlab
include ApplicationWorker
sidekiq_options dead: false
+ feature_category :importers
INTERVAL = 30.seconds.to_i
diff --git a/app/workers/gitlab_shell_worker.rb b/app/workers/gitlab_shell_worker.rb
index 0e4d40acc5c..9766331cf4b 100644
--- a/app/workers/gitlab_shell_worker.rb
+++ b/app/workers/gitlab_shell_worker.rb
@@ -4,6 +4,8 @@ class GitlabShellWorker
include ApplicationWorker
include Gitlab::ShellAdapter
+ feature_category :source_code_management
+
def perform(action, *arg)
gitlab_shell.__send__(action, *arg) # rubocop:disable GitlabSecurity/PublicSend
end
diff --git a/app/workers/gitlab_usage_ping_worker.rb b/app/workers/gitlab_usage_ping_worker.rb
index a5e22f88a3b..ad8302a844a 100644
--- a/app/workers/gitlab_usage_ping_worker.rb
+++ b/app/workers/gitlab_usage_ping_worker.rb
@@ -6,6 +6,8 @@ class GitlabUsagePingWorker
include ApplicationWorker
include CronjobQueue
+ feature_category_not_owned!
+
# Retry for up to approximately three hours then give up.
sidekiq_options retry: 10, dead: false
diff --git a/app/workers/group_destroy_worker.rb b/app/workers/group_destroy_worker.rb
index b4a3ddcae51..553fd359baf 100644
--- a/app/workers/group_destroy_worker.rb
+++ b/app/workers/group_destroy_worker.rb
@@ -4,6 +4,8 @@ class GroupDestroyWorker
include ApplicationWorker
include ExceptionBacktrace
+ feature_category :groups
+
def perform(group_id, user_id)
begin
group = Group.find(group_id)
diff --git a/app/workers/hashed_storage/base_worker.rb b/app/workers/hashed_storage/base_worker.rb
index 237e278c537..1ab2108f6bb 100644
--- a/app/workers/hashed_storage/base_worker.rb
+++ b/app/workers/hashed_storage/base_worker.rb
@@ -3,6 +3,9 @@
module HashedStorage
class BaseWorker
include ExclusiveLeaseGuard
+ include WorkerAttributes
+
+ feature_category :source_code_management
LEASE_TIMEOUT = 30.seconds.to_i
LEASE_KEY_SEGMENT = 'project_migrate_hashed_storage_worker'
diff --git a/app/workers/hashed_storage/migrator_worker.rb b/app/workers/hashed_storage/migrator_worker.rb
index 49e347d4060..72a3faec5f4 100644
--- a/app/workers/hashed_storage/migrator_worker.rb
+++ b/app/workers/hashed_storage/migrator_worker.rb
@@ -5,6 +5,7 @@ module HashedStorage
include ApplicationWorker
queue_namespace :hashed_storage
+ feature_category :source_code_management
# @param [Integer] start initial ID of the batch
# @param [Integer] finish last ID of the batch
diff --git a/app/workers/hashed_storage/rollbacker_worker.rb b/app/workers/hashed_storage/rollbacker_worker.rb
index a4da8443787..8babdcfb96d 100644
--- a/app/workers/hashed_storage/rollbacker_worker.rb
+++ b/app/workers/hashed_storage/rollbacker_worker.rb
@@ -5,6 +5,7 @@ module HashedStorage
include ApplicationWorker
queue_namespace :hashed_storage
+ feature_category :source_code_management
# @param [Integer] start initial ID of the batch
# @param [Integer] finish last ID of the batch
diff --git a/app/workers/import_export_project_cleanup_worker.rb b/app/workers/import_export_project_cleanup_worker.rb
index da3debdeede..07c29d40b54 100644
--- a/app/workers/import_export_project_cleanup_worker.rb
+++ b/app/workers/import_export_project_cleanup_worker.rb
@@ -4,6 +4,8 @@ class ImportExportProjectCleanupWorker
include ApplicationWorker
include CronjobQueue
+ feature_category :importers
+
def perform
ImportExportCleanUpService.new.execute
end
diff --git a/app/workers/import_issues_csv_worker.rb b/app/workers/import_issues_csv_worker.rb
index b9d7099af71..d9834320318 100644
--- a/app/workers/import_issues_csv_worker.rb
+++ b/app/workers/import_issues_csv_worker.rb
@@ -3,6 +3,8 @@
class ImportIssuesCsvWorker
include ApplicationWorker
+ feature_category :issue_tracking
+
sidekiq_retries_exhausted do |job|
Upload.find(job['args'][2]).destroy
end
diff --git a/app/workers/invalid_gpg_signature_update_worker.rb b/app/workers/invalid_gpg_signature_update_worker.rb
index fc8a731b427..573efdf9fb1 100644
--- a/app/workers/invalid_gpg_signature_update_worker.rb
+++ b/app/workers/invalid_gpg_signature_update_worker.rb
@@ -3,6 +3,8 @@
class InvalidGpgSignatureUpdateWorker
include ApplicationWorker
+ feature_category :source_code_management
+
# rubocop: disable CodeReuse/ActiveRecord
def perform(gpg_key_id)
gpg_key = GpgKey.find_by(id: gpg_key_id)
diff --git a/app/workers/irker_worker.rb b/app/workers/irker_worker.rb
index 29631c6b7ac..a133ed6ed1b 100644
--- a/app/workers/irker_worker.rb
+++ b/app/workers/irker_worker.rb
@@ -6,6 +6,8 @@ require 'socket'
class IrkerWorker
include ApplicationWorker
+ feature_category :integrations
+
def perform(project_id, chans, colors, push_data, settings)
project = Project.find(project_id)
diff --git a/app/workers/issue_due_scheduler_worker.rb b/app/workers/issue_due_scheduler_worker.rb
index 476cba47ad7..d4d47659ef0 100644
--- a/app/workers/issue_due_scheduler_worker.rb
+++ b/app/workers/issue_due_scheduler_worker.rb
@@ -4,6 +4,8 @@ class IssueDueSchedulerWorker
include ApplicationWorker
include CronjobQueue
+ feature_category :issue_tracking
+
# rubocop: disable CodeReuse/ActiveRecord
def perform
project_ids = Issue.opened.due_tomorrow.group(:project_id).pluck(:project_id).map { |id| [id] }
diff --git a/app/workers/mail_scheduler/issue_due_worker.rb b/app/workers/mail_scheduler/issue_due_worker.rb
index 1e1dde1e829..6df816de71f 100644
--- a/app/workers/mail_scheduler/issue_due_worker.rb
+++ b/app/workers/mail_scheduler/issue_due_worker.rb
@@ -5,6 +5,8 @@ module MailScheduler
include ApplicationWorker
include MailSchedulerQueue
+ feature_category :issue_tracking
+
# rubocop: disable CodeReuse/ActiveRecord
def perform(project_id)
Issue.opened.due_tomorrow.in_projects(project_id).preload(:project).find_each do |issue|
diff --git a/app/workers/mail_scheduler/notification_service_worker.rb b/app/workers/mail_scheduler/notification_service_worker.rb
index 421fbf04e28..0d06dab3b2e 100644
--- a/app/workers/mail_scheduler/notification_service_worker.rb
+++ b/app/workers/mail_scheduler/notification_service_worker.rb
@@ -7,6 +7,8 @@ module MailScheduler
include ApplicationWorker
include MailSchedulerQueue
+ feature_category :issue_tracking
+
def perform(meth, *args)
check_arguments!(args)
diff --git a/app/workers/merge_worker.rb b/app/workers/merge_worker.rb
index ee864b733cd..70b909afea8 100644
--- a/app/workers/merge_worker.rb
+++ b/app/workers/merge_worker.rb
@@ -3,6 +3,8 @@
class MergeWorker
include ApplicationWorker
+ feature_category :source_code_management
+
def perform(merge_request_id, current_user_id, params)
params = params.with_indifferent_access
current_user = User.find(current_user_id)
diff --git a/app/workers/migrate_external_diffs_worker.rb b/app/workers/migrate_external_diffs_worker.rb
index fe757968d49..d248e2b5500 100644
--- a/app/workers/migrate_external_diffs_worker.rb
+++ b/app/workers/migrate_external_diffs_worker.rb
@@ -3,6 +3,8 @@
class MigrateExternalDiffsWorker
include ApplicationWorker
+ feature_category :source_code_management
+
def perform(merge_request_diff_id)
diff = MergeRequestDiff.find_by_id(merge_request_diff_id)
return unless diff
diff --git a/app/workers/namespaceless_project_destroy_worker.rb b/app/workers/namespaceless_project_destroy_worker.rb
index f6e98746055..113afc268f2 100644
--- a/app/workers/namespaceless_project_destroy_worker.rb
+++ b/app/workers/namespaceless_project_destroy_worker.rb
@@ -10,6 +10,8 @@ class NamespacelessProjectDestroyWorker
include ApplicationWorker
include ExceptionBacktrace
+ feature_category :authentication_and_authorization
+
def perform(project_id)
begin
project = Project.unscoped.find(project_id)
@@ -31,6 +33,6 @@ class NamespacelessProjectDestroyWorker
def unlink_fork(project)
merge_requests = project.forked_from_project.merge_requests.opened.from_project(project)
- merge_requests.update_all(state: 'closed')
+ merge_requests.update_all(state_id: MergeRequest.available_states[:closed])
end
end
diff --git a/app/workers/namespaces/prune_aggregation_schedules_worker.rb b/app/workers/namespaces/prune_aggregation_schedules_worker.rb
index 4e40feee702..16259ffbfa6 100644
--- a/app/workers/namespaces/prune_aggregation_schedules_worker.rb
+++ b/app/workers/namespaces/prune_aggregation_schedules_worker.rb
@@ -5,6 +5,8 @@ module Namespaces
include ApplicationWorker
include CronjobQueue
+ feature_category :source_code_management
+
# Worker to prune pending rows on Namespace::AggregationSchedule
# It's scheduled to run once a day at 1:05am.
def perform
diff --git a/app/workers/namespaces/root_statistics_worker.rb b/app/workers/namespaces/root_statistics_worker.rb
index 0c1ca5eb975..fd772c8cff6 100644
--- a/app/workers/namespaces/root_statistics_worker.rb
+++ b/app/workers/namespaces/root_statistics_worker.rb
@@ -5,6 +5,7 @@ module Namespaces
include ApplicationWorker
queue_namespace :update_namespace_statistics
+ feature_category :source_code_management
def perform(namespace_id)
namespace = Namespace.find(namespace_id)
diff --git a/app/workers/namespaces/schedule_aggregation_worker.rb b/app/workers/namespaces/schedule_aggregation_worker.rb
index b7d580220d6..87e135fbf21 100644
--- a/app/workers/namespaces/schedule_aggregation_worker.rb
+++ b/app/workers/namespaces/schedule_aggregation_worker.rb
@@ -5,6 +5,7 @@ module Namespaces
include ApplicationWorker
queue_namespace :update_namespace_statistics
+ feature_category :source_code_management
def perform(namespace_id)
return unless aggregation_schedules_table_exists?
diff --git a/app/workers/new_issue_worker.rb b/app/workers/new_issue_worker.rb
index 85b53973f56..1b0fec597e7 100644
--- a/app/workers/new_issue_worker.rb
+++ b/app/workers/new_issue_worker.rb
@@ -4,6 +4,8 @@ class NewIssueWorker
include ApplicationWorker
include NewIssuable
+ feature_category :issue_tracking
+
def perform(issue_id, user_id)
return unless objects_found?(issue_id, user_id)
diff --git a/app/workers/new_merge_request_worker.rb b/app/workers/new_merge_request_worker.rb
index fa48c1b29a8..0a5b2f86331 100644
--- a/app/workers/new_merge_request_worker.rb
+++ b/app/workers/new_merge_request_worker.rb
@@ -4,6 +4,8 @@ class NewMergeRequestWorker
include ApplicationWorker
include NewIssuable
+ feature_category :source_code_management
+
def perform(merge_request_id, user_id)
return unless objects_found?(merge_request_id, user_id)
diff --git a/app/workers/new_note_worker.rb b/app/workers/new_note_worker.rb
index 7648af3a8b9..d0d2a563738 100644
--- a/app/workers/new_note_worker.rb
+++ b/app/workers/new_note_worker.rb
@@ -3,6 +3,8 @@
class NewNoteWorker
include ApplicationWorker
+ feature_category :issue_tracking
+
# Keep extra parameter to preserve backwards compatibility with
# old `NewNoteWorker` jobs (can remove later)
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/workers/new_release_worker.rb b/app/workers/new_release_worker.rb
index b80553a60db..28d2517238e 100644
--- a/app/workers/new_release_worker.rb
+++ b/app/workers/new_release_worker.rb
@@ -4,6 +4,7 @@ class NewReleaseWorker
include ApplicationWorker
queue_namespace :notifications
+ feature_category :release_orchestration
def perform(release_id)
release = Release.with_project_and_namespace.find_by_id(release_id)
diff --git a/app/workers/object_storage/background_move_worker.rb b/app/workers/object_storage/background_move_worker.rb
index 19ccae7739c..55f8e1c3ede 100644
--- a/app/workers/object_storage/background_move_worker.rb
+++ b/app/workers/object_storage/background_move_worker.rb
@@ -6,6 +6,7 @@ module ObjectStorage
include ObjectStorageQueue
sidekiq_options retry: 5
+ feature_category_not_owned!
def perform(uploader_class_name, subject_class_name, file_field, subject_id)
uploader_class = uploader_class_name.constantize
diff --git a/app/workers/object_storage/migrate_uploads_worker.rb b/app/workers/object_storage/migrate_uploads_worker.rb
index c9fd19cf9d7..01e6fdb2d3e 100644
--- a/app/workers/object_storage/migrate_uploads_worker.rb
+++ b/app/workers/object_storage/migrate_uploads_worker.rb
@@ -5,6 +5,8 @@ module ObjectStorage
include ApplicationWorker
include ObjectStorageQueue
+ feature_category_not_owned!
+
SanityCheckError = Class.new(StandardError)
class MigrationResult
diff --git a/app/workers/pages_domain_removal_cron_worker.rb b/app/workers/pages_domain_removal_cron_worker.rb
index 79f38e1b89f..25e747c78d0 100644
--- a/app/workers/pages_domain_removal_cron_worker.rb
+++ b/app/workers/pages_domain_removal_cron_worker.rb
@@ -4,6 +4,8 @@ class PagesDomainRemovalCronWorker
include ApplicationWorker
include CronjobQueue
+ feature_category :pages
+
def perform
PagesDomain.for_removal.find_each do |domain|
domain.destroy!
diff --git a/app/workers/pages_domain_ssl_renewal_cron_worker.rb b/app/workers/pages_domain_ssl_renewal_cron_worker.rb
index e5dde07a648..f7a243e9b3b 100644
--- a/app/workers/pages_domain_ssl_renewal_cron_worker.rb
+++ b/app/workers/pages_domain_ssl_renewal_cron_worker.rb
@@ -4,6 +4,8 @@ class PagesDomainSslRenewalCronWorker
include ApplicationWorker
include CronjobQueue
+ feature_category :pages
+
def perform
return unless ::Gitlab::LetsEncrypt.enabled?
diff --git a/app/workers/pages_domain_ssl_renewal_worker.rb b/app/workers/pages_domain_ssl_renewal_worker.rb
index 87fd8059946..4db7d22ef7e 100644
--- a/app/workers/pages_domain_ssl_renewal_worker.rb
+++ b/app/workers/pages_domain_ssl_renewal_worker.rb
@@ -3,6 +3,8 @@
class PagesDomainSslRenewalWorker
include ApplicationWorker
+ feature_category :pages
+
def perform(domain_id)
domain = PagesDomain.find_by_id(domain_id)
return unless domain&.enabled?
diff --git a/app/workers/pages_domain_verification_cron_worker.rb b/app/workers/pages_domain_verification_cron_worker.rb
index 60703c83e9e..bb3a7fede9a 100644
--- a/app/workers/pages_domain_verification_cron_worker.rb
+++ b/app/workers/pages_domain_verification_cron_worker.rb
@@ -4,6 +4,8 @@ class PagesDomainVerificationCronWorker
include ApplicationWorker
include CronjobQueue
+ feature_category :pages
+
def perform
return if Gitlab::Database.read_only?
diff --git a/app/workers/pages_domain_verification_worker.rb b/app/workers/pages_domain_verification_worker.rb
index 7817b2ee5fc..b0888036498 100644
--- a/app/workers/pages_domain_verification_worker.rb
+++ b/app/workers/pages_domain_verification_worker.rb
@@ -3,6 +3,8 @@
class PagesDomainVerificationWorker
include ApplicationWorker
+ feature_category :pages
+
# rubocop: disable CodeReuse/ActiveRecord
def perform(domain_id)
return if Gitlab::Database.read_only?
diff --git a/app/workers/pages_worker.rb b/app/workers/pages_worker.rb
index fa0dfa2ff4b..484d9053849 100644
--- a/app/workers/pages_worker.rb
+++ b/app/workers/pages_worker.rb
@@ -4,6 +4,7 @@ class PagesWorker
include ApplicationWorker
sidekiq_options retry: 3
+ feature_category :pages
def perform(action, *arg)
send(action, *arg) # rubocop:disable GitlabSecurity/PublicSend
diff --git a/app/workers/pipeline_process_worker.rb b/app/workers/pipeline_process_worker.rb
index 96524d93f8d..96f3725dbbe 100644
--- a/app/workers/pipeline_process_worker.rb
+++ b/app/workers/pipeline_process_worker.rb
@@ -5,6 +5,7 @@ class PipelineProcessWorker
include PipelineQueue
queue_namespace :pipeline_processing
+ feature_category :continuous_integration
# rubocop: disable CodeReuse/ActiveRecord
def perform(pipeline_id, build_ids = nil)
diff --git a/app/workers/pipeline_schedule_worker.rb b/app/workers/pipeline_schedule_worker.rb
index 9410fd1a786..f500ea08353 100644
--- a/app/workers/pipeline_schedule_worker.rb
+++ b/app/workers/pipeline_schedule_worker.rb
@@ -4,6 +4,8 @@ class PipelineScheduleWorker
include ApplicationWorker
include CronjobQueue
+ feature_category :continuous_integration
+
def perform
Ci::PipelineSchedule.runnable_schedules.preloaded.find_in_batches do |schedules|
schedules.each do |schedule|
diff --git a/app/workers/plugin_worker.rb b/app/workers/plugin_worker.rb
index c293e28be4a..e708031abdf 100644
--- a/app/workers/plugin_worker.rb
+++ b/app/workers/plugin_worker.rb
@@ -4,6 +4,7 @@ class PluginWorker
include ApplicationWorker
sidekiq_options retry: false
+ feature_category :integrations
def perform(file_name, data)
success, message = Gitlab::Plugin.execute(file_name, data)
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index 4f193e95faa..a3bc7e5b9c9 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -3,6 +3,8 @@
class PostReceive
include ApplicationWorker
+ feature_category :source_code_management
+
def perform(gl_repository, identifier, changes, push_options = {})
project, repo_type = Gitlab::GlRepository.parse(gl_repository)
diff --git a/app/workers/process_commit_worker.rb b/app/workers/process_commit_worker.rb
index f6ebe4ab006..1e4561fc6ea 100644
--- a/app/workers/process_commit_worker.rb
+++ b/app/workers/process_commit_worker.rb
@@ -10,6 +10,8 @@
class ProcessCommitWorker
include ApplicationWorker
+ feature_category :source_code_management
+
# project_id - The ID of the project this commit belongs to.
# user_id - The ID of the user that pushed the commit.
# commit_hash - Hash containing commit details to use for constructing a
diff --git a/app/workers/project_cache_worker.rb b/app/workers/project_cache_worker.rb
index e3f1f61991c..57a01c0dd8e 100644
--- a/app/workers/project_cache_worker.rb
+++ b/app/workers/project_cache_worker.rb
@@ -5,6 +5,8 @@ class ProjectCacheWorker
include ApplicationWorker
LEASE_TIMEOUT = 15.minutes.to_i
+ feature_category :source_code_management
+
# project_id - The ID of the project for which to flush the cache.
# files - An Array containing extra types of files to refresh such as
# `:readme` to flush the README and `:changelog` to flush the
diff --git a/app/workers/project_daily_statistics_worker.rb b/app/workers/project_daily_statistics_worker.rb
index 101f5c28459..19c2fd67763 100644
--- a/app/workers/project_daily_statistics_worker.rb
+++ b/app/workers/project_daily_statistics_worker.rb
@@ -3,6 +3,8 @@
class ProjectDailyStatisticsWorker
include ApplicationWorker
+ feature_category :source_code_management
+
def perform(project_id)
project = Project.find_by_id(project_id)
diff --git a/app/workers/project_destroy_worker.rb b/app/workers/project_destroy_worker.rb
index 4447e867240..1d20837faa2 100644
--- a/app/workers/project_destroy_worker.rb
+++ b/app/workers/project_destroy_worker.rb
@@ -4,6 +4,8 @@ class ProjectDestroyWorker
include ApplicationWorker
include ExceptionBacktrace
+ feature_category :source_code_management
+
def perform(project_id, user_id, params)
project = Project.find(project_id)
user = User.find(user_id)
diff --git a/app/workers/project_export_worker.rb b/app/workers/project_export_worker.rb
index ed9da39c7c3..bbcf3b72718 100644
--- a/app/workers/project_export_worker.rb
+++ b/app/workers/project_export_worker.rb
@@ -5,6 +5,7 @@ class ProjectExportWorker
include ExceptionBacktrace
sidekiq_options retry: 3
+ feature_category :source_code_management
def perform(current_user_id, project_id, after_export_strategy = {}, params = {})
current_user = User.find(current_user_id)
diff --git a/app/workers/project_service_worker.rb b/app/workers/project_service_worker.rb
index 25567cec08b..8041404fc71 100644
--- a/app/workers/project_service_worker.rb
+++ b/app/workers/project_service_worker.rb
@@ -4,6 +4,7 @@ class ProjectServiceWorker
include ApplicationWorker
sidekiq_options dead: false
+ feature_category :integrations
def perform(hook_id, data)
data = data.with_indifferent_access
diff --git a/app/workers/propagate_service_template_worker.rb b/app/workers/propagate_service_template_worker.rb
index 3ccd7615697..73a2b453207 100644
--- a/app/workers/propagate_service_template_worker.rb
+++ b/app/workers/propagate_service_template_worker.rb
@@ -4,6 +4,8 @@
class PropagateServiceTemplateWorker
include ApplicationWorker
+ feature_category :source_code_management
+
LEASE_TIMEOUT = 4.hours.to_i
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/workers/prune_old_events_worker.rb b/app/workers/prune_old_events_worker.rb
index e2d1fb3ed35..f421e8dbf59 100644
--- a/app/workers/prune_old_events_worker.rb
+++ b/app/workers/prune_old_events_worker.rb
@@ -4,6 +4,8 @@ class PruneOldEventsWorker
include ApplicationWorker
include CronjobQueue
+ feature_category_not_owned!
+
# rubocop: disable CodeReuse/ActiveRecord
def perform
# Contribution calendar shows maximum 12 months of events, we retain 3 years for data integrity.
diff --git a/app/workers/prune_web_hook_logs_worker.rb b/app/workers/prune_web_hook_logs_worker.rb
index 38054069f4e..8e48b45fc34 100644
--- a/app/workers/prune_web_hook_logs_worker.rb
+++ b/app/workers/prune_web_hook_logs_worker.rb
@@ -6,6 +6,8 @@ class PruneWebHookLogsWorker
include ApplicationWorker
include CronjobQueue
+ feature_category :integrations
+
# The maximum number of rows to remove in a single job.
DELETE_LIMIT = 50_000
diff --git a/app/workers/reactive_caching_worker.rb b/app/workers/reactive_caching_worker.rb
index b30864db802..af4a3def062 100644
--- a/app/workers/reactive_caching_worker.rb
+++ b/app/workers/reactive_caching_worker.rb
@@ -3,6 +3,8 @@
class ReactiveCachingWorker
include ApplicationWorker
+ feature_category_not_owned!
+
def perform(class_name, id, *args)
klass = begin
class_name.constantize
diff --git a/app/workers/rebase_worker.rb b/app/workers/rebase_worker.rb
index 8d06adcd993..7343226fdcd 100644
--- a/app/workers/rebase_worker.rb
+++ b/app/workers/rebase_worker.rb
@@ -5,6 +5,8 @@
class RebaseWorker
include ApplicationWorker
+ feature_category :source_code_management
+
def perform(merge_request_id, current_user_id)
current_user = User.find(current_user_id)
merge_request = MergeRequest.find(merge_request_id)
diff --git a/app/workers/remote_mirror_notification_worker.rb b/app/workers/remote_mirror_notification_worker.rb
index 368abfeda99..8bc19230caf 100644
--- a/app/workers/remote_mirror_notification_worker.rb
+++ b/app/workers/remote_mirror_notification_worker.rb
@@ -3,6 +3,8 @@
class RemoteMirrorNotificationWorker
include ApplicationWorker
+ feature_category :source_code_management
+
def perform(remote_mirror_id)
remote_mirror = RemoteMirror.find_by_id(remote_mirror_id)
diff --git a/app/workers/remove_expired_group_links_worker.rb b/app/workers/remove_expired_group_links_worker.rb
index 25128caf72f..147b412b772 100644
--- a/app/workers/remove_expired_group_links_worker.rb
+++ b/app/workers/remove_expired_group_links_worker.rb
@@ -4,6 +4,8 @@ class RemoveExpiredGroupLinksWorker
include ApplicationWorker
include CronjobQueue
+ feature_category :authentication_and_authorization
+
def perform
ProjectGroupLink.expired.destroy_all # rubocop: disable DestroyAll
end
diff --git a/app/workers/remove_expired_members_worker.rb b/app/workers/remove_expired_members_worker.rb
index 3497a1f9280..75f06fd9f6b 100644
--- a/app/workers/remove_expired_members_worker.rb
+++ b/app/workers/remove_expired_members_worker.rb
@@ -4,6 +4,8 @@ class RemoveExpiredMembersWorker
include ApplicationWorker
include CronjobQueue
+ feature_category :authentication_and_authorization
+
def perform
Member.expired.find_each do |member|
Members::DestroyService.new.execute(member, skip_authorization: true)
diff --git a/app/workers/remove_unreferenced_lfs_objects_worker.rb b/app/workers/remove_unreferenced_lfs_objects_worker.rb
index 95e7a9f537f..7f2c23f4685 100644
--- a/app/workers/remove_unreferenced_lfs_objects_worker.rb
+++ b/app/workers/remove_unreferenced_lfs_objects_worker.rb
@@ -4,6 +4,8 @@ class RemoveUnreferencedLfsObjectsWorker
include ApplicationWorker
include CronjobQueue
+ feature_category :source_code_management
+
def perform
LfsObject.destroy_unreferenced
end
diff --git a/app/workers/repository_archive_cache_worker.rb b/app/workers/repository_archive_cache_worker.rb
index c1dff8ced90..ebc83c1b17a 100644
--- a/app/workers/repository_archive_cache_worker.rb
+++ b/app/workers/repository_archive_cache_worker.rb
@@ -4,6 +4,8 @@ class RepositoryArchiveCacheWorker
include ApplicationWorker
include CronjobQueue
+ feature_category :source_code_management
+
def perform
RepositoryArchiveCleanUpService.new.execute
end
diff --git a/app/workers/repository_check/dispatch_worker.rb b/app/workers/repository_check/dispatch_worker.rb
index 0a7d9a14c6a..d2bd5f9b967 100644
--- a/app/workers/repository_check/dispatch_worker.rb
+++ b/app/workers/repository_check/dispatch_worker.rb
@@ -7,6 +7,8 @@ module RepositoryCheck
include ::EachShardWorker
include ExclusiveLeaseGuard
+ feature_category :source_code_management
+
LEASE_TIMEOUT = 1.hour
def perform
diff --git a/app/workers/repository_cleanup_worker.rb b/app/workers/repository_cleanup_worker.rb
index aa26c173a72..dd2cbd42d1f 100644
--- a/app/workers/repository_cleanup_worker.rb
+++ b/app/workers/repository_cleanup_worker.rb
@@ -4,6 +4,7 @@ class RepositoryCleanupWorker
include ApplicationWorker
sidekiq_options retry: 3
+ feature_category :source_code_management
sidekiq_retries_exhausted do |msg, err|
next if err.is_a?(ActiveRecord::RecordNotFound)
diff --git a/app/workers/repository_fork_worker.rb b/app/workers/repository_fork_worker.rb
index 35e9c58eb13..0adf745c7ac 100644
--- a/app/workers/repository_fork_worker.rb
+++ b/app/workers/repository_fork_worker.rb
@@ -6,6 +6,8 @@ class RepositoryForkWorker
include ProjectStartImport
include ProjectImportOptions
+ feature_category :source_code_management
+
def perform(*args)
target_project_id = args.shift
target_project = Project.find(target_project_id)
diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb
index 85771fa8b31..bc2d0366fdd 100644
--- a/app/workers/repository_import_worker.rb
+++ b/app/workers/repository_import_worker.rb
@@ -6,6 +6,8 @@ class RepositoryImportWorker
include ProjectStartImport
include ProjectImportOptions
+ feature_category :importers
+
# technical debt: https://gitlab.com/gitlab-org/gitlab/issues/33991
sidekiq_options memory_killer_memory_growth_kb: ENV.fetch('MEMORY_KILLER_REPOSITORY_IMPORT_WORKER_MEMORY_GROWTH_KB', 50).to_i
sidekiq_options memory_killer_max_memory_growth_kb: ENV.fetch('MEMORY_KILLER_REPOSITORY_IMPORT_WORKER_MAX_MEMORY_GROWTH_KB', 300_000).to_i
diff --git a/app/workers/repository_remove_remote_worker.rb b/app/workers/repository_remove_remote_worker.rb
index a85e9fa9394..3e55ebc77ed 100644
--- a/app/workers/repository_remove_remote_worker.rb
+++ b/app/workers/repository_remove_remote_worker.rb
@@ -4,6 +4,8 @@ class RepositoryRemoveRemoteWorker
include ApplicationWorker
include ExclusiveLeaseGuard
+ feature_category :source_code_management
+
LEASE_TIMEOUT = 1.hour
attr_reader :project, :remote_name
diff --git a/app/workers/repository_update_remote_mirror_worker.rb b/app/workers/repository_update_remote_mirror_worker.rb
index d13c7641eb3..b4d96546fa4 100644
--- a/app/workers/repository_update_remote_mirror_worker.rb
+++ b/app/workers/repository_update_remote_mirror_worker.rb
@@ -7,6 +7,7 @@ class RepositoryUpdateRemoteMirrorWorker
include Gitlab::ExclusiveLeaseHelpers
sidekiq_options retry: 3, dead: false
+ feature_category :source_code_management
LOCK_WAIT_TIME = 30.seconds
MAX_TRIES = 3
diff --git a/app/workers/requests_profiles_worker.rb b/app/workers/requests_profiles_worker.rb
index ae022d43e29..6ab020afb10 100644
--- a/app/workers/requests_profiles_worker.rb
+++ b/app/workers/requests_profiles_worker.rb
@@ -4,6 +4,8 @@ class RequestsProfilesWorker
include ApplicationWorker
include CronjobQueue
+ feature_category :source_code_management
+
def perform
Gitlab::RequestProfiler.remove_all_profiles
end
diff --git a/app/workers/run_pipeline_schedule_worker.rb b/app/workers/run_pipeline_schedule_worker.rb
index 659f8b80397..853f774875a 100644
--- a/app/workers/run_pipeline_schedule_worker.rb
+++ b/app/workers/run_pipeline_schedule_worker.rb
@@ -5,6 +5,7 @@ class RunPipelineScheduleWorker
include PipelineQueue
queue_namespace :pipeline_creation
+ feature_category :continuous_integration
# rubocop: disable CodeReuse/ActiveRecord
def perform(schedule_id, user_id)
diff --git a/app/workers/schedule_migrate_external_diffs_worker.rb b/app/workers/schedule_migrate_external_diffs_worker.rb
index 04a370f01af..8abb5922b54 100644
--- a/app/workers/schedule_migrate_external_diffs_worker.rb
+++ b/app/workers/schedule_migrate_external_diffs_worker.rb
@@ -5,6 +5,8 @@ class ScheduleMigrateExternalDiffsWorker
include CronjobQueue
include Gitlab::ExclusiveLeaseHelpers
+ feature_category :source_code_management
+
def perform
in_lock(self.class.name.underscore, ttl: 2.hours, retries: 0) do
MergeRequests::MigrateExternalDiffsService.enqueue!
diff --git a/app/workers/stuck_ci_jobs_worker.rb b/app/workers/stuck_ci_jobs_worker.rb
index 7e002d8822c..971edb1f14f 100644
--- a/app/workers/stuck_ci_jobs_worker.rb
+++ b/app/workers/stuck_ci_jobs_worker.rb
@@ -4,6 +4,8 @@ class StuckCiJobsWorker
include ApplicationWorker
include CronjobQueue
+ feature_category :continuous_integration
+
EXCLUSIVE_LEASE_KEY = 'stuck_ci_builds_worker_lease'
BUILD_RUNNING_OUTDATED_TIMEOUT = 1.hour
diff --git a/app/workers/stuck_import_jobs_worker.rb b/app/workers/stuck_import_jobs_worker.rb
index a9ff5b22b25..4993cd1220c 100644
--- a/app/workers/stuck_import_jobs_worker.rb
+++ b/app/workers/stuck_import_jobs_worker.rb
@@ -4,6 +4,8 @@ class StuckImportJobsWorker
include ApplicationWorker
include CronjobQueue
+ feature_category :importers
+
IMPORT_JOBS_EXPIRATION = 15.hours.to_i
def perform
diff --git a/app/workers/stuck_merge_jobs_worker.rb b/app/workers/stuck_merge_jobs_worker.rb
index e840ae47421..024863ab530 100644
--- a/app/workers/stuck_merge_jobs_worker.rb
+++ b/app/workers/stuck_merge_jobs_worker.rb
@@ -4,6 +4,8 @@ class StuckMergeJobsWorker
include ApplicationWorker
include CronjobQueue
+ feature_category :source_code_management
+
def self.logger
Rails.logger # rubocop:disable Gitlab/RailsLogger
end
@@ -31,7 +33,7 @@ class StuckMergeJobsWorker
def apply_current_state!(completed_jids, completed_ids)
merge_requests = MergeRequest.where(id: completed_ids)
- merge_requests.where.not(merge_commit_sha: nil).update_all(state: :merged)
+ merge_requests.where.not(merge_commit_sha: nil).update_all(state_id: MergeRequest.available_states[:merged])
merge_requests_to_reopen = merge_requests.where(merge_commit_sha: nil)
diff --git a/app/workers/system_hook_push_worker.rb b/app/workers/system_hook_push_worker.rb
index 15e369ebcfb..fc6237f359a 100644
--- a/app/workers/system_hook_push_worker.rb
+++ b/app/workers/system_hook_push_worker.rb
@@ -3,6 +3,8 @@
class SystemHookPushWorker
include ApplicationWorker
+ feature_category :source_code_management
+
def perform(push_data, hook_id)
SystemHooksService.new.execute_hooks(push_data, hook_id)
end
diff --git a/app/workers/trending_projects_worker.rb b/app/workers/trending_projects_worker.rb
index 55b599ba38f..4c8ee1ee425 100644
--- a/app/workers/trending_projects_worker.rb
+++ b/app/workers/trending_projects_worker.rb
@@ -4,6 +4,8 @@ class TrendingProjectsWorker
include ApplicationWorker
include CronjobQueue
+ feature_category :source_code_management
+
def perform
Rails.logger.info('Refreshing trending projects') # rubocop:disable Gitlab/RailsLogger
diff --git a/app/workers/update_external_pull_requests_worker.rb b/app/workers/update_external_pull_requests_worker.rb
index c5acfa82ada..8b0952528fa 100644
--- a/app/workers/update_external_pull_requests_worker.rb
+++ b/app/workers/update_external_pull_requests_worker.rb
@@ -3,6 +3,8 @@
class UpdateExternalPullRequestsWorker
include ApplicationWorker
+ feature_category :source_code_management
+
def perform(project_id, user_id, ref)
project = Project.find_by_id(project_id)
return unless project
diff --git a/app/workers/update_head_pipeline_for_merge_request_worker.rb b/app/workers/update_head_pipeline_for_merge_request_worker.rb
index 4ec2b9d8fbe..77859abfea4 100644
--- a/app/workers/update_head_pipeline_for_merge_request_worker.rb
+++ b/app/workers/update_head_pipeline_for_merge_request_worker.rb
@@ -5,6 +5,7 @@ class UpdateHeadPipelineForMergeRequestWorker
include PipelineQueue
queue_namespace :pipeline_processing
+ feature_category :continuous_integration
def perform(merge_request_id)
MergeRequest.find_by_id(merge_request_id).try do |merge_request|
diff --git a/app/workers/update_merge_requests_worker.rb b/app/workers/update_merge_requests_worker.rb
index 6c0e472e05a..8e1703cdd0b 100644
--- a/app/workers/update_merge_requests_worker.rb
+++ b/app/workers/update_merge_requests_worker.rb
@@ -3,6 +3,8 @@
class UpdateMergeRequestsWorker
include ApplicationWorker
+ feature_category :source_code_management
+
LOG_TIME_THRESHOLD = 90 # seconds
# rubocop: disable CodeReuse/ActiveRecord
diff --git a/app/workers/update_project_statistics_worker.rb b/app/workers/update_project_statistics_worker.rb
index 3abb7e34a9d..e36cebf6f4f 100644
--- a/app/workers/update_project_statistics_worker.rb
+++ b/app/workers/update_project_statistics_worker.rb
@@ -4,6 +4,8 @@
class UpdateProjectStatisticsWorker
include ApplicationWorker
+ feature_category :source_code_management
+
# project_id - The ID of the project for which to flush the cache.
# statistics - An Array containing columns from ProjectStatistics to
# refresh, if empty all columns will be refreshed
diff --git a/app/workers/upload_checksum_worker.rb b/app/workers/upload_checksum_worker.rb
index 834dcaa435d..d35367145b8 100644
--- a/app/workers/upload_checksum_worker.rb
+++ b/app/workers/upload_checksum_worker.rb
@@ -3,6 +3,8 @@
class UploadChecksumWorker
include ApplicationWorker
+ feature_category :geo_replication
+
def perform(upload_id)
upload = Upload.find(upload_id)
upload.calculate_checksum!
diff --git a/app/workers/web_hook_worker.rb b/app/workers/web_hook_worker.rb
index 09219a24a16..fd7ca93683e 100644
--- a/app/workers/web_hook_worker.rb
+++ b/app/workers/web_hook_worker.rb
@@ -3,6 +3,7 @@
class WebHookWorker
include ApplicationWorker
+ feature_category :integrations
sidekiq_options retry: 4, dead: false
def perform(hook_id, data, hook_name)