summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-10-19 18:08:54 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-10-19 18:08:54 +0000
commitb9d98fe10a624d9a6033c516c970954b4fc09372 (patch)
tree74cb5f7f97f7d40c4a5970855217bd2ee226b9a7 /app
parent589b674b06c4acb5c357f6444fb0b7344585fdc5 (diff)
downloadgitlab-ce-b9d98fe10a624d9a6033c516c970954b4fc09372.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/analytics/instance_statistics/components/pipelines_chart.vue19
-rw-r--r--app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue12
-rw-r--r--app/assets/javascripts/logs/components/environment_logs.vue62
-rw-r--r--app/assets/javascripts/logs/components/log_simple_filters.vue42
-rw-r--r--app/assets/javascripts/milestones/stores/actions.js58
-rw-r--r--app/assets/javascripts/milestones/stores/getters.js2
-rw-r--r--app/assets/javascripts/milestones/stores/index.js16
-rw-r--r--app/assets/javascripts/milestones/stores/mutation_types.js13
-rw-r--r--app/assets/javascripts/milestones/stores/mutations.js44
-rw-r--r--app/assets/javascripts/milestones/stores/state.js14
-rw-r--r--app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue34
-rw-r--r--app/assets/javascripts/vue_shared/components/editor_lite.vue4
-rw-r--r--app/models/container_expiration_policy.rb11
-rw-r--r--app/services/merge_requests/cleanup_refs_service.rb2
-rw-r--r--app/views/layouts/header/_default.html.haml2
-rw-r--r--app/workers/container_expiration_policy_worker.rb16
16 files changed, 240 insertions, 111 deletions
diff --git a/app/assets/javascripts/analytics/instance_statistics/components/pipelines_chart.vue b/app/assets/javascripts/analytics/instance_statistics/components/pipelines_chart.vue
index 279fcfe736f..b16d960402b 100644
--- a/app/assets/javascripts/analytics/instance_statistics/components/pipelines_chart.vue
+++ b/app/assets/javascripts/analytics/instance_statistics/components/pipelines_chart.vue
@@ -4,7 +4,11 @@ import { GlAlert } from '@gitlab/ui';
import { mapKeys, mapValues, pick, some, sum } from 'lodash';
import ChartSkeletonLoader from '~/vue_shared/components/resizable_chart/skeleton_loader.vue';
import { s__ } from '~/locale';
-import { formatDateAsMonth, getDayDifference } from '~/lib/utils/datetime_utility';
+import {
+ differenceInMonths,
+ formatDateAsMonth,
+ getDayDifference,
+} from '~/lib/utils/datetime_utility';
import { getAverageByMonth, sortByDate, extractValues } from '../utils';
import pipelineStatsQuery from '../graphql/queries/pipeline_stats.query.graphql';
import { TODAY, START_DATE } from '../constants';
@@ -150,19 +154,14 @@ export default {
max: this.$options.endDate,
};
},
- differenceInMonths() {
- const yearDiff = this.$options.endDate.getYear() - this.$options.startDate.getYear();
- const monthDiff = this.$options.endDate.getMonth() - this.$options.startDate.getMonth();
-
- return monthDiff + 12 * yearDiff;
- },
chartOptions() {
+ const { endDate, startDate, i18n } = this.$options;
return {
xAxis: {
...this.range,
- name: this.$options.i18n.xAxisTitle,
+ name: i18n.xAxisTitle,
type: 'time',
- splitNumber: this.differenceInMonths + 1,
+ splitNumber: differenceInMonths(startDate, endDate) + 1,
axisLabel: {
interval: 0,
showMinLabel: false,
@@ -172,7 +171,7 @@ export default {
},
},
yAxis: {
- name: this.$options.i18n.yAxisTitle,
+ name: i18n.yAxisTitle,
},
};
},
diff --git a/app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue b/app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue
index bbcb866c758..53fac09ab66 100644
--- a/app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue
+++ b/app/assets/javascripts/ide/components/commit_sidebar/editor_header.vue
@@ -1,6 +1,6 @@
<script>
import { mapActions } from 'vuex';
-import { GlModal } from '@gitlab/ui';
+import { GlModal, GlButton } from '@gitlab/ui';
import { sprintf, __ } from '~/locale';
import FileIcon from '~/vue_shared/components/file_icon.vue';
import ChangedFileIcon from '~/vue_shared/components/changed_file_icon.vue';
@@ -8,6 +8,7 @@ import ChangedFileIcon from '~/vue_shared/components/changed_file_icon.vue';
export default {
components: {
GlModal,
+ GlButton,
FileIcon,
ChangedFileIcon,
},
@@ -52,15 +53,16 @@ export default {
</strong>
<changed-file-icon :file="activeFile" :is-centered="false" />
<div class="ml-auto">
- <button
+ <gl-button
v-if="canDiscard"
ref="discardButton"
- type="button"
- class="btn btn-remove btn-inverted gl-mr-3"
+ category="secondary"
+ variant="danger"
+ class="gl-mr-3"
@click="showDiscardModal"
>
{{ __('Discard changes') }}
- </button>
+ </gl-button>
</div>
<gl-modal
ref="discardModal"
diff --git a/app/assets/javascripts/logs/components/environment_logs.vue b/app/assets/javascripts/logs/components/environment_logs.vue
index 97b96cb5839..f7c0bd5ae13 100644
--- a/app/assets/javascripts/logs/components/environment_logs.vue
+++ b/app/assets/javascripts/logs/components/environment_logs.vue
@@ -3,12 +3,11 @@ import { throttle } from 'lodash';
import { mapActions, mapState, mapGetters } from 'vuex';
import {
GlSprintf,
- GlIcon,
GlAlert,
- GlDeprecatedDropdown,
- GlDeprecatedDropdownHeader,
- GlDeprecatedDropdownItem,
- GlDeprecatedDropdownDivider,
+ GlDropdown,
+ GlDropdownSectionHeader,
+ GlDropdownItem,
+ GlDropdownDivider,
GlInfiniteScroll,
} from '@gitlab/ui';
@@ -23,12 +22,11 @@ import { formatDate } from '../utils';
export default {
components: {
GlSprintf,
- GlIcon,
GlAlert,
- GlDeprecatedDropdown,
- GlDeprecatedDropdownHeader,
- GlDeprecatedDropdownItem,
- GlDeprecatedDropdownDivider,
+ GlDropdown,
+ GlDropdownSectionHeader,
+ GlDropdownItem,
+ GlDropdownDivider,
GlInfiniteScroll,
LogSimpleFilters,
LogAdvancedFilters,
@@ -174,46 +172,38 @@ export default {
<div class="top-bar d-md-flex border bg-secondary-50 pt-2 pr-1 pb-0 pl-2">
<div class="flex-grow-0">
- <gl-deprecated-dropdown
+ <gl-dropdown
id="environments-dropdown"
:text="environments.current || managedApps.current"
:disabled="environments.isLoading"
- class="mb-2 gl-h-32 pr-2 d-flex d-md-block js-environments-dropdown"
+ class="gl-mr-3 gl-mb-3 gl-display-flex gl-display-md-block js-environments-dropdown"
>
- <gl-deprecated-dropdown-header class="gl-text-center">
+ <gl-dropdown-section-header>
{{ s__('Environments|Environments') }}
- </gl-deprecated-dropdown-header>
- <gl-deprecated-dropdown-item
+ </gl-dropdown-section-header>
+ <gl-dropdown-item
v-for="env in environments.options"
:key="env.id"
+ :is-check-item="true"
+ :is-checked="isCurrentEnvironment(env.name)"
@click="showEnvironment(env.name)"
>
- <div class="d-flex">
- <gl-icon
- :class="{ invisible: !isCurrentEnvironment(env.name) }"
- name="status_success_borderless"
- />
- <div class="gl-flex-grow-1">{{ env.name }}</div>
- </div>
- </gl-deprecated-dropdown-item>
- <gl-deprecated-dropdown-divider />
- <gl-deprecated-dropdown-header class="gl-text-center">
+ {{ env.name }}
+ </gl-dropdown-item>
+ <gl-dropdown-divider />
+ <gl-dropdown-section-header>
{{ s__('Environments|Managed apps') }}
- </gl-deprecated-dropdown-header>
- <gl-deprecated-dropdown-item
+ </gl-dropdown-section-header>
+ <gl-dropdown-item
v-for="app in managedApps.options"
:key="app.id"
+ :is-check-item="true"
+ :is-checked="isCurrentManagedApp(app.name)"
@click="showManagedApp(app.name)"
>
- <div class="gl-display-flex">
- <gl-icon
- :class="{ invisible: !isCurrentManagedApp(app.name) }"
- name="status_success_borderless"
- />
- <div class="gl-flex-grow-1">{{ app.name }}</div>
- </div>
- </gl-deprecated-dropdown-item>
- </gl-deprecated-dropdown>
+ {{ app.name }}
+ </gl-dropdown-item>
+ </gl-dropdown>
</div>
<log-advanced-filters
diff --git a/app/assets/javascripts/logs/components/log_simple_filters.vue b/app/assets/javascripts/logs/components/log_simple_filters.vue
index 2e1270b5428..ba30d4628c9 100644
--- a/app/assets/javascripts/logs/components/log_simple_filters.vue
+++ b/app/assets/javascripts/logs/components/log_simple_filters.vue
@@ -1,19 +1,13 @@
<script>
import { mapActions, mapState } from 'vuex';
-import {
- GlIcon,
- GlDeprecatedDropdown,
- GlDeprecatedDropdownHeader,
- GlDeprecatedDropdownItem,
-} from '@gitlab/ui';
+import { GlDropdown, GlDropdownSectionHeader, GlDropdownItem } from '@gitlab/ui';
import { s__ } from '~/locale';
export default {
components: {
- GlIcon,
- GlDeprecatedDropdown,
- GlDeprecatedDropdownHeader,
- GlDeprecatedDropdownItem,
+ GlDropdown,
+ GlDropdownSectionHeader,
+ GlDropdownItem,
},
props: {
disabled: {
@@ -44,35 +38,31 @@ export default {
</script>
<template>
<div>
- <gl-deprecated-dropdown
+ <gl-dropdown
ref="podsDropdown"
:text="podDropdownText"
:disabled="disabled"
- class="mb-2 gl-h-32 pr-2 d-flex d-md-block flex-grow-0 qa-pods-dropdown"
+ class="gl-mr-3 gl-mb-3 gl-display-flex gl-display-md-block qa-pods-dropdown"
>
- <gl-deprecated-dropdown-header class="text-center">
+ <gl-dropdown-section-header>
{{ s__('Environments|Select pod') }}
- </gl-deprecated-dropdown-header>
+ </gl-dropdown-section-header>
- <gl-deprecated-dropdown-item v-if="!pods.options.length" disabled>
+ <gl-dropdown-item v-if="!pods.options.length" disabled>
<span ref="noPodsMsg" class="text-muted">
{{ s__('Environments|No pods to display') }}
</span>
- </gl-deprecated-dropdown-item>
- <gl-deprecated-dropdown-item
+ </gl-dropdown-item>
+ <gl-dropdown-item
v-for="podName in pods.options"
:key="podName"
+ :is-check-item="true"
+ :is-checked="isCurrentPod(podName)"
class="text-nowrap"
@click="showPodLogs(podName)"
>
- <div class="d-flex">
- <gl-icon
- :class="{ invisible: !isCurrentPod(podName) }"
- name="status_success_borderless"
- />
- <div class="flex-grow-1">{{ podName }}</div>
- </div>
- </gl-deprecated-dropdown-item>
- </gl-deprecated-dropdown>
+ {{ podName }}
+ </gl-dropdown-item>
+ </gl-dropdown>
</div>
</template>
diff --git a/app/assets/javascripts/milestones/stores/actions.js b/app/assets/javascripts/milestones/stores/actions.js
new file mode 100644
index 00000000000..3859771aeba
--- /dev/null
+++ b/app/assets/javascripts/milestones/stores/actions.js
@@ -0,0 +1,58 @@
+import Api from '~/api';
+import * as types from './mutation_types';
+
+export const setProjectId = ({ commit }, projectId) => commit(types.SET_PROJECT_ID, projectId);
+
+export const setSelectedMilestones = ({ commit }, selectedMilestones) =>
+ commit(types.SET_SELECTED_MILESTONES, selectedMilestones);
+
+export const toggleMilestones = ({ commit, state }, selectedMilestone) => {
+ const removeMilestone = state.selectedMilestones.includes(selectedMilestone);
+
+ if (removeMilestone) {
+ commit(types.REMOVE_SELECTED_MILESTONE, selectedMilestone);
+ } else {
+ commit(types.ADD_SELECTED_MILESTONE, selectedMilestone);
+ }
+};
+
+export const search = ({ dispatch, commit }, query) => {
+ commit(types.SET_QUERY, query);
+
+ dispatch('searchMilestones');
+};
+
+export const fetchMilestones = ({ commit, state }) => {
+ commit(types.REQUEST_START);
+
+ Api.projectMilestones(state.projectId)
+ .then(response => {
+ commit(types.RECEIVE_PROJECT_MILESTONES_SUCCESS, response);
+ })
+ .catch(error => {
+ commit(types.RECEIVE_PROJECT_MILESTONES_ERROR, error);
+ })
+ .finally(() => {
+ commit(types.REQUEST_FINISH);
+ });
+};
+
+export const searchMilestones = ({ commit, state }) => {
+ commit(types.REQUEST_START);
+
+ const options = {
+ search: state.query,
+ scope: 'milestones',
+ };
+
+ Api.projectSearch(state.projectId, options)
+ .then(response => {
+ commit(types.RECEIVE_PROJECT_MILESTONES_SUCCESS, response);
+ })
+ .catch(error => {
+ commit(types.RECEIVE_PROJECT_MILESTONES_ERROR, error);
+ })
+ .finally(() => {
+ commit(types.REQUEST_FINISH);
+ });
+};
diff --git a/app/assets/javascripts/milestones/stores/getters.js b/app/assets/javascripts/milestones/stores/getters.js
new file mode 100644
index 00000000000..d8a283403ec
--- /dev/null
+++ b/app/assets/javascripts/milestones/stores/getters.js
@@ -0,0 +1,2 @@
+/** Returns `true` if there is at least one in-progress request */
+export const isLoading = ({ requestCount }) => requestCount > 0;
diff --git a/app/assets/javascripts/milestones/stores/index.js b/app/assets/javascripts/milestones/stores/index.js
new file mode 100644
index 00000000000..2bebffc19ab
--- /dev/null
+++ b/app/assets/javascripts/milestones/stores/index.js
@@ -0,0 +1,16 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import * as actions from './actions';
+import * as getters from './getters';
+import mutations from './mutations';
+import createState from './state';
+
+Vue.use(Vuex);
+
+export default () =>
+ new Vuex.Store({
+ actions,
+ getters,
+ mutations,
+ state: createState(),
+ });
diff --git a/app/assets/javascripts/milestones/stores/mutation_types.js b/app/assets/javascripts/milestones/stores/mutation_types.js
new file mode 100644
index 00000000000..370d386dba2
--- /dev/null
+++ b/app/assets/javascripts/milestones/stores/mutation_types.js
@@ -0,0 +1,13 @@
+export const SET_PROJECT_ID = 'SET_PROJECT_ID';
+
+export const SET_SELECTED_MILESTONES = 'SET_SELECTED_MILESTONES';
+export const ADD_SELECTED_MILESTONE = 'ADD_SELECTED_MILESTONE';
+export const REMOVE_SELECTED_MILESTONE = 'REMOVE_SELECTED_MILESTONE';
+
+export const SET_QUERY = 'SET_QUERY';
+
+export const REQUEST_START = 'REQUEST_START';
+export const REQUEST_FINISH = 'REQUEST_FINISH';
+
+export const RECEIVE_PROJECT_MILESTONES_SUCCESS = 'RECEIVE_PROJECT_MILESTONES_SUCCESS';
+export const RECEIVE_PROJECT_MILESTONES_ERROR = 'RECEIVE_PROJECT_MILESTONES_ERROR';
diff --git a/app/assets/javascripts/milestones/stores/mutations.js b/app/assets/javascripts/milestones/stores/mutations.js
new file mode 100644
index 00000000000..7c75d09766c
--- /dev/null
+++ b/app/assets/javascripts/milestones/stores/mutations.js
@@ -0,0 +1,44 @@
+import Vue from 'vue';
+import * as types from './mutation_types';
+import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
+
+export default {
+ [types.SET_PROJECT_ID](state, projectId) {
+ state.projectId = projectId;
+ },
+ [types.SET_SELECTED_MILESTONES](state, selectedMilestones) {
+ Vue.set(state, 'selectedMilestones', selectedMilestones);
+ },
+ [types.ADD_SELECTED_MILESTONE](state, selectedMilestone) {
+ state.selectedMilestones.push(selectedMilestone);
+ },
+ [types.REMOVE_SELECTED_MILESTONE](state, selectedMilestone) {
+ const filteredMilestones = state.selectedMilestones.filter(
+ milestone => milestone !== selectedMilestone,
+ );
+ Vue.set(state, 'selectedMilestones', filteredMilestones);
+ },
+ [types.SET_QUERY](state, query) {
+ state.query = query;
+ },
+ [types.REQUEST_START](state) {
+ state.requestCount += 1;
+ },
+ [types.REQUEST_FINISH](state) {
+ state.requestCount -= 1;
+ },
+ [types.RECEIVE_PROJECT_MILESTONES_SUCCESS](state, response) {
+ state.matches.projectMilestones = {
+ list: convertObjectPropsToCamelCase(response.data).map(({ title }) => ({ title })),
+ totalCount: parseInt(response.headers['x-total'], 10),
+ error: null,
+ };
+ },
+ [types.RECEIVE_PROJECT_MILESTONES_ERROR](state, error) {
+ state.matches.projectMilestones = {
+ list: [],
+ totalCount: 0,
+ error,
+ };
+ },
+};
diff --git a/app/assets/javascripts/milestones/stores/state.js b/app/assets/javascripts/milestones/stores/state.js
new file mode 100644
index 00000000000..0944539f367
--- /dev/null
+++ b/app/assets/javascripts/milestones/stores/state.js
@@ -0,0 +1,14 @@
+export default () => ({
+ projectId: null,
+ groupId: null,
+ query: '',
+ matches: {
+ projectMilestones: {
+ list: [],
+ totalCount: 0,
+ error: null,
+ },
+ },
+ selectedMilestones: [],
+ requestCount: 0,
+});
diff --git a/app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue b/app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue
index 5d59880d497..a9079f91f50 100644
--- a/app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue
+++ b/app/assets/javascripts/pages/projects/graphs/components/code_coverage.vue
@@ -1,11 +1,5 @@
<script>
-import {
- GlAlert,
- GlDeprecatedDropdown,
- GlDeprecatedDropdownItem,
- GlIcon,
- GlSprintf,
-} from '@gitlab/ui';
+import { GlAlert, GlDropdown, GlDropdownItem, GlSprintf } from '@gitlab/ui';
import { GlAreaChart } from '@gitlab/ui/dist/charts';
import dateFormat from 'dateformat';
import { get } from 'lodash';
@@ -17,9 +11,8 @@ export default {
components: {
GlAlert,
GlAreaChart,
- GlDeprecatedDropdown,
- GlDeprecatedDropdownItem,
- GlIcon,
+ GlDropdown,
+ GlDropdownItem,
GlSprintf,
},
props: {
@@ -140,25 +133,18 @@ export default {
{{ __('It seems that there is currently no available data for code coverage') }}
</span>
</gl-alert>
- <gl-deprecated-dropdown v-if="canShowData" :text="selectedDailyCoverageName">
- <gl-deprecated-dropdown-item
+ <gl-dropdown v-if="canShowData" :text="selectedDailyCoverageName">
+ <gl-dropdown-item
v-for="({ group_name }, index) in dailyCoverageData"
:key="index"
:value="group_name"
+ :is-check-item="true"
+ :is-checked="index === selectedCoverageIndex"
@click="setSelectedCoverage(index)"
>
- <div class="gl-display-flex">
- <gl-icon
- v-if="index === selectedCoverageIndex"
- name="mobile-issue-close"
- class="gl-absolute"
- />
- <span class="gl-display-flex align-items-center ml-4">
- {{ group_name }}
- </span>
- </div>
- </gl-deprecated-dropdown-item>
- </gl-deprecated-dropdown>
+ {{ group_name }}
+ </gl-dropdown-item>
+ </gl-dropdown>
</div>
<gl-area-chart
v-if="!isLoading"
diff --git a/app/assets/javascripts/vue_shared/components/editor_lite.vue b/app/assets/javascripts/vue_shared/components/editor_lite.vue
index bc3a9ee45f8..cfe3ce0a11c 100644
--- a/app/assets/javascripts/vue_shared/components/editor_lite.vue
+++ b/app/assets/javascripts/vue_shared/components/editor_lite.vue
@@ -58,7 +58,9 @@ export default {
this.editor.updateModelLanguage(newVal);
},
value(newVal) {
- this.editor.setValue(newVal);
+ if (this.editor.getValue() !== newVal) {
+ this.editor.setValue(newVal);
+ }
},
},
mounted() {
diff --git a/app/models/container_expiration_policy.rb b/app/models/container_expiration_policy.rb
index b1dd720d908..641d244b665 100644
--- a/app/models/container_expiration_policy.rb
+++ b/app/models/container_expiration_policy.rb
@@ -3,6 +3,7 @@
class ContainerExpirationPolicy < ApplicationRecord
include Schedulable
include UsageStatistics
+ include EachBatch
belongs_to :project, inverse_of: :container_expiration_policy
@@ -19,6 +20,16 @@ class ContainerExpirationPolicy < ApplicationRecord
scope :active, -> { where(enabled: true) }
scope :preloaded, -> { preload(project: [:route]) }
+ def self.executable
+ runnable_schedules.where(
+ 'EXISTS (?)',
+ ContainerRepository.select(1)
+ .where(
+ 'container_repositories.project_id = container_expiration_policies.project_id'
+ )
+ )
+ end
+
def self.keep_n_options
{
1 => _('%{tags} tag per image name') % { tags: 1 },
diff --git a/app/services/merge_requests/cleanup_refs_service.rb b/app/services/merge_requests/cleanup_refs_service.rb
index 0f03f5f09b4..d003124a112 100644
--- a/app/services/merge_requests/cleanup_refs_service.rb
+++ b/app/services/merge_requests/cleanup_refs_service.rb
@@ -17,7 +17,7 @@ module MergeRequests
@repository = merge_request.project.repository
@ref_path = merge_request.ref_path
@merge_ref_path = merge_request.merge_ref_path
- @ref_head_sha = @repository.commit(merge_request.ref_path).id
+ @ref_head_sha = @repository.commit(merge_request.ref_path)&.id
@merge_ref_sha = merge_request.merge_ref_head&.id
end
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index c5d7b148e69..f6dc808aa55 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -92,7 +92,7 @@
%li.nav-item
%div
- sign_in_text = allow_signup? ? _('Sign in / Register') : _('Sign in')
- = link_to sign_in_text, new_session_path(:user, redirect_to_referer: 'yes'), class: 'gl-button btn btn-sign-in'
+ = link_to sign_in_text, new_session_path(:user, redirect_to_referer: 'yes'), class: 'btn btn-sign-in'
%button.navbar-toggler.d-block.d-sm-none{ type: 'button' }
%span.sr-only= _('Toggle navigation')
diff --git a/app/workers/container_expiration_policy_worker.rb b/app/workers/container_expiration_policy_worker.rb
index 96590e165ae..61ba27f00d2 100644
--- a/app/workers/container_expiration_policy_worker.rb
+++ b/app/workers/container_expiration_policy_worker.rb
@@ -7,13 +7,15 @@ class ContainerExpirationPolicyWorker # rubocop:disable Scalability/IdempotentWo
feature_category :container_registry
def perform
- ContainerExpirationPolicy.runnable_schedules.preloaded.find_each do |container_expiration_policy|
- with_context(project: container_expiration_policy.project,
- user: container_expiration_policy.project.owner) do |project:, user:|
- ContainerExpirationPolicyService.new(project, user)
- .execute(container_expiration_policy)
- rescue ContainerExpirationPolicyService::InvalidPolicyError => e
- Gitlab::ErrorTracking.log_exception(e, container_expiration_policy_id: container_expiration_policy.id)
+ ContainerExpirationPolicy.executable.preloaded.each_batch do |relation|
+ relation.each do |container_expiration_policy|
+ with_context(project: container_expiration_policy.project,
+ user: container_expiration_policy.project.owner) do |project:, user:|
+ ContainerExpirationPolicyService.new(project, user)
+ .execute(container_expiration_policy)
+ rescue ContainerExpirationPolicyService::InvalidPolicyError => e
+ Gitlab::ErrorTracking.log_exception(e, container_expiration_policy_id: container_expiration_policy.id)
+ end
end
end
end