Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-11-14 15:25:06 +00:00
parent 8028505496
commit 415360b8c4
156 changed files with 1236 additions and 1075 deletions

View File

@ -1,6 +1,5 @@
---
FactoryBot/ExcessiveCreateList:
Details: grace period
Exclude:
- 'ee/spec/controllers/groups/hooks_controller_spec.rb'
- 'ee/spec/features/search/elastic/global_search_spec.rb'

View File

@ -1,4 +0,0 @@
---
# Cop supports --autocorrect.
Gemspec/AddRuntimeDependency:
Details: grace period

View File

@ -1,5 +1,4 @@
---
Gitlab/AvoidCurrentOrganization:
Details: grace period
Exclude:
- 'lib/gitlab/github_gists_import/importer/gist_importer.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
Gitlab/DocumentationLinks/Link:
Details: grace period
Exclude:
- '**/*.haml'
- 'app/helpers/releases_helper.rb'

View File

@ -1,6 +1,5 @@
---
Gitlab/EeOnlyClass:
Details: grace period
Exclude:
- 'ee/app/controllers/concerns/ee/routable_actions/sso_enforcement_redirect.rb'
- 'ee/app/graphql/ee/resolvers/pending_group_members_resolver.rb'

View File

@ -1,4 +0,0 @@
---
# Cop supports --autocorrect.
InternalAffairs/CopDescriptionWithExample:
Details: grace period

View File

@ -137,20 +137,6 @@ Layout/LineLength:
- 'app/models/ci/unit_test.rb'
- 'app/models/clusters/agent.rb'
- 'app/models/clusters/cluster.rb'
- 'app/models/commit_range.rb'
- 'app/models/commit_status.rb'
- 'app/models/concerns/analytics/cycle_analytics/stage_event_model.rb'
- 'app/models/concerns/avatarable.rb'
- 'app/models/concerns/bulk_insert_safe.rb'
- 'app/models/concerns/cache_markdown_field.rb'
- 'app/models/concerns/cacheable_attributes.rb'
- 'app/models/concerns/cascading_namespace_setting_attribute.rb'
- 'app/models/concerns/ci/has_status.rb'
- 'app/models/concerns/each_batch.rb'
- 'app/models/concerns/enums/ci/pipeline.rb'
- 'app/models/concerns/enums/vulnerability.rb'
- 'app/models/concerns/fast_destroy_all.rb'
- 'app/models/concerns/group_descendant.rb'
- 'app/models/concerns/ignorable_columns.rb'
- 'app/models/concerns/iid_routes.rb'
- 'app/models/concerns/integrations/has_data_fields.rb'

View File

@ -1,5 +1,4 @@
---
Lint/Debugger:
Details: grace period
Exclude:
- 'spec/support/helpers/docs_screenshot_helpers.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
Lint/SafeNavigationConsistency:
Details: grace period
Exclude:
- 'app/models/concerns/ci/deployable.rb'
- 'app/policies/packages/policies/dependency_proxy/group_policy.rb'

View File

@ -1,6 +1,5 @@
---
# Cop supports --autocorrect.
Lint/Void:
Details: grace period
Exclude:
- 'spec/lib/gitlab/import_export/json/streaming_serializer_spec.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
Rails/Date:
Details: grace period
Exclude:
- 'app/controllers/users_controller.rb'
- 'app/finders/issues_finder.rb'

View File

@ -1,6 +1,5 @@
---
# Cop supports --autocorrect.
Rails/EnumHash:
Details: grace period
Exclude:
- 'app/models/activity_pub/releases_subscription.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
Rails/EnumSyntax:
Details: grace period
Exclude:
- 'app/models/abuse_report.rb'
- 'app/models/alert_management/alert.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
Rails/PluralizationGrammar:
Details: grace period
Exclude:
- 'app/models/application_setting.rb'
- 'app/models/application_setting_implementation.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
Rails/WhereRange:
Details: grace period
Exclude:
- 'app/finders/events_finder.rb'
- 'app/finders/groups_finder.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
RSpec/BeEmpty:
Details: grace period
Exclude:
- 'ee/spec/controllers/subscriptions/groups_controller_spec.rb'
- 'ee/spec/finders/groups/users_finder_spec.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
RSpec/BeEq:
Details: grace period
Exclude:
- 'ee/spec/bin/custom_ability_spec.rb'
- 'ee/spec/controllers/admin/application_settings_controller_spec.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
RSpec/BeNil:
Details: grace period
Exclude:
- 'ee/spec/controllers/projects_controller_spec.rb'
- 'ee/spec/graphql/mutations/issues/set_weight_spec.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
RSpec/ContainExactly:
Details: grace period
Exclude:
- 'ee/spec/controllers/operations_controller_spec.rb'
- 'ee/spec/finders/billed_users_finder_spec.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
RSpec/Dialect:
Details: grace period
Exclude:
- 'ee/spec/controllers/admin/application_settings_controller_spec.rb'
- 'ee/spec/helpers/ee/personal_access_tokens_helper_spec.rb'

View File

@ -1,4 +0,0 @@
---
# Cop supports --autocorrect.
RSpec/DuplicatedMetadata:
Details: grace period

View File

@ -1,4 +0,0 @@
---
# Cop supports --autocorrect.
RSpec/EmptyMetadata:
Details: grace period

View File

@ -1,4 +0,0 @@
---
# Cop supports --autocorrect.
RSpec/EmptyOutput:
Details: grace period

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
RSpec/Eq:
Details: grace period
Exclude:
- 'ee/spec/controllers/admin/application_settings_controller_spec.rb'
- 'spec/controllers/projects/compare_controller_spec.rb'

View File

@ -1,6 +1,5 @@
---
RSpec/ExampleWithoutDescription:
Details: grace period
Exclude:
- 'ee/spec/bin/custom_ability_spec.rb'
- 'ee/spec/components/gitlab_subscriptions/discover_duo_pro_component_spec.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
RSpec/ExcessiveDocstringSpacing:
Details: grace period
Exclude:
- 'ee/spec/controllers/ee/groups/usage_quotas_controller_spec.rb'
- 'ee/spec/features/gitlab_subscriptions/trials/duo_enterprise/creation_with_one_existing_namespace_flow_spec.rb'

View File

@ -1,6 +1,5 @@
---
RSpec/ExpectInLet:
Details: grace period
Exclude:
- 'ee/spec/models/elasticsearch_indexed_namespace_spec.rb'
- 'ee/spec/models/elasticsearch_indexed_project_spec.rb'

View File

@ -1,6 +1,5 @@
---
RSpec/IdenticalEqualityAssertion:
Details: grace period
Exclude:
- 'ee/spec/lib/gitlab/ci/reports/license_scanning/license_spec.rb'
- 'ee/spec/lib/gitlab/elastic/document_reference_spec.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
RSpec/IsExpectedSpecify:
Details: grace period
Exclude:
- 'ee/spec/controllers/groups/analytics/repository_analytics_controller_spec.rb'
- 'ee/spec/graphql/ee/types/branch_protection_type_spec.rb'

View File

@ -1,6 +1,5 @@
---
RSpec/MissingExpectationTargetMethod:
Details: grace period
Exclude:
- 'ee/spec/lib/ee/gitlab/ci/pipeline/chain/validate/external_spec.rb'
- 'spec/config/object_store_settings_spec.rb'

View File

@ -1,6 +1,5 @@
---
RSpec/NoExpectationExample:
Details: grace period
Exclude:
- 'ee/spec/components/gitlab_subscriptions/discover_duo_pro_component_spec.rb'
- 'ee/spec/features/billings/billing_plans_spec.rb'

View File

@ -1,6 +1,5 @@
---
RSpec/PendingWithoutReason:
Details: grace period
Exclude:
- 'ee/spec/controllers/operations_controller_spec.rb'
- 'ee/spec/features/merge_request/user_approves_spec.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
RSpec/ReceiveMessages:
Details: grace period
Exclude:
- 'ee/spec/bin/custom_ability_spec.rb'
- 'ee/spec/components/namespaces/storage/limit_alert_component_spec.rb'

View File

@ -1,6 +1,5 @@
---
# Cop supports --autocorrect.
RSpec/RedundantAround:
Details: grace period
Exclude:
- 'spec/spec_helper.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
RSpec/RedundantPredicateMatcher:
Details: grace period
Exclude:
- 'ee/spec/lib/gitlab/ci/templates/api_fuzzing_gitlab_ci_yaml_spec.rb'
- 'ee/spec/lib/gitlab/ci/templates/api_fuzzing_latest_gitlab_ci_yaml_spec.rb'

View File

@ -1,5 +1,4 @@
---
RSpec/RemoveConst:
Details: grace period
Exclude:
- 'spec/support/helpers/click_house_schema_helpers.rb'

View File

@ -1,6 +1,5 @@
---
RSpec/RepeatedSubjectCall:
Details: grace period
Exclude:
- 'ee/spec/controllers/projects/settings/repository_controller_spec.rb'
- 'ee/spec/controllers/registrations/groups_controller_spec.rb'

View File

@ -1,3 +0,0 @@
---
RSpec/SkipBlockInsideExample:
Details: grace period

View File

@ -1,6 +1,5 @@
---
RSpec/SpecFilePathFormat:
Details: grace period
Exclude:
- 'ee/spec/models/merge_request/blocking_spec.rb'
- 'ee/spec/requests/api/ci/runner/jobs_put_spec.rb'

View File

@ -1,6 +1,5 @@
---
RSpec/SpecFilePathSuffix:
Details: grace period
Exclude:
- 'ee/spec/frontend/fixtures/analytics/charts.rb'
- 'ee/spec/frontend/fixtures/analytics/devops_reports/devops_adoption/enabled_namespaces.rb'

View File

@ -1,5 +1,4 @@
---
RSpec/UndescriptiveLiteralsDescription:
Details: grace period
Exclude:
- 'spec/services/merge_requests/base_service_spec.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
RSpec/VerifiedDoubleReference:
Details: grace period
Exclude:
- 'ee/spec/controllers/groups/analytics/productivity_analytics_controller_spec.rb'
- 'ee/spec/controllers/groups/security/policies_controller_spec.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
Style/ArgumentsForwarding:
Details: grace period
Exclude:
- 'app/controllers/admin/users_controller.rb'
- 'app/controllers/application_controller.rb'

View File

@ -1,4 +0,0 @@
---
# Cop supports --autocorrect.
Style/EmptyLiteral:
Details: grace period

View File

@ -1,4 +0,0 @@
---
# Cop supports --autocorrect.
Style/Iso8601Date:
Details: grace period

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
Style/MapIntoArray:
Details: grace period
Exclude:
- 'app/finders/projects/members/effective_access_level_finder.rb'
- 'app/services/packages/nuget/extract_metadata_content_service.rb'

View File

@ -1,4 +0,0 @@
---
# Cop supports --autocorrect.
Style/RedundantInterpolationUnfreeze:
Details: grace period

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
Style/SendWithLiteralMethodName:
Details: grace period
Exclude:
- 'ee/spec/models/ci/build_spec.rb'
- 'lib/gitlab/database/load_balancing/connection_proxy.rb'

View File

@ -1,7 +1,6 @@
---
# Cop supports --autocorrect.
Style/SuperArguments:
Details: grace period
Exclude:
- 'app/finders/merge_requests_finder.rb'
- 'app/finders/packages/composer/packages_finder.rb'

View File

@ -0,0 +1,14 @@
import $ from 'jquery';
if (gon.features?.findAndReplace) {
$(document).on('markdown-editor:find-and-replace', (e, keyboardEvent) => {
const $target = $(keyboardEvent.target);
if ($target.is('textarea.markdown-area')) {
$(document).triggerHandler('markdown-editor:find-and-replace:show', [
$target.closest('form'),
]);
keyboardEvent.preventDefault();
}
});
}

View File

@ -10,6 +10,7 @@ import { initGlobalAlerts } from './global_alerts';
import './shortcuts';
import './toggler_behavior';
import './preview_markdown';
import './find_and_replace';
installGlEmojiElement();
initCopyAsGFM();

View File

@ -1,6 +1,6 @@
import { memoize } from 'lodash';
import AccessorUtilities from '~/lib/utils/accessor';
import { __ } from '~/locale';
import { __, s__ } from '~/locale';
/**
* @param {object} command
@ -174,6 +174,13 @@ export const OUTDENT_LINE = {
customizable: false,
};
export const FIND_AND_REPLACE = {
id: 'editing.findAndReplace',
description: s__('MarkdownEditor|Find and replace'),
defaultKeys: ['mod+f'],
customizable: false,
};
export const TOGGLE_MARKDOWN_PREVIEW = {
id: 'editing.toggleMarkdownPreview',
description: __('Toggle Markdown preview'),
@ -589,6 +596,7 @@ export const EDITING_SHORTCUTS_GROUP = {
STRIKETHROUGH_TEXT,
LINK_TEXT,
TOGGLE_MARKDOWN_PREVIEW,
FIND_AND_REPLACE,
EDIT_RECENT_COMMENT,
SAVE_CHANGES,
],

View File

@ -18,6 +18,7 @@ import {
HIDE_APPEARING_CONTENT,
TOGGLE_CANARY,
TOGGLE_MARKDOWN_PREVIEW,
FIND_AND_REPLACE,
GO_TO_YOUR_TODO_LIST,
GO_TO_ACTIVITY_FEED,
GO_TO_YOUR_ISSUES,
@ -113,6 +114,14 @@ export default class Shortcuts {
keysFor(TOGGLE_MARKDOWN_PREVIEW).includes(combo) ? false : undefined,
);
if (gon?.features?.findAndReplace) {
this.add(FIND_AND_REPLACE, Shortcuts.toggleFindAndReplaceBar);
addStopCallback((e, element, combo) =>
keysFor(FIND_AND_REPLACE).includes(combo) ? false : undefined,
);
}
$(document).on('click', '.js-shortcuts-modal-trigger', this.onToggleHelp);
if (shouldDisableShortcuts()) {
@ -255,6 +264,10 @@ export default class Shortcuts {
$(document).triggerHandler('markdown-preview:toggle', [e]);
}
static toggleFindAndReplaceBar(e) {
$(document).triggerHandler('markdown-editor:find-and-replace', [e]);
}
focusFilter(e) {
if (!this.filterInput) {
this.filterInput = $('input[type=search]', '.nav-controls');

View File

@ -45,7 +45,7 @@ export default {
{{ pipelineId }}
</gl-link>
<span class="gl-text-secondary">
<span class="gl-text-subtle">
<span>{{ __('created by') }}</span>
<gl-link v-if="showAvatar" :href="userPath" data-testid="pipeline-user-link">
<gl-avatar :src="pipelineUserAvatar" :size="16" />
@ -54,7 +54,7 @@ export default {
</span>
</div>
<div v-if="job.stage" class="gl-mt-1 gl-truncate gl-text-sm gl-text-secondary">
<div v-if="job.stage" class="gl-mt-1 gl-truncate gl-text-sm gl-text-subtle">
<span data-testid="job-stage-name">{{ $options.i18n.stageLabel }}: {{ job.stage.name }}</span>
</div>
</div>

View File

@ -39,7 +39,7 @@ export default {
<template>
<div>
<ci-icon :status="job.detailedStatus" show-status-text />
<div class="gl-ml-1 gl-mt-2 gl-text-sm gl-text-secondary">
<div class="gl-ml-1 gl-mt-2 gl-text-sm gl-text-subtle">
<div v-if="duration" data-testid="job-duration">
<gl-icon name="timer" :size="$options.iconSize" data-testid="duration-icon" />
{{ durationFormatted }}

View File

@ -739,6 +739,9 @@ export default {
this.toggleTreeList();
this.adjustView();
},
isDiffViewActive(item) {
return this.virtualScrollCurrentIndex >= 0 && this.currentDiffFileId === item.file_hash;
},
},
howToMergeDocsPath: helpPagePath('user/project/merge_requests/merge_request_troubleshooting.md', {
anchor: 'check-out-merge-requests-locally-through-the-head-ref',
@ -812,6 +815,7 @@ export default {
:item="item"
:active="active"
:class="{ active }"
class="gl-mb-5"
>
<diff-file
:file="item"
@ -824,7 +828,7 @@ export default {
:can-current-user-fork="canCurrentUserFork"
:view-diffs-file-by-file="viewDiffsFileByFile"
:active="active"
:is-diff-view-active="currentDiffFileId === item.file_hash"
:is-diff-view-active="isDiffViewActive(item)"
/>
</dynamic-scroller-item>
</template>
@ -846,6 +850,7 @@ export default {
:can-current-user-fork="canCurrentUserFork"
:view-diffs-file-by-file="viewDiffsFileByFile"
:is-diff-view-active="currentDiffFileId === file.file_hash"
class="gl-mb-5"
/>
</template>
<div

View File

@ -430,11 +430,10 @@ export default {
'has-body': showBody,
'is-virtual-scrolling': isVirtualScrollingEnabled,
'linked-file': isLinkedFile,
'gl-border-gray-200': isDiffViewActive && !file.conflict_type,
'gl-border-red-700': isDiffViewActive && file.conflict_type,
'diff-file-is-active': isDiffViewActive,
}"
:data-path="file.new_path"
class="diff-file file-holder gl-mb-5"
class="diff-file file-holder"
>
<gl-alert
v-if="!showLoadingIcon && file.conflict_type"
@ -492,8 +491,6 @@ export default {
hasBodyClasses.header,
{
'!gl-rounded-none !gl-bg-red-200': file.conflict_type,
'!gl-bg-strong': isDiffViewActive && !file.conflict_type,
'!gl-bg-red-300': isDiffViewActive && file.conflict_type,
'!gl-rounded-tl-none !gl-rounded-tr-none': file.conflict_type && isCollapsed,
'!gl-border-0': file.conflict_type || isCollapsed,
},
@ -504,7 +501,7 @@ export default {
<div
v-if="idState.forkMessageVisible"
class="js-file-fork-suggestion-section file-fork-suggestion gl-border-1 gl-border-t-0 gl-border-solid gl-border-gray-100"
class="js-file-fork-suggestion-section file-fork-suggestion gl-border-1 gl-border-t-0 gl-border-solid gl-border-default"
>
<span v-safe-html="forkMessage" class="file-fork-suggestion-note"></span>
<gl-button

View File

@ -95,9 +95,7 @@ export default {
};
},
skip() {
return (
!this.glFeatures.realtimeIssuableTodo || !todoQueries[this.issuableType].subscription
);
return !todoQueries[this.issuableType].subscription;
},
},
},

View File

@ -1,6 +1,6 @@
<!-- eslint-disable vue/multi-word-component-names -->
<script>
import { GlPopover, GlButton, GlTooltipDirective } from '@gitlab/ui';
import { GlPopover, GlButton, GlTooltipDirective, GlFormInput } from '@gitlab/ui';
import $ from 'jquery';
import {
keysFor,
@ -10,6 +10,7 @@ import {
LINK_TEXT,
INDENT_LINE,
OUTDENT_LINE,
FIND_AND_REPLACE,
} from '~/behaviors/shortcuts/keybindings';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { getModifierKey } from '~/constants';
@ -28,6 +29,7 @@ export default {
ToolbarButton,
GlPopover,
GlButton,
GlFormInput,
DrawioToolbarButton,
CommentTemplatesModal,
AiActionsDropdown: () => import('ee_component/ai/components/ai_actions_dropdown.vue'),
@ -108,6 +110,11 @@ export default {
return {
tag: '> ',
suggestPopoverVisible: false,
shouldShowFindAndReplaceBar: false,
findAndReplace: {
find: '',
replace: '',
},
modifierKey,
shiftKey: modifierKey === '⌘' ? '⇧' : 'Shift+',
};
@ -144,6 +151,11 @@ export default {
!this.newCommentTemplatePath)
);
},
showFindAndReplaceButton() {
return (
this.glFeatures.findAndReplace && !this.restrictedToolBarItems.includes('find-and-replace')
);
},
},
watch: {
showSuggestPopover() {
@ -153,12 +165,14 @@ export default {
mounted() {
$(document).on('markdown-preview:show.vue', this.showMarkdownPreview);
$(document).on('markdown-preview:hide.vue', this.hideMarkdownPreview);
$(document).on('markdown-editor:find-and-replace:show', this.showFindAndReplaceBar);
this.updateSuggestPopoverVisibility();
},
beforeDestroy() {
$(document).off('markdown-preview:show.vue', this.showMarkdownPreview);
$(document).off('markdown-preview:hide.vue', this.hideMarkdownPreview);
$(document).off('markdown-editor:find-and-replace:show', this.showFindAndReplaceBar);
},
methods: {
async updateSuggestPopoverVisibility() {
@ -243,6 +257,21 @@ export default {
this.$el.closest('.md-area')?.querySelector('textarea')?.focus();
}, 500);
},
showFindAndReplaceBar(_, form) {
if (!this.isValid(form)) return;
this.shouldShowFindAndReplaceBar = true;
},
handleKeyDown(e) {
if (e.key === 'Enter') {
e.preventDefault();
return;
}
if (e.key === 'Escape') {
this.shouldShowFindAndReplaceBar = false;
}
},
},
shortcuts: {
bold: keysFor(BOLD_TEXT),
@ -251,6 +280,7 @@ export default {
link: keysFor(LINK_TEXT),
indent: keysFor(INDENT_LINE),
outdent: keysFor(OUTDENT_LINE),
findAndReplace: keysFor(FIND_AND_REPLACE),
},
i18n: {
comment: __('This comment was generated by AI'),
@ -545,7 +575,27 @@ export default {
tracking-property="fullScreen"
/>
</div>
<toolbar-button
v-if="showFindAndReplaceButton"
v-show="!previewMarkdown"
class="gl-hidden"
:button-title="s__('MarkdownEditor|Find and replace')"
:shortcuts="$options.shortcuts.findAndReplace"
icon="retry"
/>
</div>
</div>
<div
v-if="shouldShowFindAndReplaceBar"
class="gl-border gl-absolute gl-right-0 gl-z-1 gl-flex gl-w-34 gl-rounded-bl-base gl-border-r-0 gl-bg-section gl-p-3 gl-shadow-sm"
data-testid="find-and-replace"
>
<gl-form-input
v-model="findAndReplace.find"
:placeholder="__('Find')"
autofocus
@keydown="handleKeyDown"
/>
</div>
</div>
</template>

View File

@ -16,6 +16,11 @@ $diff-file-header: 41px;
.diff-file {
margin-bottom: $gl-padding;
&.diff-file-is-active,
&:has(*:not(textarea):focus-visible) {
box-shadow: 0 0 0 2px var(--gl-border-color-strong);
}
table.code tr:last-of-type td:last-of-type {
border-bottom-right-radius: $gl-border-radius-base-inner;
}
@ -48,17 +53,6 @@ $diff-file-header: 41px;
top: calc(#{$calc-application-header-height} + #{$mr-sticky-header-height} + #{$diff-file-header} - #{$gl-border-size-1});
}
&::before {
content: '';
position: absolute;
top: -1px;
left: -11px;
width: 10px;
height: calc(100% + 1px);
@apply gl-bg-default;
pointer-events: none;
}
&.is-commit,
&.is-compare,
&.is-wiki {
@ -655,12 +649,6 @@ table.code {
}
}
.files {
.diff-file:not(.is-virtual-scrolling):last-child {
margin-bottom: 0;
}
}
.diff-comments-more-count,
.diff-notes-collapse,
.inline-findings-collapse {

View File

@ -42,7 +42,7 @@
@include clearfix;
padding: 10px 0;
border-bottom: 1px solid $gray-100;
@apply gl-border-b gl-border-b-subtle;
display: block;
margin: 0;
@ -51,10 +51,10 @@
}
&.active {
background: $gray-10;
@apply gl-bg-subtle;
a {
font-weight: $gl-font-weight-bold;
@apply gl-font-bold;
}
}

View File

@ -286,7 +286,7 @@
vertical-align: top;
padding-top: $gl-spacing-scale-4;
padding-bottom: $gl-spacing-scale-4;
border-bottom: 1px solid var(--gray-50, $gray-50);
@apply gl-border-b gl-border-b-subtle;
}
.project-row:last-of-type {
@ -302,7 +302,7 @@
.stats {
float: right;
line-height: $list-text-height;
color: $gl-text-color-secondary;
@apply gl-text-subtle;
@include media-breakpoint-down(xs) {
padding-top: $gl-padding-6;

View File

@ -7,5 +7,5 @@
= actions
- if description? || @description
.gl-w-full.gl-mt-2.gl-text-secondary{ data: { testid: 'page-heading-description' } }
.gl-w-full.gl-mt-2.gl-text-subtle{ data: { testid: 'page-heading-description' } }
= description || @description

View File

@ -48,7 +48,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:reviewer_assign_drawer, current_user)
push_frontend_feature_flag(:vulnerability_code_flow, project)
push_frontend_feature_flag(:pipeline_vulnerability_code_flow, project)
push_frontend_feature_flag(:realtime_issuable_todo, current_user)
end
around_action :allow_gitaly_ref_name_caching, only: [:index, :show, :diffs, :rapid_diffs, :discussions]

View File

@ -73,8 +73,7 @@ module GraphqlTriggers
::GitlabSchema.subscriptions.trigger('workItemUpdated', { work_item_id: work_item.to_gid }, work_item)
end
def self.issuable_todo_updated(issuable, user)
return if ::Feature.disabled?(:realtime_issuable_todo, user)
def self.issuable_todo_updated(issuable)
return unless issuable.respond_to?(:to_gid)
::GitlabSchema.subscriptions.trigger(

View File

@ -4,6 +4,8 @@ module Routing
module PseudonymizationHelper
PSEUDONOMIZED_NAMESPACE = "namespace"
PSEUDONOMIZED_PROJECT = "project"
PSEUDONOMIZED_GROUP = "group"
PSEUDONOMIZED_ID = "id"
class MaskHelper
QUERY_PARAMS_TO_NOT_MASK = %w[
@ -109,19 +111,27 @@ module Routing
return unless params && params[:controller]
return if params[:action] == "route_not_found"
original_id = params[:id]
case params[:controller]
when 'groups'
params[:id] = PSEUDONOMIZED_NAMESPACE
when 'projects'
params[:id] = PSEUDONOMIZED_PROJECT
params[:namespace_id] = PSEUDONOMIZED_NAMESPACE
else
params[:project_id] = PSEUDONOMIZED_PROJECT if params[:project_id]
params[:namespace_id] = PSEUDONOMIZED_NAMESPACE if params[:namespace_id]
params[:id] = PSEUDONOMIZED_ID if params[:id]
end
params[:project_id] = PSEUDONOMIZED_PROJECT if params[:project_id]
params[:group_id] = PSEUDONOMIZED_GROUP if params[:group_id]
params[:namespace_id] = PSEUDONOMIZED_NAMESPACE if params[:namespace_id]
masked_query_params = masked_query_params(URI.parse(url))
Gitlab::Routing.url_helpers.url_for(params.merge(params: masked_query_params))
rescue ActionController::UrlGenerationError
# If URL cannot be constructed with placeholder, use original ID
params[:id] = original_id
Gitlab::Routing.url_helpers.url_for(params.merge(params: masked_query_params))
end

View File

@ -10,6 +10,8 @@ module Ci
self.table_name = 'catalog_resource_component_last_usages'
self.primary_key = :id
scope :older_than_30_days, -> { where(last_used_date: ...30.days.ago.to_date) }
belongs_to :component, class_name: 'Ci::Catalog::Resources::Component', inverse_of: :last_usages
belongs_to :catalog_resource, class_name: 'Ci::Catalog::Resource', inverse_of: :component_last_usages
belongs_to :component_project, class_name: 'Project', inverse_of: :ci_component_last_usages

View File

@ -8,9 +8,15 @@
# range.exclude_start? # => false
# range.to_s # => "f3f85602...e86e1013"
#
# range = CommitRange.new('f3f856029bc5f966c5a7ee24cf7efefdd20e6019..e86e1013709735be5bb767e2b228930c543f25ae', project)
# range = CommitRange.new(
# 'f3f856029bc5f966c5a7ee24cf7efefdd20e6019..e86e1013709735be5bb767e2b228930c543f25ae',
# project
# )
# range.exclude_start? # => true
# range.to_param # => {from: "f3f856029bc5f966c5a7ee24cf7efefdd20e6019^", to: "e86e1013709735be5bb767e2b228930c543f25ae"}
# range.to_param # => {
# from: "f3f856029bc5f966c5a7ee24cf7efefdd20e6019^",
# to: "e86e1013709735be5bb767e2b228930c543f25ae"
# }
# range.to_s # => "f3f85602..e86e1013"
#
# # Assuming the specified project has a repository containing both commits:

View File

@ -18,9 +18,18 @@ class CommitStatus < Ci::ApplicationRecord
belongs_to :user
belongs_to :project
belongs_to :pipeline, ->(build) { in_partition(build) }, class_name: 'Ci::Pipeline', foreign_key: :commit_id, inverse_of: :statuses, partition_foreign_key: :partition_id
belongs_to :pipeline,
->(build) { in_partition(build) },
class_name: 'Ci::Pipeline',
foreign_key: :commit_id,
inverse_of: :statuses,
partition_foreign_key: :partition_id
belongs_to :auto_canceled_by, class_name: 'Ci::Pipeline', inverse_of: :auto_canceled_jobs
belongs_to :ci_stage, ->(build) { in_partition(build) }, class_name: 'Ci::Stage', foreign_key: :stage_id, partition_foreign_key: :partition_id
belongs_to :ci_stage,
->(build) { in_partition(build) },
class_name: 'Ci::Stage',
foreign_key: :stage_id,
partition_foreign_key: :partition_id
has_many :needs, class_name: 'Ci::BuildNeed', foreign_key: :build_id, inverse_of: :build
@ -141,7 +150,16 @@ class CommitStatus < Ci::ApplicationRecord
event :drop do
transition canceling: :canceled # runner returns success/failed
transition [:created, :waiting_for_resource, :preparing, :waiting_for_callback, :pending, :running, :manual, :scheduled] => :failed
transition [
:created,
:waiting_for_resource,
:preparing,
:waiting_for_callback,
:pending,
:running,
:manual,
:scheduled
] => :failed
end
event :success do
@ -154,7 +172,14 @@ class CommitStatus < Ci::ApplicationRecord
transition CANCELABLE_STATUSES.map(&:to_sym) + [:manual] => :canceled
end
before_transition [:created, :waiting_for_resource, :preparing, :skipped, :manual, :scheduled] => :pending do |commit_status|
before_transition [
:created,
:waiting_for_resource,
:preparing,
:skipped,
:manual,
:scheduled
] => :pending do |commit_status|
commit_status.queued_at = Time.current
end

View File

@ -18,12 +18,19 @@ module Analytics
scope :start_event_timestamp_before, ->(date) { where(arel_table[:start_event_timestamp].lteq(date)) }
scope :authored, ->(user) { where(author_id: user) }
scope :with_milestone_id, ->(milestone_id) { where(milestone_id: milestone_id) }
scope :without_milestone_id, ->(milestone_id) { where('milestone_id <> ? or milestone_id IS NULL', milestone_id) }
scope :without_milestone_id,
->(milestone_id) { where('milestone_id <> ? or milestone_id IS NULL', milestone_id) }
scope :end_event_is_not_happened_yet, -> { where(end_event_timestamp: nil) }
scope :for_consistency_check_worker, ->(direction) do
keyset_order(
:end_event_timestamp => { order_expression: arel_order(arel_table[:end_event_timestamp], direction), nullable: direction == :asc ? :nulls_last : :nulls_first },
issuable_id_column => { order_expression: arel_order(arel_table[issuable_id_column], direction), nullable: :not_nullable }
:end_event_timestamp => {
order_expression: arel_order(arel_table[:end_event_timestamp], direction),
nullable: direction == :asc ? :nulls_last : :nulls_first
},
issuable_id_column => {
order_expression: arel_order(arel_table[issuable_id_column], direction),
nullable: :not_nullable
}
)
end
scope :order_by_end_event, ->(direction) do
@ -31,7 +38,10 @@ module Analytics
# start_event_timestamp must be included in the ORDER BY clause for the duration
# calculation to work: SELECT end_event_timestamp - start_event_timestamp
keyset_order(
:end_event_timestamp => { order_expression: arel_order(arel_table[:end_event_timestamp], direction), nullable: direction == :asc ? :nulls_last : :nulls_first },
:end_event_timestamp => {
order_expression: arel_order(arel_table[:end_event_timestamp], direction),
nullable: direction == :asc ? :nulls_last : :nulls_first
},
issuable_id_column => { order_expression: arel_order(arel_table[issuable_id_column], direction) },
:start_event_timestamp => { order_expression: arel_order(arel_table[:start_event_timestamp], direction) }
)
@ -41,7 +51,10 @@ module Analytics
# start_event_timestamp must be included in the ORDER BY clause for the duration
# calculation to work: SELECT end_event_timestamp - start_event_timestamp
keyset_order(
:end_event_timestamp => { order_expression: arel_order(arel_table[:end_event_timestamp], direction), nullable: direction == :asc ? :nulls_last : :nulls_first },
:end_event_timestamp => {
order_expression: arel_order(arel_table[:end_event_timestamp], direction),
nullable: direction == :asc ? :nulls_last : :nulls_first
},
issuable_id_column => { order_expression: arel_order(arel_table[issuable_id_column], direction) },
:start_event_timestamp => { order_expression: arel_order(arel_table[:start_event_timestamp], direction) },
:duration_in_milliseconds => {

View File

@ -52,7 +52,9 @@ module Avatarable
def avatar_type
unless self.avatar.image?
errors.add :avatar, "file format is not supported. Please try one of the following supported formats: #{AvatarUploader::SAFE_IMAGE_EXT.join(', ')}"
errors.add :avatar,
"file format is not supported. " \
"Please try one of the following supported formats: #{AvatarUploader::SAFE_IMAGE_EXT.join(', ')}"
end
end

View File

@ -93,14 +93,24 @@ module BulkInsertSafe
#
# @return true if operation succeeded, throws otherwise.
#
def bulk_insert!(items, validate: true, skip_duplicates: false, returns: nil, unique_by: nil, batch_size: DEFAULT_BATCH_SIZE, &handle_attributes)
_bulk_insert_all!(items,
def bulk_insert!(
items,
validate: true,
skip_duplicates: false,
returns: nil,
unique_by: nil,
batch_size: DEFAULT_BATCH_SIZE,
&handle_attributes
)
_bulk_insert_all!(
items,
validate: validate,
on_duplicate: skip_duplicates ? :skip : :raise,
returns: returns,
unique_by: unique_by,
batch_size: batch_size,
&handle_attributes)
&handle_attributes
)
end
# Upserts the given ActiveRecord [items] to the table mapped to this class.
@ -128,14 +138,23 @@ module BulkInsertSafe
#
# @return true if operation succeeded, throws otherwise.
#
def bulk_upsert!(items, unique_by:, returns: nil, validate: true, batch_size: DEFAULT_BATCH_SIZE, &handle_attributes)
_bulk_insert_all!(items,
def bulk_upsert!(
items,
unique_by:,
returns: nil,
validate: true,
batch_size: DEFAULT_BATCH_SIZE,
&handle_attributes
)
_bulk_insert_all!(
items,
validate: validate,
on_duplicate: :update,
returns: returns,
unique_by: unique_by,
batch_size: batch_size,
&handle_attributes)
&handle_attributes
)
end
private
@ -161,11 +180,16 @@ module BulkInsertSafe
transaction do
items.each_slice(batch_size).flat_map do |item_batch|
attributes = _bulk_insert_item_attributes(
item_batch, validate, &handle_attributes)
attributes = _bulk_insert_item_attributes(item_batch, validate, &handle_attributes)
ActiveRecord::InsertAll
.new(insert_all_proxy_class, attributes, on_duplicate: on_duplicate, returning: returning, unique_by: unique_by)
.new(
insert_all_proxy_class,
attributes,
on_duplicate: on_duplicate,
returning: returning,
unique_by: unique_by
)
.execute
.cast_values(insert_all_proxy_class.attribute_types).to_a
end

View File

@ -117,8 +117,10 @@ module CacheMarkdownField
refresh_markdown_cache
else
# Invalidated due to stale HTML cache
# This could happen when the Markdown cache version is bumped or when a model is imported and the HTML is empty.
# We persist the updated HTML here so that subsequent calls to this method do not have to regenerate the HTML again.
# This could happen when the Markdown cache version is bumped
# or when a model is imported and the HTML is empty.
# We persist the updated HTML here so that subsequent calls
# to this method do not have to regenerate the HTML again.
refresh_markdown_cache!
end
end
@ -133,7 +135,9 @@ module CacheMarkdownField
# rubocop:disable Gitlab/ModuleWithInstanceVariables -- acceptable use case
# See https://docs.gitlab.com/ee/development/module_with_instance_variables.html#acceptable-use
@latest_cached_markdown_version ||= Gitlab::MarkdownCache.latest_cached_markdown_version(local_version: local_version)
@latest_cached_markdown_version ||= Gitlab::MarkdownCache.latest_cached_markdown_version(
local_version: local_version
)
# rubocop:enable Gitlab/ModuleWithInstanceVariables
end

View File

@ -83,6 +83,10 @@ module CacheableAttributes
end
def cache!
self.class.cache_backend.write(self.class.cache_key, self, expires_in: Gitlab.config.gitlab['application_settings_cache_seconds'] || 60)
self.class.cache_backend.write(
self.class.cache_key,
self,
expires_in: Gitlab.config.gitlab['application_settings_cache_seconds'] || 60
)
end
end

View File

@ -39,7 +39,8 @@ module CascadingNamespaceSettingAttribute
# - `toggle_security_policy_custom_ci_locked_by_ancestor?`
# - `toggle_security_policy_custom_ci_locked_by_application_setting?`
# - `toggle_security_policy_custom_ci?` (only defined for boolean attributes)
# - `toggle_security_policy_custom_ci_locked_ancestor` - Returns locked namespace settings object (only namespace_id)
# - `toggle_security_policy_custom_ci_locked_ancestor` - Returns locked namespace settings object
# (only namespace_id)
#
# Defined validators ensure attribute value cannot be updated if locked by
# an ancestor or application settings.
@ -64,7 +65,9 @@ module CascadingNamespaceSettingAttribute
validate :"lock_#{attribute}_changeable?"
before_save :"before_save_#{attribute}", if: -> { will_save_change_to_attribute?(attribute) }
after_update :"clear_descendant_#{attribute}_locks", if: -> { saved_change_to_attribute?("lock_#{attribute}", to: true) }
after_update :"clear_descendant_#{attribute}_locks", if: -> {
saved_change_to_attribute?("lock_#{attribute}", to: true)
}
end
end
@ -162,7 +165,10 @@ module CascadingNamespaceSettingAttribute
return unless cascading_attribute_changed?("lock_#{attribute}")
if cascading_attribute_locked?(attribute, include_self: false)
return errors.add(:"lock_#{attribute}", s_('CascadingSettings|cannot be changed because it is locked by an ancestor'))
return errors.add(
:"lock_#{attribute}",
s_('CascadingSettings|cannot be changed because it is locked by an ancestor')
)
end
# Don't allow locking a `nil` attribute.
@ -231,8 +237,9 @@ module CascadingNamespaceSettingAttribute
self.class
.select(attribute)
.joins("join unnest(ARRAY[#{namespace_ancestor_ids.join(',')}]) with ordinality t(namespace_id, ord) USING (namespace_id)")
.where("#{attribute} IS NOT NULL")
.joins(
"join unnest(ARRAY[#{namespace_ancestor_ids.join(',')}]) with ordinality t(namespace_id, ord) USING (namespace_id)"
).where("#{attribute} IS NOT NULL")
.order('t.ord')
.limit(1).first&.read_attribute(attribute)
end

View File

@ -6,13 +6,41 @@ module Ci
DEFAULT_STATUS = 'created'
BLOCKED_STATUS = %w[manual scheduled].freeze
AVAILABLE_STATUSES = %w[created waiting_for_resource preparing waiting_for_callback pending running success failed canceling canceled skipped manual scheduled].freeze
AVAILABLE_STATUSES = %w[
created
waiting_for_resource
preparing
waiting_for_callback
pending
running
success
failed
canceling
canceled
skipped
manual
scheduled
].freeze
STARTED_STATUSES = %w[running success failed].freeze
ACTIVE_STATUSES = %w[waiting_for_resource preparing waiting_for_callback pending running].freeze
COMPLETED_STATUSES = %w[success failed canceled skipped].freeze
COMPLETED_WITH_MANUAL_STATUSES = COMPLETED_STATUSES + %w[manual]
STOPPED_STATUSES = COMPLETED_STATUSES + BLOCKED_STATUS
ORDERED_STATUSES = %w[failed preparing pending running waiting_for_callback waiting_for_resource manual scheduled canceling canceled success skipped created].freeze
ORDERED_STATUSES = %w[
failed
preparing
pending
running
waiting_for_callback
waiting_for_resource
manual
scheduled
canceling
canceled
success
skipped
created
].freeze
PASSED_WITH_WARNINGS_STATUSES = %w[failed canceled].to_set.freeze
IGNORED_STATUSES = %w[manual].to_set.freeze
EXECUTING_STATUSES = %w[running canceling].freeze

View File

@ -35,7 +35,8 @@ module EachBatch
#
# This will produce SQL queries along the lines of:
#
# User Load (0.7ms) SELECT "users"."id" FROM "users" WHERE ("users"."id" >= 41654) ORDER BY "users"."id" ASC LIMIT 1 OFFSET 1000
# User Load (0.7ms) SELECT "users"."id" FROM "users" WHERE ("users"."id" >= 41654)
# ORDER BY "users"."id" ASC LIMIT 1 OFFSET 1000
# (0.7ms) SELECT COUNT(*) FROM "users" WHERE ("users"."id" >= 41654) AND ("users"."id" < 42687)
#
# of - The number of rows to retrieve per batch.

View File

@ -66,7 +66,15 @@ module Enums
# - when a container_registry_push pipeline runs it is for security testing purpose and should
# not affect the ref CI status.
def self.dangling_sources
sources.slice(:webide, :parent_pipeline, :ondemand_dast_scan, :ondemand_dast_validation, :security_orchestration_policy, :container_registry_push, :duo_workflow)
sources.slice(
:webide,
:parent_pipeline,
:ondemand_dast_scan,
:ondemand_dast_validation,
:security_orchestration_policy,
:container_registry_push,
:duo_workflow
)
end
# CI sources are those pipeline events that affect the CI status of the ref

View File

@ -37,8 +37,9 @@ module Enums
security_audit: 4
}.with_indifferent_access.freeze
# keep the order of the values in the state enum, it is used in state_order method to properly order vulnerabilities based on state
# remember to recreate index_vulnerabilities_on_state_case_id index when you update or extend this enum
# keep the order of the values in the state enum, it is used in state_order method
# to properly order vulnerabilities based on state remember to recreate
# index_vulnerabilities_on_state_case_id index when you update or extend this enum
VULNERABILITY_STATES = {
detected: 1,
confirmed: 4,

View File

@ -15,7 +15,8 @@
#
# Situation
# - `Project` has many `Ci::BuildTraceChunk` through `Ci::Build`
# - `Ci::BuildTraceChunk` stores associated data in Redis, so it relies on `dependent: :destroy` and `before_destroy` for the deletion
# - `Ci::BuildTraceChunk` stores associated data in Redis,
# so it relies on `dependent: :destroy` and `before_destroy` for the deletion
#
# How to use
# - Define `use_fast_destroy :build_trace_chunks` in `Project` model.

View File

@ -36,7 +36,9 @@ module GroupDescendant
def expand_hierarchy_for_child(child, hierarchy, hierarchy_top, preloaded)
parent = hierarchy_top if hierarchy_top && child.parent_id == hierarchy_top.id
parent ||= preloaded.detect { |possible_parent| possible_parent.is_a?(Group) && possible_parent.id == child.parent_id }
parent ||= preloaded.detect do |possible_parent|
possible_parent.is_a?(Group) && possible_parent.id == child.parent_id
end
if parent.nil? && !child.parent_id.nil?
parent = child.parent

View File

@ -49,7 +49,7 @@ module Users
SQL
::Gitlab::Database::LoadBalancing::SessionMap
.current(connection.load_balancer).fallback_to_replicas_for_ambiguous_queries do
.current(load_balancer).fallback_to_replicas_for_ambiguous_queries do
connection.execute(sql).to_a
end
end

View File

@ -4,6 +4,10 @@ module WorkItems
module Widgets
class LinkedItems < Base
delegate :linked_work_items, to: :work_item
def self.quick_action_commands
[:blocks, :blocked_by]
end
end
end
end

View File

@ -116,7 +116,7 @@ module IssuableLinks
end
def references(extractor)
extractor.issues
extractor.issues + extractor.work_items
end
def extractor_context

View File

@ -43,6 +43,16 @@ module Projects
tracker = create_status_tracker
unless tracker.persisted?
return error(
format(
_('Relation import could not be created: %{errors}'),
errors: tracker.errors.full_messages.to_sentence
),
:bad_request
)
end
attach_import_file
Projects::ImportExport::RelationImportWorker.perform_async(

View File

@ -208,7 +208,7 @@ class TodoService
resolve_todos(pending_todos([current_user], attributes), current_user)
GraphqlTriggers.issuable_todo_updated(target, current_user)
GraphqlTriggers.issuable_todo_updated(target)
end
# Resolves all todos related to target for all users
@ -237,7 +237,7 @@ class TodoService
todo.update(state: resolution, resolved_by_action: resolved_by_action)
GraphqlTriggers.issuable_todo_updated(todo.target, current_user)
GraphqlTriggers.issuable_todo_updated(todo.target)
current_user.update_todos_count_cache
end

View File

@ -5,13 +5,51 @@ module WorkItems
module Widgets
class Milestone < Base
def before_create
# set milestone, e.g.
# target_work_item.milestone_id = work_item.milestone_id
# todo system notes for removed/not copied milestone?
return unless target_work_item.get_widget(:milestone)
return if work_item.milestone_id.blank?
target_work_item.milestone = matching_milestone
end
def post_move_cleanup
# do it
work_item.update_column(:milestone_id, nil)
end
private
def matching_milestone
params = { project_ids: target_work_item.project&.id, group_ids: ancestors }
milestone = by_id(params)
return milestone if milestone.present?
by_title(params)
end
def by_id(params)
return if work_item.milestone_id.blank?
find_milestone(params.merge(ids: work_item.milestone_id))
end
def by_title(params)
return if work_item.milestone&.title.blank?
find_milestone(params.merge(title: work_item.milestone&.title))
end
def find_milestone(params)
milestones = MilestonesFinder.new(params).execute
milestones.first
end
def ancestors
case target_work_item.namespace
when Group
target_work_item.namespace.self_and_ancestors
else
target_work_item.project.ancestors
end
end
end
end

View File

@ -1,9 +1,9 @@
- class_name = local_assigns.fetch(:class_name, '')
.branch-commit.gl-text-sm.gl-text-gray-500.gl-truncate{ class: class_name }
.branch-commit.gl-text-sm.gl-text-subtle.gl-truncate{ class: class_name }
= link_to commit.short_id, project_commit_path(project, commit.id), class: "commit-sha"
&middot;
%span
= link_to_markdown commit.title, project_commit_path(project, commit.id), class: "commit-row-message !gl-text-gray-500"
= link_to_markdown commit.title, project_commit_path(project, commit.id), class: "commit-row-message !gl-text-subtle"
&middot;
%span.gl-text-secondary= time_ago_with_tooltip(commit.committed_date)
%span.gl-text-subtle= time_ago_with_tooltip(commit.committed_date)

View File

@ -89,7 +89,7 @@
= updated_tooltip
= render_if_exists 'shared/projects/actions', project: project
.project-cell.project-controls{ class: "#{css_class} !gl-hidden sm:!gl-table-cell", data: { testid: 'project_controls'} }
.project-cell.project-controls.gl-text-subtle{ class: "#{css_class} !gl-hidden sm:!gl-table-cell", data: { testid: 'project_controls'} }
.controls.gl-flex.gl-items-center.gl-mb-2.gl-gap-4{ class: "#{css_controls_class} !gl-pr-0 !gl-justify-end" }
- if show_pipeline_status_icon && last_pipeline.present?
- pipeline_path = pipelines_project_commit_path(project.pipeline_status.project, project.pipeline_status.sha, ref: project.pipeline_status.ref)

View File

@ -255,6 +255,15 @@
:weight: 1
:idempotent: true
:tags: []
- :name: cronjob:ci_catalog_resources_cleanup_last_usages
:worker_name: Ci::Catalog::Resources::CleanupLastUsagesWorker
:feature_category: :pipeline_composition
:has_external_dependencies: false
:urgency: :low
:resource_boundary: :unknown
:weight: 1
:idempotent: true
:tags: []
- :name: cronjob:ci_catalog_resources_process_sync_events
:worker_name: Ci::Catalog::Resources::ProcessSyncEventsWorker
:feature_category: :pipeline_composition

View File

@ -7,6 +7,10 @@ class AutoMergeProcessWorker # rubocop:disable Scalability/IdempotentWorker
sidekiq_options retry: 3
# Avoid _simultaneous execution_ of this job for the same MR,
# but reschedule the second job just in case the first fails.
deduplicate :until_executed, if_deduplicated: :reschedule_once
queue_namespace :auto_merge
feature_category :continuous_delivery
worker_resource_boundary :cpu

View File

@ -0,0 +1,24 @@
# frozen_string_literal: true
module Ci
module Catalog
module Resources
class CleanupLastUsagesWorker
include ApplicationWorker
include CronjobQueue # rubocop: disable Scalability/CronWorkerContext -- Periodic processing is required
feature_category :pipeline_composition
data_consistency :sticky
urgency :low
idempotent!
def perform
Ci::Catalog::Resources::Components::LastUsage.older_than_30_days.each_batch(of: 1000) do |batch|
batch.delete_all
end
end
end
end
end
end

View File

@ -6,4 +6,4 @@ rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/500069
milestone: '17.6'
type: beta
group: group::provision
default_enabled: false
default_enabled: true

View File

@ -1,9 +0,0 @@
---
name: realtime_issuable_todo
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/449018
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/147456
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/495542
milestone: '17.5'
group: group::code review
type: beta
default_enabled: false

View File

@ -1,9 +0,0 @@
---
name: use_load_balancing_session_map
feature_issue_url: https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/3834
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/168642
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/496505
milestone: '17.6'
group: group::scalability
type: gitlab_com_derisk
default_enabled: false

View File

@ -0,0 +1,9 @@
---
name: find_and_replace
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/481892
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/164251
rollout_issue_url:
milestone: '17.6'
group: group::knowledge
type: wip
default_enabled: false

View File

@ -720,6 +720,9 @@ Settings.cron_jobs['performance_bar_stats']['job_class'] = 'GitlabPerformanceBar
Settings.cron_jobs['ci_catalog_resources_aggregate_last30_day_usage_worker'] ||= {}
Settings.cron_jobs['ci_catalog_resources_aggregate_last30_day_usage_worker']['cron'] ||= '*/4 * * * *'
Settings.cron_jobs['ci_catalog_resources_aggregate_last30_day_usage_worker']['job_class'] = 'Ci::Catalog::Resources::AggregateLast30DayUsageWorker'
Settings.cron_jobs['ci_catalog_resources_cleanup_last_usages_worker'] ||= {}
Settings.cron_jobs['ci_catalog_resources_cleanup_last_usages_worker']['cron'] ||= '0 0 * * *'
Settings.cron_jobs['ci_catalog_resources_cleanup_last_usages_worker']['job_class'] = 'Ci::Catalog::Resources::CleanupLastUsagesWorker'
Settings.cron_jobs['ci_click_house_finished_pipelines_sync_worker'] ||= {}
Settings.cron_jobs['ci_click_house_finished_pipelines_sync_worker']['cron'] ||= '*/4 * * * *'
Settings.cron_jobs['ci_click_house_finished_pipelines_sync_worker']['args'] ||= [1]

View File

@ -0,0 +1,8 @@
---
migration_job_name: BackfillCiRunnersPartitionedTable
description: This migration copies runners from ci_runners to the new partitioned ci_runners_e59bb2812d table
feature_category: runner
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/166520
milestone: '17.6'
queued_migration_version: 20241023144448
finalized_by: # version of the migration that finalized this BBM

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class AddLastUsedDateIndexInLastUsage < Gitlab::Database::Migration[2.2]
disable_ddl_transaction!
milestone '17.6'
INDEX_NAME = 'index_last_usages_on_last_used_date'
def up
add_concurrent_index :catalog_resource_component_last_usages, :last_used_date, name: INDEX_NAME
end
def down
remove_concurrent_index :catalog_resource_component_last_usages, :last_used_date, name: INDEX_NAME
end
end

View File

@ -0,0 +1,13 @@
# frozen_string_literal: true
class RemoveFaultyAsyncIndexDefinitions2 < Gitlab::Database::Migration[2.2]
milestone '17.6'
def up
unprepare_async_index_by_name 'gitlab_partitions_dynamic.security_findings_126', 'index_ee8a554af9'
end
def down
# no-op
end
end

Some files were not shown because too many files have changed in this diff Show More