Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2025-05-12 18:07:30 +00:00
parent a5c6357e1e
commit d275f7ab34
52 changed files with 258 additions and 215 deletions

View File

@ -2342,6 +2342,12 @@ Gitlab/BoundedContexts:
- 'ee/app/graphql/resolvers/security_orchestration/policy_violations_resolver.rb' - 'ee/app/graphql/resolvers/security_orchestration/policy_violations_resolver.rb'
- 'ee/app/graphql/resolvers/security_orchestration/scan_execution_policy_resolver.rb' - 'ee/app/graphql/resolvers/security_orchestration/scan_execution_policy_resolver.rb'
- 'ee/app/graphql/resolvers/security_orchestration/scan_result_policy_resolver.rb' - 'ee/app/graphql/resolvers/security_orchestration/scan_result_policy_resolver.rb'
- 'ee/app/graphql/types/security_orchestration/scan_execution_policy_attributes_type.rb'
- 'ee/app/graphql/types/security_orchestration/approval_policy_attributes_type.rb'
- 'ee/app/graphql/types/security_orchestration/pipeline_execution_scheduled_policy_attributes_type.rb'
- 'ee/app/graphql/types/security_orchestration/pipeline_execution_policy_attributes_type.rb'
- 'ee/app/graphql/types/security_orchestration/pipeline_execution_policy_scheduled_fields_type.rb'
- 'ee/app/graphql/types/security/vulnerability_management_policy_attributes_type.rb'
- 'ee/app/graphql/resolvers/security_orchestration/security_policy_project_suggestions_resolver.rb' - 'ee/app/graphql/resolvers/security_orchestration/security_policy_project_suggestions_resolver.rb'
- 'ee/app/graphql/resolvers/security_report/finding_reports_comparer_resolver.rb' - 'ee/app/graphql/resolvers/security_report/finding_reports_comparer_resolver.rb'
- 'ee/app/graphql/resolvers/security_report/finding_resolver.rb' - 'ee/app/graphql/resolvers/security_report/finding_resolver.rb'

View File

@ -715,7 +715,7 @@ gem 'parslet', '~> 1.8', feature_category: :shared
gem 'ipynbdiff', path: 'gems/ipynbdiff', require: 'ipynb_diff', feature_category: :shared gem 'ipynbdiff', path: 'gems/ipynbdiff', require: 'ipynb_diff', feature_category: :shared
gem 'ed25519', '~> 1.3.0', feature_category: :shared gem 'ed25519', '~> 1.4.0', feature_category: :shared
# Error Tracking OpenAPI client # Error Tracking OpenAPI client
# See https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/development/rake_tasks.md#update-openapi-client-for-error-tracking-feature # See https://gitlab.com/gitlab-org/gitlab/-/blob/master/doc/development/rake_tasks.md#update-openapi-client-for-error-tracking-feature

View File

@ -137,8 +137,8 @@
{"name":"dry-types","version":"1.7.1","platform":"ruby","checksum":"12165841145a18dd22151f143707b90c8093f71e5ae06ee0f2301f5321f8cdb8"}, {"name":"dry-types","version":"1.7.1","platform":"ruby","checksum":"12165841145a18dd22151f143707b90c8093f71e5ae06ee0f2301f5321f8cdb8"},
{"name":"dumb_delegator","version":"1.0.0","platform":"ruby","checksum":"ff5e411816d2d8ad8e260b269e712ae3839dddb0f9f8e18d3b1a3fe08f6d2e94"}, {"name":"dumb_delegator","version":"1.0.0","platform":"ruby","checksum":"ff5e411816d2d8ad8e260b269e712ae3839dddb0f9f8e18d3b1a3fe08f6d2e94"},
{"name":"duo_api","version":"1.4.0","platform":"ruby","checksum":"06a6b406184e6e4b14af7389ac3990e667fb8509a1feba7de3af2f78d98c0877"}, {"name":"duo_api","version":"1.4.0","platform":"ruby","checksum":"06a6b406184e6e4b14af7389ac3990e667fb8509a1feba7de3af2f78d98c0877"},
{"name":"ed25519","version":"1.3.0","platform":"java","checksum":"8e5d2f8a5325c7a463d61d1a48406ce54074c610f3dccd889e6532c9527a3894"}, {"name":"ed25519","version":"1.4.0","platform":"java","checksum":"10410f0538bc35eead91fa82bc4be48c0a3593573cd7f03d941ce1c0b7129bfd"},
{"name":"ed25519","version":"1.3.0","platform":"ruby","checksum":"514a5584f84d39daac568a17ec93a4e7261e140c52c562ed8c382c18456e627d"}, {"name":"ed25519","version":"1.4.0","platform":"ruby","checksum":"16e97f5198689a154247169f3453ef4cfd3f7a47481fde0ae33206cdfdcac506"},
{"name":"elasticsearch","version":"7.17.11","platform":"ruby","checksum":"ed080f085d939f21d07f424ebcea95326e4bdb5f770a8f33aac699374f2ffc86"}, {"name":"elasticsearch","version":"7.17.11","platform":"ruby","checksum":"ed080f085d939f21d07f424ebcea95326e4bdb5f770a8f33aac699374f2ffc86"},
{"name":"elasticsearch-api","version":"7.17.11","platform":"ruby","checksum":"fed8f7b64493c97cf3984a33396a798204b54b8e1b01c5b6c099fa3fd4209107"}, {"name":"elasticsearch-api","version":"7.17.11","platform":"ruby","checksum":"fed8f7b64493c97cf3984a33396a798204b54b8e1b01c5b6c099fa3fd4209107"},
{"name":"elasticsearch-model","version":"7.2.1","platform":"ruby","checksum":"8b5c4b57664bb29f4854fa39603b5ccecfbf9b22fee87bcd16917321dae6a20b"}, {"name":"elasticsearch-model","version":"7.2.1","platform":"ruby","checksum":"8b5c4b57664bb29f4854fa39603b5ccecfbf9b22fee87bcd16917321dae6a20b"},

View File

@ -586,7 +586,7 @@ GEM
zeitwerk (~> 2.6) zeitwerk (~> 2.6)
dumb_delegator (1.0.0) dumb_delegator (1.0.0)
duo_api (1.4.0) duo_api (1.4.0)
ed25519 (1.3.0) ed25519 (1.4.0)
elasticsearch (7.17.11) elasticsearch (7.17.11)
elasticsearch-api (= 7.17.11) elasticsearch-api (= 7.17.11)
elasticsearch-transport (= 7.17.11) elasticsearch-transport (= 7.17.11)
@ -2130,7 +2130,7 @@ DEPENDENCIES
doorkeeper-openid_connect (~> 1.8.10) doorkeeper-openid_connect (~> 1.8.10)
drb (~> 2.2) drb (~> 2.2)
duo_api (~> 1.3) duo_api (~> 1.3)
ed25519 (~> 1.3.0) ed25519 (~> 1.4.0)
elasticsearch-api (= 7.17.11) elasticsearch-api (= 7.17.11)
elasticsearch-model (~> 7.2) elasticsearch-model (~> 7.2)
elasticsearch-rails (~> 7.2) elasticsearch-rails (~> 7.2)

View File

@ -137,8 +137,8 @@
{"name":"dry-types","version":"1.7.1","platform":"ruby","checksum":"12165841145a18dd22151f143707b90c8093f71e5ae06ee0f2301f5321f8cdb8"}, {"name":"dry-types","version":"1.7.1","platform":"ruby","checksum":"12165841145a18dd22151f143707b90c8093f71e5ae06ee0f2301f5321f8cdb8"},
{"name":"dumb_delegator","version":"1.0.0","platform":"ruby","checksum":"ff5e411816d2d8ad8e260b269e712ae3839dddb0f9f8e18d3b1a3fe08f6d2e94"}, {"name":"dumb_delegator","version":"1.0.0","platform":"ruby","checksum":"ff5e411816d2d8ad8e260b269e712ae3839dddb0f9f8e18d3b1a3fe08f6d2e94"},
{"name":"duo_api","version":"1.4.0","platform":"ruby","checksum":"06a6b406184e6e4b14af7389ac3990e667fb8509a1feba7de3af2f78d98c0877"}, {"name":"duo_api","version":"1.4.0","platform":"ruby","checksum":"06a6b406184e6e4b14af7389ac3990e667fb8509a1feba7de3af2f78d98c0877"},
{"name":"ed25519","version":"1.3.0","platform":"java","checksum":"8e5d2f8a5325c7a463d61d1a48406ce54074c610f3dccd889e6532c9527a3894"}, {"name":"ed25519","version":"1.4.0","platform":"java","checksum":"10410f0538bc35eead91fa82bc4be48c0a3593573cd7f03d941ce1c0b7129bfd"},
{"name":"ed25519","version":"1.3.0","platform":"ruby","checksum":"514a5584f84d39daac568a17ec93a4e7261e140c52c562ed8c382c18456e627d"}, {"name":"ed25519","version":"1.4.0","platform":"ruby","checksum":"16e97f5198689a154247169f3453ef4cfd3f7a47481fde0ae33206cdfdcac506"},
{"name":"elasticsearch","version":"7.17.11","platform":"ruby","checksum":"ed080f085d939f21d07f424ebcea95326e4bdb5f770a8f33aac699374f2ffc86"}, {"name":"elasticsearch","version":"7.17.11","platform":"ruby","checksum":"ed080f085d939f21d07f424ebcea95326e4bdb5f770a8f33aac699374f2ffc86"},
{"name":"elasticsearch-api","version":"7.17.11","platform":"ruby","checksum":"fed8f7b64493c97cf3984a33396a798204b54b8e1b01c5b6c099fa3fd4209107"}, {"name":"elasticsearch-api","version":"7.17.11","platform":"ruby","checksum":"fed8f7b64493c97cf3984a33396a798204b54b8e1b01c5b6c099fa3fd4209107"},
{"name":"elasticsearch-model","version":"7.2.1","platform":"ruby","checksum":"8b5c4b57664bb29f4854fa39603b5ccecfbf9b22fee87bcd16917321dae6a20b"}, {"name":"elasticsearch-model","version":"7.2.1","platform":"ruby","checksum":"8b5c4b57664bb29f4854fa39603b5ccecfbf9b22fee87bcd16917321dae6a20b"},

View File

@ -586,7 +586,7 @@ GEM
zeitwerk (~> 2.6) zeitwerk (~> 2.6)
dumb_delegator (1.0.0) dumb_delegator (1.0.0)
duo_api (1.4.0) duo_api (1.4.0)
ed25519 (1.3.0) ed25519 (1.4.0)
elasticsearch (7.17.11) elasticsearch (7.17.11)
elasticsearch-api (= 7.17.11) elasticsearch-api (= 7.17.11)
elasticsearch-transport (= 7.17.11) elasticsearch-transport (= 7.17.11)
@ -2130,7 +2130,7 @@ DEPENDENCIES
doorkeeper-openid_connect (~> 1.8.10) doorkeeper-openid_connect (~> 1.8.10)
drb (~> 2.2) drb (~> 2.2)
duo_api (~> 1.3) duo_api (~> 1.3)
ed25519 (~> 1.3.0) ed25519 (~> 1.4.0)
elasticsearch-api (= 7.17.11) elasticsearch-api (= 7.17.11)
elasticsearch-model (~> 7.2) elasticsearch-model (~> 7.2)
elasticsearch-rails (~> 7.2) elasticsearch-rails (~> 7.2)

View File

@ -116,7 +116,7 @@ export default {
<help-popover v-if="isFinished" icon="information-o" data-testid="reimport-info-icon"> <help-popover v-if="isFinished" icon="information-o" data-testid="reimport-info-icon">
{{ {{
s__('BulkImport|Re-import creates a new group. It does not sync with the existing group.') s__('BulkImport|Re-import creates a new group and does not sync with the existing group.')
}} }}
</help-popover> </help-popover>

View File

@ -836,7 +836,7 @@ export default {
<span v-if="showImportProjectsWarning" class="gl-shrink-0"> <span v-if="showImportProjectsWarning" class="gl-shrink-0">
<gl-icon <gl-icon
v-gl-tooltip v-gl-tooltip
:title="s__('BulkImport|Some groups will be imported without projects.')" :title="s__('BulkImport|Some groups are imported without projects.')"
name="warning" name="warning"
variant="warning" variant="warning"
data-testid="import-projects-warning" data-testid="import-projects-warning"
@ -889,7 +889,7 @@ export default {
<span data-testid="new-path-col"> <span data-testid="new-path-col">
<span class="gl-mr-2">{{ data.label }}</span <span class="gl-mr-2">{{ data.label }}</span
><gl-icon ><gl-icon
v-gl-tooltip="s__('BulkImport|Path of the new group.')" v-gl-tooltip="s__('BulkImport|Path of the new group')"
name="information" name="information"
:size="12" :size="12"
/> />

View File

@ -1,7 +1,7 @@
import { __, s__ } from '~/locale'; import { __, s__ } from '~/locale';
export const i18n = { export const i18n = {
ERROR_TARGET_NAMESPACE_REQUIRED: s__('BulkImport|Please select a parent group.'), ERROR_TARGET_NAMESPACE_REQUIRED: s__('BulkImport|Select a parent group.'),
ERROR_INVALID_FORMAT: s__( ERROR_INVALID_FORMAT: s__(
'GroupSettings|Please choose a group URL with no special characters or spaces.', 'GroupSettings|Please choose a group URL with no special characters or spaces.',
), ),
@ -13,7 +13,7 @@ export const i18n = {
ERROR_IMPORT: s__('BulkImport|Importing the group failed.'), ERROR_IMPORT: s__('BulkImport|Importing the group failed.'),
ERROR_IMPORT_COMPLETED: s__('BulkImport|Enter another name to re-import.'), ERROR_IMPORT_COMPLETED: s__('BulkImport|Enter another name to re-import.'),
ERROR_TOO_MANY_REQUESTS: s__( ERROR_TOO_MANY_REQUESTS: s__(
'Bulkmport|Over six imports in one minute were attempted. Wait at least one minute and try again.', 'Bulkmport|More than six imports were attempted in one minute. Try again after a minute.',
), ),
NO_GROUPS_FOUND: s__('BulkImport|No groups found'), NO_GROUPS_FOUND: s__('BulkImport|No groups found'),

View File

@ -16,7 +16,7 @@ export class StatusPoller {
}, },
errorCallback: () => errorCallback: () =>
createAlert({ createAlert({
message: s__('BulkImport|Update of import statuses with realtime changes failed'), message: s__('BulkImport|Unable to update import statuses with real-time changes'),
}), }),
}); });

View File

@ -277,7 +277,7 @@ export default {
<gl-empty-state <gl-empty-state
v-else-if="!hasHistoryItems" v-else-if="!hasHistoryItems"
:title="s__('BulkImport|No history is available')" :title="s__('BulkImport|No history is available')"
:description="s__('BulkImport|Your imported groups and projects will appear here.')" :description="s__('BulkImport|Your imported groups and projects appear here.')"
/> />
<template v-else> <template v-else>
<gl-table-lite :fields="$options.fields" :items="historyItems" class="gl-w-full"> <gl-table-lite :fields="$options.fields" :items="historyItems" class="gl-w-full">

View File

@ -136,7 +136,7 @@ export default {
<gl-empty-state <gl-empty-state
v-else-if="!hasHistoryItems" v-else-if="!hasHistoryItems"
:title="s__('BulkImport|No history is available')" :title="s__('BulkImport|No history is available')"
:description="s__('BulkImport|Your imported projects will appear here.')" :description="s__('BulkImport|Your imported projects appear here.')"
/> />
<template v-else> <template v-else>
<gl-table :fields="$options.fields" :items="historyItems" class="gl-w-full"> <gl-table :fields="$options.fields" :items="historyItems" class="gl-w-full">
@ -152,7 +152,9 @@ export default {
</gl-link> </gl-link>
<span v-else>{{ item.import_url }}</span> <span v-else>{{ item.import_url }}</span>
</template> </template>
<span v-else>{{ s__('BulkImport|Template / File-based import / Direct transfer') }}</span> <span v-else>{{
s__('BulkImport|Template, file-based import, or direct transfer')
}}</span>
</template> </template>
<template #cell(destination)="{ item }"> <template #cell(destination)="{ item }">
<gl-link :href="item.http_url_to_repo"> <gl-link :href="item.http_url_to_repo">

View File

@ -261,6 +261,14 @@ export default {
this.canAdminProtectedBranches && (this.allowEditSquashSetting || this.isAllBranchesRule) this.canAdminProtectedBranches && (this.allowEditSquashSetting || this.isAllBranchesRule)
); );
}, },
showDeleteRuleBtn() {
return (
this.glFeatures.editBranchRules &&
this.branchRule &&
this.canAdminProtectedBranches &&
!this.isAllBranchesRule
);
},
}, },
methods: { methods: {
...mapActions(['setRulesFilter', 'fetchRules']), ...mapActions(['setRulesFilter', 'fetchRules']),
@ -444,7 +452,7 @@ export default {
<page-heading :heading="$options.i18n.pageTitle"> <page-heading :heading="$options.i18n.pageTitle">
<template #actions> <template #actions>
<gl-button <gl-button
v-if="glFeatures.editBranchRules && branchRule && canAdminProtectedBranches" v-if="showDeleteRuleBtn"
v-gl-modal="$options.deleteModalId" v-gl-modal="$options.deleteModalId"
data-testid="delete-rule-button" data-testid="delete-rule-button"
category="secondary" category="secondary"

View File

@ -23,7 +23,6 @@ import projectShortPathQuery from './queries/project_short_path.query.graphql';
import refsQuery from './queries/ref.query.graphql'; import refsQuery from './queries/ref.query.graphql';
import createRouter from './router'; import createRouter from './router';
import { updateFormAction } from './utils/dom'; import { updateFormAction } from './utils/dom';
import { setTitle } from './utils/title';
import { generateHistoryUrl } from './utils/url_utility'; import { generateHistoryUrl } from './utils/url_utility';
import { generateRefDestinationPath } from './utils/ref_switcher_utils'; import { generateRefDestinationPath } from './utils/ref_switcher_utils';
import initHeaderApp from './init_header_app'; import initHeaderApp from './init_header_app';
@ -47,7 +46,7 @@ export default function setupVueRepositoryList() {
explainCodeAvailable, explainCodeAvailable,
targetBranch, targetBranch,
} = dataset; } = dataset;
const router = createRouter(projectPath, escapedRef); const router = createRouter(projectPath, escapedRef, fullName);
initFileTreeBrowser(router); initFileTreeBrowser(router);
apolloProvider.clients.defaultClient.cache.writeQuery({ apolloProvider.clients.defaultClient.cache.writeQuery({
@ -231,10 +230,6 @@ export default function setupVueRepositoryList() {
initRefSwitcher(); initRefSwitcher();
initForkInfo(); initForkInfo();
router.afterEach(({ params: { path } }) => {
setTitle(path, ref, fullName);
});
const breadcrumbEl = document.getElementById('js-repo-breadcrumb'); const breadcrumbEl = document.getElementById('js-repo-breadcrumb');
if (breadcrumbEl) { if (breadcrumbEl) {

View File

@ -2,6 +2,7 @@ import { escapeRegExp } from 'lodash';
import Vue from 'vue'; import Vue from 'vue';
import VueRouter from 'vue-router'; import VueRouter from 'vue-router';
import { joinPaths, webIDEUrl } from '~/lib/utils/url_utility'; import { joinPaths, webIDEUrl } from '~/lib/utils/url_utility';
import { setTitle } from './utils/title';
import BlobPage from './pages/blob.vue'; import BlobPage from './pages/blob.vue';
import IndexPage from './pages/index.vue'; import IndexPage from './pages/index.vue';
import TreePage from './pages/tree.vue'; import TreePage from './pages/tree.vue';
@ -19,7 +20,7 @@ const normalizePathParam = (pathParam) => {
return pathParam?.replace(/^\//, '') || '/'; return pathParam?.replace(/^\//, '') || '/';
}; };
export default function createRouter(base, baseRef) { export default function createRouter(base, baseRef, fullName) {
const treePathRoute = { const treePathRoute = {
component: TreePage, component: TreePage,
props: (route) => ({ props: (route) => ({
@ -81,8 +82,9 @@ export default function createRouter(base, baseRef) {
], ],
}); });
router.afterEach((to) => { router.afterEach(({ params: { path }, name }) => {
const needsClosingSlash = !to.name.includes('blobPath'); const needsClosingSlash = !name.includes('blobPath');
const normalizedPath = normalizePathParam(path);
window.gl.webIDEPath = webIDEUrl( window.gl.webIDEPath = webIDEUrl(
joinPaths( joinPaths(
'/', '/',
@ -90,10 +92,12 @@ export default function createRouter(base, baseRef) {
'edit', 'edit',
decodeURI(baseRef), decodeURI(baseRef),
'-', '-',
normalizePathParam(to.params.path), normalizedPath,
needsClosingSlash && '/', needsClosingSlash && '/',
), ),
); );
setTitle(normalizedPath, baseRef, fullName);
}); });
return router; return router;

View File

@ -38,11 +38,6 @@ export default {
}, },
}, },
}, },
data() {
return {
selected: this.value,
};
},
computed: { computed: {
statusDropdownOptions() { statusDropdownOptions() {
return this.$options.STATUS_LIST.map((status) => ({ return this.$options.STATUS_LIST.map((status) => ({
@ -71,14 +66,14 @@ export default {
<template> <template>
<gl-collapsible-listbox <gl-collapsible-listbox
ref="dropdown" ref="dropdown"
v-model="selected" :selected="value"
:header-text="headerText" :header-text="headerText"
block block
:toggle-text="currentStatusLabel" :toggle-text="currentStatusLabel"
:items="statusDropdownOptions" :items="statusDropdownOptions"
toggle-class="dropdown-menu-toggle gl-mb-2" toggle-class="dropdown-menu-toggle gl-mb-2"
data-testid="escalation-status-dropdown" data-testid="escalation-status-dropdown"
@select="$emit('input', selected)" @select="$emit('input', $event)"
> >
<template #list-item="{ item }"> <template #list-item="{ item }">
<span class="gl-block">{{ item.text }}</span> <span class="gl-block">{{ item.text }}</span>

View File

@ -7,7 +7,6 @@ import TestCaseDetails from '~/ci/pipeline_details/test_reports/test_case_detail
import MrWidget from '~/vue_merge_request_widget/components/widget/widget.vue'; import MrWidget from '~/vue_merge_request_widget/components/widget/widget.vue';
import MrWidgetRow from '~/vue_merge_request_widget/components/widget/widget_content_row.vue'; import MrWidgetRow from '~/vue_merge_request_widget/components/widget/widget_content_row.vue';
import { DynamicScroller, DynamicScrollerItem } from 'vendor/vue-virtual-scroller'; import { DynamicScroller, DynamicScrollerItem } from 'vendor/vue-virtual-scroller';
import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { EXTENSION_ICONS } from '../../constants'; import { EXTENSION_ICONS } from '../../constants';
import { import {
summaryTextBuilder, summaryTextBuilder,
@ -30,7 +29,6 @@ export default {
DynamicScrollerItem, DynamicScrollerItem,
TestCaseDetails, TestCaseDetails,
}, },
mixins: [glFeatureFlagMixin()],
i18n, i18n,
props: { props: {
mr: { mr: {
@ -46,10 +44,8 @@ export default {
}; };
}, },
computed: { computed: {
// show in-progress test report immediately when `mr_show_reports_immediately`
// feature flag is enabled and the current pipeline is active.
shouldShowLoading() { shouldShowLoading() {
if (this.mr.isPipelineActive && this.glFeatures.mrShowReportsImmediately) { if (this.mr.isPipelineActive) {
return 'collapsed'; return 'collapsed';
} }

View File

@ -574,7 +574,7 @@ export default {
return this.fullPath || null; return this.fullPath || null;
}, },
handleKeydown(e) { handleKeydown(e) {
if (isMetaEnterKeyPair(e)) { if (isMetaEnterKeyPair(e) && !this.loading) {
this.createWorkItem(); this.createWorkItem();
} }
}, },

View File

@ -42,7 +42,6 @@ class Projects::MergeRequestsController < Projects::MergeRequests::ApplicationCo
push_frontend_feature_flag(:mr_experience_survey, project) push_frontend_feature_flag(:mr_experience_survey, project)
push_frontend_feature_flag(:mr_pipelines_graphql, project) push_frontend_feature_flag(:mr_pipelines_graphql, project)
push_frontend_feature_flag(:notifications_todos_buttons, current_user) push_frontend_feature_flag(:notifications_todos_buttons, current_user)
push_frontend_feature_flag(:mr_show_reports_immediately, project)
push_frontend_feature_flag(:improved_review_experience, current_user) push_frontend_feature_flag(:improved_review_experience, current_user)
end end

View File

@ -246,21 +246,21 @@ class BulkImports::Entity < ApplicationRecord
end end
def validate_parent_is_a_group def validate_parent_is_a_group
errors.add(:parent, s_('BulkImport|must be a group')) unless parent.group_entity? errors.add(:parent, s_('BulkImport|must be a group.')) unless parent.group_entity?
end end
def validate_imported_entity_type def validate_imported_entity_type
if group.present? && project_entity? if group.present? && project_entity?
errors.add( errors.add(
:group, :group,
s_('BulkImport|expected an associated Project but has an associated Group') s_('BulkImport|must belong to a project.')
) )
end end
if project.present? && group_entity? if project.present? && group_entity?
errors.add( errors.add(
:project, :project,
s_('BulkImport|expected an associated Group but has an associated Project') s_('BulkImport|must belong to a group.')
) )
end end
end end
@ -287,9 +287,9 @@ class BulkImports::Entity < ApplicationRecord
errors.add( errors.add(
:source_full_path, :source_full_path,
s_('BulkImport|must have a relative path structure with no HTTP ' \ s_('BulkImport|must have a relative path with no HTTP ' \
'protocol characters, or leading or trailing forward slashes. Path segments must not start or ' \ 'protocol characters or leading or trailing forward slashes. Path segments must not start or ' \
'end with a special character, and must not contain consecutive special characters') 'end with a special character or contain consecutive special characters.')
) )
end end

View File

@ -1166,19 +1166,11 @@ module Ci
end end
def complete_and_has_reports?(reports_scope) def complete_and_has_reports?(reports_scope)
if Feature.enabled?(:mr_show_reports_immediately, project, type: :development) complete? && has_reports?(reports_scope)
latest_report_builds(reports_scope).exists?
else
complete? && has_reports?(reports_scope)
end
end end
def complete_or_manual_and_has_reports?(reports_scope) def complete_or_manual_and_has_reports?(reports_scope)
if Feature.enabled?(:mr_show_reports_immediately, project, type: :development) complete_or_manual? && has_reports?(reports_scope)
latest_report_builds(reports_scope).exists?
else
complete_or_manual? && has_reports?(reports_scope)
end
end end
def has_coverage_reports? def has_coverage_reports?

View File

@ -1957,7 +1957,7 @@ class MergeRequest < ApplicationRecord
end end
def has_test_reports? def has_test_reports?
diff_head_pipeline&.complete_and_has_reports?(Ci::JobArtifact.of_report_type(:test)) diff_head_pipeline&.has_reports?(Ci::JobArtifact.of_report_type(:test))
end end
# rubocop: disable Metrics/AbcSize -- Despite being long, this method is quite straightforward. Splitting it in smaller chunks would likely reduce readability. # rubocop: disable Metrics/AbcSize -- Despite being long, this method is quite straightforward. Splitting it in smaller chunks would likely reduce readability.

View File

@ -43,6 +43,7 @@
= render 'groups/settings/two_factor_auth', f: f, group: @group = render 'groups/settings/two_factor_auth', f: f, group: @group
= render 'groups/settings/membership', f: f, group: @group = render 'groups/settings/membership', f: f, group: @group
= render_if_exists 'groups/settings/remove_dormant_members', f: f, group: @group = render_if_exists 'groups/settings/remove_dormant_members', f: f, group: @group
= render_if_exists 'groups/settings/disable_invite_members', f: f, group: @group
= render_if_exists 'groups/settings/extensions_marketplace', f: f, group: @group = render_if_exists 'groups/settings/extensions_marketplace', f: f, group: @group
= render_if_exists 'groups/settings/pages_access_control', f: f, group: @group = render_if_exists 'groups/settings/pages_access_control', f: f, group: @group

View File

@ -11,10 +11,10 @@
- if @has_errors || @skipped_count > 0 - if @has_errors || @skipped_count > 0
%p{ style: text_style } %p{ style: text_style }
= safe_format(s_('BulkImport|Items assigned to placeholder users have been reassigned to users in %{strong_open}%{group}%{strong_close}.'), strong_tag_pair, group: @group.name) = safe_format(s_('BulkImport|Items assigned to placeholder users have been reassigned to users in %{strong_open}%{group}%{strong_close} according to the uploaded CSV file.'), strong_tag_pair, group: @group.name)
- else - else
%p{ style: text_style } %p{ style: text_style }
= safe_format(s_('BulkImport|All items assigned to placeholder users have been reassigned to users in %{strong_open}%{group}%{strong_close}.'), strong_tag_pair, group: @group.name) = safe_format(s_('BulkImport|All items assigned to placeholder users have been reassigned to users in %{strong_open}%{group}%{strong_close} according to the uploaded CSV file.'), strong_tag_pair, group: @group.name)
%ul %ul
%li %li

View File

@ -1,9 +1,9 @@
<%= @title %> <%= @title %>
<% if @has_errors || @skipped_count > 0%> <% if @has_errors || @skipped_count > 0%>
<%= safe_format(s_('BulkImport|Items assigned to placeholder users have been reassigned to users in %{strong_open}%{group}%{strong_close}.'), strong_open: '', strong_close: '', group: @group.name) %> <%= safe_format(s_('BulkImport|Items assigned to placeholder users have been reassigned to users in %{strong_open}%{group}%{strong_close} according to the uploaded CSV file.'), strong_open: '', strong_close: '', group: @group.name) %>
<% else %> <% else %>
<%= safe_format(s_('BulkImport|All items assigned to placeholder users have been reassigned to users in %{strong_open}%{group}%{strong_close}.'), strong_open: '', strong_close: '', group: @group.name) %> <%= safe_format(s_('BulkImport|All items assigned to placeholder users have been reassigned to users in %{strong_open}%{group}%{strong_close} according to the uploaded CSV file.'), strong_open: '', strong_close: '', group: @group.name) %>
<% end %> <% end %>
- <%= safe_format(ns_('BulkImport|%{count} placeholder user has been matched to a user.', 'BulkImport|%{count} placeholder users have been matched to users.', @success_count), count: @success_count) %> - <%= safe_format(ns_('BulkImport|%{count} placeholder user has been matched to a user.', 'BulkImport|%{count} placeholder users have been matched to users.', @success_count), count: @success_count) %>

View File

@ -1,8 +0,0 @@
---
name: mr_show_reports_immediately
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/76612
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/367027
milestone: '15.2'
type: development
group: group::pipeline execution
default_enabled: false

View File

@ -2,6 +2,7 @@
stage: Plan stage: Plan
group: Optimize group: Optimize
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
description: Retrieve project and group DORA metrics with the REST API.
title: DevOps Research and Assessment (DORA) metrics API title: DevOps Research and Assessment (DORA) metrics API
--- ---

View File

@ -332,6 +332,8 @@ a branch pipeline instead.
It's also possible that your [`workflow: rules`](yaml/_index.md#workflow) configuration It's also possible that your [`workflow: rules`](yaml/_index.md#workflow) configuration
blocked the pipeline, or allowed the wrong pipeline type. blocked the pipeline, or allowed the wrong pipeline type.
If you are using pull mirroring, you can check the [troubleshooting entry for pull mirroring pipelines](../user/project/repository/mirror/troubleshooting.md#pull-mirroring-is-not-triggering-pipelines).
### Pipeline with many jobs fails to start ### Pipeline with many jobs fails to start
A Pipeline that has more jobs than the instance's defined [CI/CD limits](../administration/settings/continuous_integration.md#set-cicd-limits) A Pipeline that has more jobs than the instance's defined [CI/CD limits](../administration/settings/continuous_integration.md#set-cicd-limits)

View File

@ -15,7 +15,7 @@ ClickHouse blog also has a very good post, [Super charging your ClickHouse queri
It is possible to use [`EXPLAIN`](https://clickhouse.com/docs/en/sql-reference/statements/explain) statements with queries to get visible steps of the query pipeline. Note the different [types](https://clickhouse.com/docs/en/sql-reference/statements/explain#explain-types) of `EXPLAIN`. It is possible to use [`EXPLAIN`](https://clickhouse.com/docs/en/sql-reference/statements/explain) statements with queries to get visible steps of the query pipeline. Note the different [types](https://clickhouse.com/docs/en/sql-reference/statements/explain#explain-types) of `EXPLAIN`.
Also, to get detailed query execution pipeline, you can toggle the logs level to `trace` via `clickhouse-client` and then execute the query. Also, to get detailed query execution pipeline, you can set the logs level to `trace` with `clickhouse-client` and then execute the query.
For example: For example:

View File

@ -2,6 +2,7 @@
stage: Plan stage: Plan
group: Optimize group: Optimize
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
description: Gain insights into DevOps performance and identify opportunities for workflow improvements.
title: DevOps Research and Assessment (DORA) metrics title: DevOps Research and Assessment (DORA) metrics
--- ---

View File

@ -2,6 +2,7 @@
stage: Plan stage: Plan
group: Optimize group: Optimize
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
description: View DevSecOps metrics (such as DORA and vulnerabilities) across your organization on a customizable dashboard.
title: Value Streams Dashboard title: Value Streams Dashboard
--- ---
@ -241,13 +242,15 @@ To retrieve aggregated usage counts in the group, use the [GraphQL API](../../ap
## View the Value Streams Dashboard ## View the Value Streams Dashboard
### For groups
Prerequisites: Prerequisites:
- You must have at least the Reporter role for the group. - You must have at least the Reporter role for the group or project.
- Overview background aggregation for Value Streams Dashboards must be enabled. - [Overview background aggregation](#enable-or-disable-overview-background-aggregation) must be enabled.
- To view the contributor count metric in the comparison panel, you must [set up ClickHouse](../../integration/clickhouse.md). - To view the contributor count metric in the comparison panel, you must [set up ClickHouse](../../integration/clickhouse.md).
- To track deployment to production, the group or project must have an environment in the [production deployment tier](../../ci/environments/_index.md#deployment-tier-of-environments).
- To measure the cycle time, [issues must be crosslinked from commit messages](../../user/project/issues/crosslinking_issues.md#from-commit-messages).
### For groups
To view the Value Streams Dashboard for a group: To view the Value Streams Dashboard for a group:
@ -272,12 +275,6 @@ To view the Value Streams Dashboard for a group:
{{< /history >}} {{< /history >}}
Prerequisites:
- You must have at least the Reporter role for the project.
- Overview background aggregation for Value Streams Dashboards must be enabled.
- To view the contributor count metric in the comparison panel, you must [set up ClickHouse](../../integration/clickhouse.md).
To view the Value Streams Dashboard as an analytics dashboard for a project: To view the Value Streams Dashboard as an analytics dashboard for a project:
1. On the left sidebar, select **Search or go to** and find your project. 1. On the left sidebar, select **Search or go to** and find your project.

View File

@ -24,10 +24,11 @@ Before you can install the agent in your cluster, you need:
- [Digital Ocean](https://docs.digitalocean.com/products/kubernetes/getting-started/quickstart/) - [Digital Ocean](https://docs.digitalocean.com/products/kubernetes/getting-started/quickstart/)
- [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine/docs/deploy-app-cluster) - [Google Kubernetes Engine (GKE)](https://cloud.google.com/kubernetes-engine/docs/deploy-app-cluster)
- You should use [Infrastructure as Code techniques](../../../infrastructure/iac/_index.md) for managing infrastructure resources at scale. - You should use [Infrastructure as Code techniques](../../../infrastructure/iac/_index.md) for managing infrastructure resources at scale.
- On GitLab Self-Managed, a GitLab administrator must set up the - Access to an agent server:
[agent server](../../../../administration/clusters/kas.md). - On GitLab.com, the agent server is available at `wss://kas.gitlab.com`.
Then it is available by default at `wss://gitlab.example.com/-/kubernetes-agent/`. - On GitLab Self-Managed, a GitLab administrator must set up the [agent server](../../../../administration/clusters/kas.md).
On GitLab.com, the agent server is available at `wss://kas.gitlab.com`. Then it is available by default at `wss://gitlab.example.com/-/kubernetes-agent/`.
- On GitLab Dedicated, the agent server is available at `wss://kas.<instance-domain>`, for example `wss://kas.example.gitlab-dedicated.com`. If you use a [custom hostname](../../../../administration/dedicated/configure_instance/network_security.md#bring-your-own-domain-byod) for your GitLab Dedicated instance, you can also choose a custom hostname for the KAS service.
## Bootstrap the agent with Flux support (recommended) ## Bootstrap the agent with Flux support (recommended)

View File

@ -250,6 +250,30 @@ To disable group mentions:
1. Select **Group mentions are disabled**. 1. Select **Group mentions are disabled**.
1. Select **Save changes**. 1. Select **Save changes**.
## Disable user invitations to a group
{{< history >}}
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/189898) in GitLab 18.0. Disabled by default.
{{< /history >}}
You can disable the ability for users to invite new members to sub-groups or projects in a top-level
group. This also stops group Owners from sending invites. You must disable this setting before you
can invite users again.
Prerequisites:
- You must have the Owner role for the group.
To disable user invitations:
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Settings > General**.
1. Expand the **Permissions and group features** section.
1. Select **Disable Group/Project members invitation**.
1. Select **Save changes**.
## Export members as CSV ## Export members as CSV
{{< details >}} {{< details >}}

View File

@ -17,7 +17,7 @@ module API
resource :experiments do resource :experiments do
desc 'Fetch experiment by experiment_id' do desc 'Fetch experiment by experiment_id' do
success Entities::Ml::Mlflow::GetExperiment success Entities::Ml::Mlflow::GetExperiment
detail 'https://www.mlflow.org/docs/1.28.0/rest-api.html#get-experiment' detail 'https://www.mlflow.org/docs/2.19.0/rest-api.html#get-experiment'
end end
params do params do
optional :experiment_id, type: String, default: '', desc: 'Experiment ID, in reference to the project' optional :experiment_id, type: String, default: '', desc: 'Experiment ID, in reference to the project'
@ -28,7 +28,7 @@ module API
desc 'Fetch experiment by experiment_name' do desc 'Fetch experiment by experiment_name' do
success Entities::Ml::Mlflow::GetExperiment success Entities::Ml::Mlflow::GetExperiment
detail 'https://www.mlflow.org/docs/1.28.0/rest-api.html#get-experiment-by-name' detail 'https://www.mlflow.org/docs/2.19.0/rest-api.html#get-experiment-by-name'
end end
params do params do
optional :experiment_name, type: String, default: '', desc: 'Experiment name' optional :experiment_name, type: String, default: '', desc: 'Experiment name'
@ -39,7 +39,7 @@ module API
desc 'List experiments' do desc 'List experiments' do
success Entities::Ml::Mlflow::ListExperiment success Entities::Ml::Mlflow::ListExperiment
detail 'https://www.mlflow.org/docs/latest/rest-api.html#list-experiments' detail 'https://www.mlflow.org/docs/2.19.0/rest-api.html#search-experiments'
end end
get 'list', urgency: :low do get 'list', urgency: :low do
response = { experiments: experiment_repository.all } response = { experiments: experiment_repository.all }
@ -49,7 +49,7 @@ module API
desc 'Search experiments' do desc 'Search experiments' do
success Entities::Ml::Mlflow::ListExperiment success Entities::Ml::Mlflow::ListExperiment
detail 'https://www.mlflow.org/docs/latest/rest-api.html#list-experiments' detail 'https://www.mlflow.org/docs/2.19.0/rest-api.html#search-experiments'
end end
params do params do
optional :max_results, optional :max_results,
@ -85,7 +85,7 @@ module API
desc 'Create experiment' do desc 'Create experiment' do
success Entities::Ml::Mlflow::NewExperiment success Entities::Ml::Mlflow::NewExperiment
detail 'https://www.mlflow.org/docs/1.28.0/rest-api.html#create-experiment' detail 'https://www.mlflow.org/docs/2.19.0/rest-api.html#create-experiment'
end end
params do params do
requires :name, type: String, desc: 'Experiment name' requires :name, type: String, desc: 'Experiment name'
@ -102,7 +102,7 @@ module API
desc 'Sets a tag for an experiment.' do desc 'Sets a tag for an experiment.' do
summary 'Sets a tag for an experiment. ' summary 'Sets a tag for an experiment. '
detail 'https://www.mlflow.org/docs/1.28.0/rest-api.html#set-experiment-tag' detail 'https://www.mlflow.org/docs/2.19.0/rest-api.html#set-experiment-tag'
end end
params do params do
requires :experiment_id, type: String, desc: 'ID of the experiment.' requires :experiment_id, type: String, desc: 'ID of the experiment.'
@ -118,7 +118,7 @@ module API
desc 'Delete an experiment.' do desc 'Delete an experiment.' do
summary 'Delete an experiment.' summary 'Delete an experiment.'
detail 'https://mlflow.org/docs/latest/rest-api.html#delete-experiment' detail 'https://mlflow.org/docs/2.19.0/rest-api.html#delete-experiment'
end end
params do params do
requires :experiment_id, type: String, desc: 'ID of the experiment.' requires :experiment_id, type: String, desc: 'ID of the experiment.'

View File

@ -16,7 +16,7 @@ module API
resource 'model-versions' do resource 'model-versions' do
desc 'Creates a Model Version.' do desc 'Creates a Model Version.' do
success Entities::Ml::Mlflow::ModelVersion success Entities::Ml::Mlflow::ModelVersion
detail 'MLFlow Model Versions map to GitLab Model Versions. https://mlflow.org/docs/2.6.0/rest-api.html#create-modelversion' detail 'MLFlow Model Versions map to GitLab Model Versions. https://mlflow.org/docs/2.19.0/rest-api.html#create-modelversion'
end end
route_setting :api, write: true route_setting :api, write: true
route_setting :model_registry, write: true route_setting :model_registry, write: true
@ -50,7 +50,7 @@ module API
desc 'Fetch the download URI for the model version.' do desc 'Fetch the download URI for the model version.' do
success Entities::Ml::Mlflow::GetDownload success Entities::Ml::Mlflow::GetDownload
detail 'Returns version in MLflow format "mlflow-artifacts:<version>" https://mlflow.org/docs/2.6.0/rest-api.html#get-download-uri-for-modelversion-artifacts' detail 'Returns version in MLflow format "mlflow-artifacts:<version>" https://mlflow.org/docs/2.19.0/rest-api.html#get-download-uri-for-modelversion-artifacts'
end end
params do params do
requires :name, type: String, desc: 'Model version name' requires :name, type: String, desc: 'Model version name'
@ -62,7 +62,7 @@ module API
desc 'Fetch model version by name and version' do desc 'Fetch model version by name and version' do
success Entities::Ml::Mlflow::ModelVersion success Entities::Ml::Mlflow::ModelVersion
detail 'https://mlflow.org/docs/2.6.0/rest-api.html#get-modelversion' detail 'https://mlflow.org/docs/2.19.0/rest-api.html#get-modelversion'
end end
params do params do
requires :name, type: String, desc: 'Model version name' requires :name, type: String, desc: 'Model version name'
@ -75,7 +75,7 @@ module API
desc 'Updates a Model Version.' do desc 'Updates a Model Version.' do
success Entities::Ml::Mlflow::ModelVersion success Entities::Ml::Mlflow::ModelVersion
detail 'https://mlflow.org/docs/2.6.0/rest-api.html#update-modelversion' detail 'https://mlflow.org/docs/2.19.0/rest-api.html#update-modelversion'
end end
route_setting :api, write: true route_setting :api, write: true
route_setting :model_registry, write: true route_setting :model_registry, write: true

View File

@ -19,7 +19,7 @@ module API
resource 'registered-models' do resource 'registered-models' do
desc 'Creates a Registered Model.' do desc 'Creates a Registered Model.' do
success Entities::Ml::Mlflow::RegisteredModel success Entities::Ml::Mlflow::RegisteredModel
detail 'MLFlow Registered Models map to GitLab Models. https://mlflow.org/docs/2.6.0/rest-api.html#create-registeredmodel' detail 'MLFlow Registered Models map to GitLab Models. https://mlflow.org/docs/2.19.0/rest-api.html#create-registeredmodel'
end end
route_setting :api, write: true route_setting :api, write: true
route_setting :model_registry, write: true route_setting :model_registry, write: true
@ -50,7 +50,7 @@ module API
desc 'Fetch a Registered Model by Name' do desc 'Fetch a Registered Model by Name' do
success Entities::Ml::Mlflow::RegisteredModel success Entities::Ml::Mlflow::RegisteredModel
detail 'https://www.mlflow.org/docs/1.28.0/rest-api.html#get-registeredmodel' detail 'https://www.mlflow.org/docs/2.19.0/rest-api.html#get-registeredmodel'
end end
params do params do
# The name param is actually required, however it is listed as optional here # The name param is actually required, however it is listed as optional here
@ -65,7 +65,7 @@ module API
desc 'Update a Registered Model by Name' do desc 'Update a Registered Model by Name' do
success Entities::Ml::Mlflow::RegisteredModel success Entities::Ml::Mlflow::RegisteredModel
detail 'https://mlflow.org/docs/2.6.0/rest-api.html#update-registeredmodel' detail 'https://mlflow.org/docs/2.19.0/rest-api.html#update-registeredmodel'
end end
route_setting :api, write: true route_setting :api, write: true
route_setting :model_registry, write: true route_setting :model_registry, write: true
@ -86,7 +86,7 @@ module API
desc 'Fetch the latest Model Version for the given Registered Model Name' do desc 'Fetch the latest Model Version for the given Registered Model Name' do
success Entities::Ml::Mlflow::ModelVersion success Entities::Ml::Mlflow::ModelVersion
detail 'https://mlflow.org/docs/2.6.0/rest-api.html#get-latest-modelversions' detail 'https://mlflow.org/docs/2.19.0/rest-api.html#get-latest-modelversions'
end end
params do params do
# The name param is actually required, however it is listed as optional here # The name param is actually required, however it is listed as optional here
@ -103,7 +103,7 @@ module API
desc 'Delete a Registered Model by Name' do desc 'Delete a Registered Model by Name' do
success Entities::Ml::Mlflow::RegisteredModel success Entities::Ml::Mlflow::RegisteredModel
detail 'https://mlflow.org/docs/2.6.0/rest-api.html#delete-registeredmodel' detail 'https://mlflow.org/docs/2.19.0/rest-api.html#delete-registeredmodel'
end end
route_setting :api, write: true route_setting :api, write: true
route_setting :model_registry, write: true route_setting :model_registry, write: true
@ -129,7 +129,7 @@ module API
desc 'Search Registered Models within a project' do desc 'Search Registered Models within a project' do
success Entities::Ml::Mlflow::RegisteredModel success Entities::Ml::Mlflow::RegisteredModel
detail 'https://mlflow.org/docs/2.6.0/rest-api.html#search-registeredmodels' detail 'https://mlflow.org/docs/2.19.0/rest-api.html#search-registeredmodels'
end end
params do params do
optional :filter, optional :filter,
@ -177,7 +177,7 @@ module API
desc: 'The alias of the model, e.g. the Semantic Version `1.0.0`' desc: 'The alias of the model, e.g. the Semantic Version `1.0.0`'
end end
desc 'Gets a Model Version by alias' do desc 'Gets a Model Version by alias' do
detail 'https://mlflow.org/docs/latest/rest-api.html#get-model-version-by-alias' detail 'https://mlflow.org/docs/2.19.0/rest-api.html#get-model-version-by-alias'
end end
get 'alias', urgency: :low do get 'alias', urgency: :low do
present find_model_version(user_project, params[:name], params[:alias]), present find_model_version(user_project, params[:name], params[:alias]),

View File

@ -19,7 +19,7 @@ module API
resource :runs do resource :runs do
desc 'Creates a Run.' do desc 'Creates a Run.' do
success Entities::Ml::Mlflow::Run success Entities::Ml::Mlflow::Run
detail 'MLFlow Runs map to GitLab Candidates. https://www.mlflow.org/docs/1.28.0/rest-api.html#create-run' detail 'MLFlow Runs map to GitLab Candidates. https://www.mlflow.org/docs/2.19.0/rest-api.html#create-run'
end end
params do params do
requires :experiment_id, type: Integer, requires :experiment_id, type: Integer,
@ -50,7 +50,7 @@ module API
desc 'Searches runs/candidates within a project' do desc 'Searches runs/candidates within a project' do
success Entities::Ml::Mlflow::Run success Entities::Ml::Mlflow::Run
detail 'https://www.mlflow.org/docs/1.28.0/rest-api.html#search-runs' \ detail 'https://www.mlflow.org/docs/2.19.0/rest-api.html#search-runs' \
'experiment_ids supports only a single experiment ID.' \ 'experiment_ids supports only a single experiment ID.' \
'Introduced in GitLab 16.4' 'Introduced in GitLab 16.4'
end end
@ -90,7 +90,7 @@ module API
desc 'Updates a Run.' do desc 'Updates a Run.' do
success Entities::Ml::Mlflow::UpdateRun success Entities::Ml::Mlflow::UpdateRun
detail 'MLFlow Runs map to GitLab Candidates. https://www.mlflow.org/docs/1.28.0/rest-api.html#update-run' detail 'MLFlow Runs map to GitLab Candidates. https://www.mlflow.org/docs/2.19.0/rest-api.html#update-run'
end end
params do params do
requires :run_id, type: String, desc: 'UUID of the candidate.' requires :run_id, type: String, desc: 'UUID of the candidate.'
@ -137,7 +137,7 @@ module API
'used in an ETL pipeline. A param can be logged only once for a run, duplicate will be .' \ 'used in an ETL pipeline. A param can be logged only once for a run, duplicate will be .' \
'ignored' 'ignored'
detail 'https://www.mlflow.org/docs/1.28.0/rest-api.html#log-param' detail 'https://www.mlflow.org/docs/2.19.0/rest-api.html#log-param'
end end
params do params do
requires :run_id, type: String, desc: 'UUID of the run.' requires :run_id, type: String, desc: 'UUID of the run.'
@ -153,7 +153,7 @@ module API
desc 'Sets a tag for a run.' do desc 'Sets a tag for a run.' do
summary 'Sets a tag for a run. ' summary 'Sets a tag for a run. '
detail 'https://www.mlflow.org/docs/1.28.0/rest-api.html#set-tag' detail 'https://www.mlflow.org/docs/2.19.0/rest-api.html#set-tag'
end end
params do params do
requires :run_id, type: String, desc: 'UUID of the run.' requires :run_id, type: String, desc: 'UUID of the run.'
@ -170,7 +170,7 @@ module API
summary 'Log a batch of metrics and params for a run. Validation errors will block the entire batch, ' \ summary 'Log a batch of metrics and params for a run. Validation errors will block the entire batch, ' \
'duplicate errors will be ignored.' 'duplicate errors will be ignored.'
detail 'https://www.mlflow.org/docs/1.28.0/rest-api.html#log-param' detail 'https://www.mlflow.org/docs/2.19.0/rest-api.html#log-param'
end end
params do params do
requires :run_id, type: String, desc: 'UUID of the run.' requires :run_id, type: String, desc: 'UUID of the run.'
@ -196,7 +196,7 @@ module API
desc 'Delete a run.' do desc 'Delete a run.' do
summary 'Delete a run.' summary 'Delete a run.'
detail 'https://mlflow.org/docs/2.16.0/rest-api.html#delete-run' detail 'https://mlflow.org/docs/2.19.0/rest-api.html#delete-run'
end end
params do params do
requires :run_id, type: String, desc: 'UUID of the run.' requires :run_id, type: String, desc: 'UUID of the run.'

View File

@ -3,7 +3,7 @@
module BulkImports module BulkImports
class Error < StandardError class Error < StandardError
def self.unsupported_gitlab_version def self.unsupported_gitlab_version
self.new(format(s_("BulkImport|Unsupported GitLab version. Minimum supported version is '%{version}'."), self.new(format(s_("BulkImport|Unsupported GitLab version. The minimum supported version is '%{version}'."),
version: BulkImport::MIN_MAJOR_VERSION)) version: BulkImport::MIN_MAJOR_VERSION))
end end

View File

@ -11312,7 +11312,7 @@ msgstr ""
msgid "BulkImport|A CSV file with a list of placeholder reassignment errors is attached to this email." msgid "BulkImport|A CSV file with a list of placeholder reassignment errors is attached to this email."
msgstr "" msgstr ""
msgid "BulkImport|All items assigned to placeholder users have been reassigned to users in %{strong_open}%{group}%{strong_close}." msgid "BulkImport|All items assigned to placeholder users have been reassigned to users in %{strong_open}%{group}%{strong_close} according to the uploaded CSV file."
msgstr "" msgstr ""
msgid "BulkImport|Be aware of %{visibilityLinkStart}visibility rules%{visibilityLinkEnd} and %{placeholdersLinkStart}placeholder user limits%{placeholdersLinkEnd} when importing groups." msgid "BulkImport|Be aware of %{visibilityLinkStart}visibility rules%{visibilityLinkEnd} and %{placeholdersLinkStart}placeholder user limits%{placeholdersLinkEnd} when importing groups."
@ -11381,7 +11381,7 @@ msgstr ""
msgid "BulkImport|Invalid source URL. Enter only the base URL of the source GitLab instance." msgid "BulkImport|Invalid source URL. Enter only the base URL of the source GitLab instance."
msgstr "" msgstr ""
msgid "BulkImport|Items assigned to placeholder users have been reassigned to users in %{strong_open}%{group}%{strong_close}." msgid "BulkImport|Items assigned to placeholder users have been reassigned to users in %{strong_open}%{group}%{strong_close} according to the uploaded CSV file."
msgstr "" msgstr ""
msgid "BulkImport|Items that failed to be imported for %{id}" msgid "BulkImport|Items that failed to be imported for %{id}"
@ -11423,7 +11423,7 @@ msgstr ""
msgid "BulkImport|Only groups you have the %{role} role for are listed for import." msgid "BulkImport|Only groups you have the %{role} role for are listed for import."
msgstr "" msgstr ""
msgid "BulkImport|Path of the new group." msgid "BulkImport|Path of the new group"
msgstr "" msgstr ""
msgid "BulkImport|Placeholder reassignments completed successfully" msgid "BulkImport|Placeholder reassignments completed successfully"
@ -11432,18 +11432,18 @@ msgstr ""
msgid "BulkImport|Placeholder reassignments completed with errors" msgid "BulkImport|Placeholder reassignments completed with errors"
msgstr "" msgstr ""
msgid "BulkImport|Please select a parent group."
msgstr ""
msgid "BulkImport|Project import history" msgid "BulkImport|Project import history"
msgstr "" msgstr ""
msgid "BulkImport|Re-import creates a new group. It does not sync with the existing group." msgid "BulkImport|Re-import creates a new group and does not sync with the existing group."
msgstr "" msgstr ""
msgid "BulkImport|Review results" msgid "BulkImport|Review results"
msgstr "" msgstr ""
msgid "BulkImport|Select a parent group."
msgstr ""
msgid "BulkImport|Select parent group" msgid "BulkImport|Select parent group"
msgstr "" msgstr ""
@ -11462,7 +11462,7 @@ msgstr ""
msgid "BulkImport|Showing %{start}-%{end} of %{total} that you own matching filter \"%{filter}\" from %{link}" msgid "BulkImport|Showing %{start}-%{end} of %{total} that you own matching filter \"%{filter}\" from %{link}"
msgstr "" msgstr ""
msgid "BulkImport|Some groups will be imported without projects." msgid "BulkImport|Some groups are imported without projects."
msgstr "" msgstr ""
msgid "BulkImport|Source" msgid "BulkImport|Source"
@ -11471,7 +11471,7 @@ msgstr ""
msgid "BulkImport|Source group" msgid "BulkImport|Source group"
msgstr "" msgstr ""
msgid "BulkImport|Template / File-based import / Direct transfer" msgid "BulkImport|Template, file-based import, or direct transfer"
msgstr "" msgstr ""
msgid "BulkImport|The following items are not migrated: %{bullets} To include these items, ask the administrator of %{host} to upgrade GitLab." msgid "BulkImport|The following items are not migrated: %{bullets} To include these items, ask the administrator of %{host} to upgrade GitLab."
@ -11492,10 +11492,10 @@ msgstr ""
msgid "BulkImport|Unable to process the CSV file for %{strong_open}%{group}%{strong_close} to reassign placeholders. Try to upload the file again." msgid "BulkImport|Unable to process the CSV file for %{strong_open}%{group}%{strong_close} to reassign placeholders. Try to upload the file again."
msgstr "" msgstr ""
msgid "BulkImport|Unsupported GitLab version. Minimum supported version is '%{version}'." msgid "BulkImport|Unable to update import statuses with real-time changes"
msgstr "" msgstr ""
msgid "BulkImport|Update of import statuses with realtime changes failed" msgid "BulkImport|Unsupported GitLab version. The minimum supported version is '%{version}'."
msgstr "" msgstr ""
msgid "BulkImport|View import history" msgid "BulkImport|View import history"
@ -11510,25 +11510,25 @@ msgstr ""
msgid "BulkImport|You cannot import projects with this group. To import projects, reconfigure the source GitLab instance or group. %{linkStart}Learn more.%{linkEnd}" msgid "BulkImport|You cannot import projects with this group. To import projects, reconfigure the source GitLab instance or group. %{linkStart}Learn more.%{linkEnd}"
msgstr "" msgstr ""
msgid "BulkImport|Your imported groups and projects will appear here." msgid "BulkImport|Your imported groups and projects appear here."
msgstr "" msgstr ""
msgid "BulkImport|Your imported projects will appear here." msgid "BulkImport|Your imported projects appear here."
msgstr "" msgstr ""
msgid "BulkImport|expected an associated Group but has an associated Project" msgid "BulkImport|must be a group."
msgstr "" msgstr ""
msgid "BulkImport|expected an associated Project but has an associated Group" msgid "BulkImport|must belong to a group."
msgstr "" msgstr ""
msgid "BulkImport|must be a group" msgid "BulkImport|must belong to a project."
msgstr "" msgstr ""
msgid "BulkImport|must have a relative path structure with no HTTP protocol characters, or leading or trailing forward slashes. Path segments must not start or end with a special character, and must not contain consecutive special characters" msgid "BulkImport|must have a relative path with no HTTP protocol characters or leading or trailing forward slashes. Path segments must not start or end with a special character or contain consecutive special characters."
msgstr "" msgstr ""
msgid "Bulkmport|Over six imports in one minute were attempted. Wait at least one minute and try again." msgid "Bulkmport|More than six imports were attempted in one minute. Try again after a minute."
msgstr "" msgstr ""
msgid "Bullet list" msgid "Bullet list"
@ -23502,6 +23502,9 @@ msgstr ""
msgid "Each project can also have an issue tracker and a wiki." msgid "Each project can also have an issue tracker and a wiki."
msgstr "" msgstr ""
msgid "Eclipse"
msgstr ""
msgid "Edit" msgid "Edit"
msgstr "" msgstr ""
@ -27866,6 +27869,12 @@ msgstr ""
msgid "Get started!" msgid "Get started!"
msgstr "" msgstr ""
msgid "GetStarted|Download the extension to access GitLab features and GitLab Duo AI capabilities to handle everyday tasks."
msgstr ""
msgid "GetStarted|Use GitLab Duo locally"
msgstr ""
msgid "GiB" msgid "GiB"
msgstr "" msgstr ""
@ -27998,6 +28007,9 @@ msgstr ""
msgid "GitLab Billing Team." msgid "GitLab Billing Team."
msgstr "" msgstr ""
msgid "GitLab CLI"
msgstr ""
msgid "GitLab Community Edition" msgid "GitLab Community Edition"
msgstr "" msgstr ""
@ -30078,6 +30090,9 @@ msgstr ""
msgid "GroupSettings|Disable personal access tokens for enterprise users" msgid "GroupSettings|Disable personal access tokens for enterprise users"
msgstr "" msgstr ""
msgid "GroupSettings|Disable user invitations to groups and projects within %{group}"
msgstr ""
msgid "GroupSettings|Emails are not encrypted. Concerned administrators may want to disable diff previews." msgid "GroupSettings|Emails are not encrypted. Concerned administrators may want to disable diff previews."
msgstr "" msgstr ""
@ -30147,6 +30162,9 @@ msgstr ""
msgid "GroupSettings|If enabled, individual user accounts will be able to use only issued SSH certificates for Git access. It doesn't apply to service accounts, deploy keys, and other types of internal accounts." msgid "GroupSettings|If enabled, individual user accounts will be able to use only issued SSH certificates for Git access. It doesn't apply to service accounts, deploy keys, and other types of internal accounts."
msgstr "" msgstr ""
msgid "GroupSettings|If enabled, users can no longer invite members to groups or projects in the top-level group. %{learn_more_link}."
msgstr ""
msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories." msgid "GroupSettings|If not specified at the group or instance level, the default is %{default_initial_branch_name}. Does not affect existing repositories."
msgstr "" msgstr ""
@ -33969,6 +33987,9 @@ msgstr ""
msgid "Japanese language support using" msgid "Japanese language support using"
msgstr "" msgstr ""
msgid "Jetbrains"
msgstr ""
msgid "Jira display name" msgid "Jira display name"
msgstr "" msgstr ""
@ -39996,6 +40017,9 @@ msgstr ""
msgid "Neither gitlab_instance_uid or sub found on Cloud Connector token" msgid "Neither gitlab_instance_uid or sub found on Cloud Connector token"
msgstr "" msgstr ""
msgid "Neovim"
msgstr ""
msgid "Network" msgid "Network"
msgstr "" msgstr ""
@ -65605,6 +65629,9 @@ msgid_plural "Users in subscription"
msgstr[0] "" msgstr[0] ""
msgstr[1] "" msgstr[1] ""
msgid "User invitation restrictions"
msgstr ""
msgid "User is blocked" msgid "User is blocked"
msgstr "" msgstr ""
@ -66339,6 +66366,9 @@ msgstr ""
msgid "Using required encryption strategy when encrypted field is missing!" msgid "Using required encryption strategy when encrypted field is missing!"
msgstr "" msgstr ""
msgid "VS Code"
msgstr ""
msgid "VS Code Extension Marketplace" msgid "VS Code Extension Marketplace"
msgstr "" msgstr ""
@ -67046,6 +67076,9 @@ msgstr ""
msgid "Visit new homepage" msgid "Visit new homepage"
msgstr "" msgstr ""
msgid "Visual Studio"
msgstr ""
msgid "Visual Studio Code" msgid "Visual Studio Code"
msgstr "" msgstr ""
@ -70287,6 +70320,9 @@ msgstr ""
msgid "You cannot impersonate an internal user" msgid "You cannot impersonate an internal user"
msgstr "" msgstr ""
msgid "You cannot invite a new member to %{strong_start}%{group_name}%{strong_end} since its disabled by %{actor}."
msgstr ""
msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute." msgid "You cannot play this scheduled pipeline at the moment. Please wait a minute."
msgstr "" msgstr ""

View File

@ -120,7 +120,11 @@ module QA
it( it(
'successfully imports project wiki', 'successfully imports project wiki',
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347567' testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/347567',
quarantine: {
issue: 'https://gitlab.com/gitlab-org/gitlab/-/issues/541472',
type: :investigating
}
) do ) do
expect_project_import_finished_successfully expect_project_import_finished_successfully

View File

@ -135,7 +135,6 @@ spec/frontend/pages/shared/wikis/components/delete_wiki_modal_spec.js
spec/frontend/performance_bar/index_spec.js spec/frontend/performance_bar/index_spec.js
spec/frontend/pipeline_wizard/components/step_spec.js spec/frontend/pipeline_wizard/components/step_spec.js
spec/frontend/projects/commit/components/form_modal_spec.js spec/frontend/projects/commit/components/form_modal_spec.js
spec/frontend/projects/commits/components/author_select_spec.js
spec/frontend/projects/report_abuse/components/report_abuse_dropdown_item_spec.js spec/frontend/projects/report_abuse/components/report_abuse_dropdown_item_spec.js
spec/frontend/projects/settings/components/branch_rule_modal_spec.js spec/frontend/projects/settings/components/branch_rule_modal_spec.js
spec/frontend/projects/settings/topics/components/topics_token_selector_spec.js spec/frontend/projects/settings/topics/components/topics_token_selector_spec.js
@ -149,7 +148,6 @@ spec/frontend/set_status_modal/user_profile_set_status_wrapper_spec.js
spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js
spec/frontend/sidebar/components/confidential/confidentiality_dropdown_spec.js spec/frontend/sidebar/components/confidential/confidentiality_dropdown_spec.js
spec/frontend/sidebar/components/confidential/sidebar_confidentiality_widget_spec.js spec/frontend/sidebar/components/confidential/sidebar_confidentiality_widget_spec.js
spec/frontend/sidebar/components/incidents/escalation_status_spec.js
spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view_spec.js spec/frontend/sidebar/components/labels/labels_select_vue/dropdown_contents_labels_view_spec.js
spec/frontend/sidebar/components/milestone/milestone_dropdown_spec.js spec/frontend/sidebar/components/milestone/milestone_dropdown_spec.js
spec/frontend/sidebar/components/subscriptions/subscriptions_dropdown_spec.js spec/frontend/sidebar/components/subscriptions/subscriptions_dropdown_spec.js

View File

@ -240,13 +240,13 @@ describe('import table', () => {
}); });
it('does not validate by default', () => { it('does not validate by default', () => {
expect(wrapper.find('tbody tr').text()).not.toContain('Please select a parent group.'); expect(wrapper.find('tbody tr').text()).not.toContain('Select a parent group.');
}); });
it('triggers validations when import button is clicked', async () => { it('triggers validations when import button is clicked', async () => {
await findRowImportDropdownAtIndex(0).trigger('click'); await findRowImportDropdownAtIndex(0).trigger('click');
expect(wrapper.find('tbody tr').text()).toContain('Please select a parent group.'); expect(wrapper.find('tbody tr').text()).toContain('Select a parent group.');
}); });
it('is valid when root namespace is selected', async () => { it('is valid when root namespace is selected', async () => {
@ -255,7 +255,7 @@ describe('import table', () => {
}); });
await findRowImportDropdownAtIndex(0).trigger('click'); await findRowImportDropdownAtIndex(0).trigger('click');
expect(wrapper.find('tbody tr').text()).not.toContain('Please select a parent group.'); expect(wrapper.find('tbody tr').text()).not.toContain('Select a parent group.');
expect(findFirstImportTargetNamespaceText()).toBe('No parent'); expect(findFirstImportTargetNamespaceText()).toBe('No parent');
}); });
@ -265,7 +265,7 @@ describe('import table', () => {
}); });
await findRowImportDropdownAtIndex(0).trigger('click'); await findRowImportDropdownAtIndex(0).trigger('click');
expect(wrapper.find('tbody tr').text()).not.toContain('Please select a parent group.'); expect(wrapper.find('tbody tr').text()).not.toContain('Select a parent group.');
expect(findFirstImportTargetNamespaceText()).toBe('gitlab-org'); expect(findFirstImportTargetNamespaceText()).toBe('gitlab-org');
}); });
}); });
@ -453,7 +453,7 @@ describe('import table', () => {
expect(createAlert).not.toHaveBeenCalled(); expect(createAlert).not.toHaveBeenCalled();
expect(wrapper.find('tbody tr').text()).toContain( expect(wrapper.find('tbody tr').text()).toContain(
'Over six imports in one minute were attempted. Wait at least one minute and try again.', 'More than six imports were attempted in one minute. Try again after a minute.',
); );
}); });
@ -745,7 +745,7 @@ describe('import table', () => {
expect(findImportProjectsWarning().props('name')).toBe('warning'); expect(findImportProjectsWarning().props('name')).toBe('warning');
expect(findImportProjectsWarning().attributes('title')).toBe( expect(findImportProjectsWarning().attributes('title')).toBe(
'Some groups will be imported without projects.', 'Some groups are imported without projects.',
); );
}); });
@ -867,7 +867,7 @@ describe('import table', () => {
const tooltip = getBinding(icon.element, 'gl-tooltip'); const tooltip = getBinding(icon.element, 'gl-tooltip');
expect(tooltip).toBeDefined(); expect(tooltip).toBeDefined();
expect(tooltip.value).toBe('Path of the new group.'); expect(tooltip.value).toBe('Path of the new group');
}); });
describe('re-import', () => { describe('re-import', () => {

View File

@ -151,6 +151,8 @@ describe('Author Select', () => {
describe('listbox list', () => { describe('listbox list', () => {
beforeEach(() => { beforeEach(() => {
store.state.commitsAuthors = authors; store.state.commitsAuthors = authors;
createComponent();
}); });
it('has a "Any Author" as the first list item', () => { it('has a "Any Author" as the first list item', () => {

View File

@ -511,6 +511,13 @@ describe('View branch rules', () => {
}); });
}); });
it('does not render delete rule button when target is All branches', () => {
jest.spyOn(util, 'getParameterByName').mockReturnValueOnce('All branches');
createComponent();
expect(findDeleteRuleButton().exists()).toBe(false);
});
it('renders delete rule button', () => { it('renders delete rule button', () => {
expect(findDeleteRuleButton().text()).toBe('Delete rule'); expect(findDeleteRuleButton().text()).toBe('Delete rule');
}); });

View File

@ -3,6 +3,9 @@ import IndexPage from '~/repository/pages/index.vue';
import TreePage from '~/repository/pages/tree.vue'; import TreePage from '~/repository/pages/tree.vue';
import createRouter from '~/repository/router'; import createRouter from '~/repository/router';
import { getMatchedComponents } from '~/lib/utils/vue3compat/vue_router'; import { getMatchedComponents } from '~/lib/utils/vue3compat/vue_router';
import { setTitle } from '~/repository/utils/title';
jest.mock('~/repository/utils/title');
describe('Repository router spec', () => { describe('Repository router spec', () => {
it.each` it.each`
@ -51,4 +54,24 @@ describe('Repository router spec', () => {
}, },
); );
}); });
describe('Setting page title', () => {
const projectPath = 'group/project';
const projectName = 'Project Name';
const branch = 'main';
it.each`
path | expectedPath
${'/'} | ${'/'}
${'/tree/main'} | ${'/'}
${'/-/tree/main/app/assets'} | ${'app/assets'}
${'/-/blob/main/file.md'} | ${'file.md'}
`('sets title with correct parameters for $path', async ({ path, expectedPath }) => {
const router = createRouter(projectPath, branch, projectName);
await router.push(path);
expect(setTitle).toHaveBeenCalledWith(expectedPath, branch, projectName);
});
});
}); });

View File

@ -51,7 +51,7 @@ describe('Test report extension', () => {
const findAllExtensionListItems = () => wrapper.findAllByTestId('extension-list-item'); const findAllExtensionListItems = () => wrapper.findAllByTestId('extension-list-item');
const findModal = () => wrapper.findComponent(TestCaseDetails); const findModal = () => wrapper.findComponent(TestCaseDetails);
const createComponent = (props, flagState = false) => { const createComponent = (props) => {
wrapper = mountExtended(testReportExtension, { wrapper = mountExtended(testReportExtension, {
propsData: { propsData: {
mr: { mr: {
@ -59,11 +59,6 @@ describe('Test report extension', () => {
...props, ...props,
}, },
}, },
provide: {
glFeatures: {
mrShowReportsImmediately: flagState,
},
},
}); });
}; };
@ -111,10 +106,10 @@ describe('Test report extension', () => {
expect(wrapper.text()).toContain('Test summary results are being parsed'); expect(wrapper.text()).toContain('Test summary results are being parsed');
}); });
describe('with feature flag mrShowReportsImmediately enabled', () => { describe('with in progress pipeline', () => {
beforeEach(async () => { beforeEach(async () => {
mockApi(HTTP_STATUS_OK, recentFailures); mockApi(HTTP_STATUS_OK, recentFailures);
createComponent({ isPipelineActive: true }, true); createComponent({ isPipelineActive: true });
await waitForPromises(); await waitForPromises();
}); });

View File

@ -211,6 +211,13 @@ RSpec.describe Groups::GroupMembersHelper, feature_category: :groups_and_project
end end
describe '#group_member_header_subtext' do describe '#group_member_header_subtext' do
let(:current_user) { create(:user) }
before do
allow(helper).to receive(:current_user).and_return(current_user)
allow(helper).to receive(:can?).with(current_user, :invite_group_members, group).and_return(true)
end
it 'contains expected text with group name' do it 'contains expected text with group name' do
expect(helper.group_member_header_subtext(group)).to match("You're viewing members of .*#{group.name}") expect(helper.group_member_header_subtext(group)).to match("You're viewing members of .*#{group.name}")
end end

View File

@ -167,6 +167,7 @@ RSpec.describe Projects::ProjectMembersHelper, feature_category: :groups_and_pro
describe '#project_member_header_subtext' do describe '#project_member_header_subtext' do
before do before do
allow(helper).to receive(:can?).with(current_user, :invite_project_members, project).and_return(true)
allow(helper).to receive(:can?).with(current_user, :admin_project_member, project).and_return(can_admin_member) allow(helper).to receive(:can?).with(current_user, :admin_project_member, project).and_return(can_admin_member)
end end

View File

@ -4597,21 +4597,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep, feature_category:
context 'when pipeline status is running' do context 'when pipeline status is running' do
let(:pipeline) { create(:ci_pipeline, :running) } let(:pipeline) { create(:ci_pipeline, :running) }
context 'with mr_show_reports_immediately flag enabled' do it { expect(subject).to be_falsey }
before do
stub_feature_flags(mr_show_reports_immediately: project)
end
it { expect(subject).to be_truthy }
end
context 'with mr_show_reports_immediately flag disabled' do
before do
stub_feature_flags(mr_show_reports_immediately: false)
end
it { expect(subject).to be_falsey }
end
end end
context 'when pipeline status is success' do context 'when pipeline status is success' do
@ -4655,38 +4641,24 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep, feature_category:
create(:ci_build, :test_reports, pipeline: pipeline) create(:ci_build, :test_reports, pipeline: pipeline)
end end
context 'with mr_show_reports_immediately flag enabled' do it { expect(subject).to be_falsey }
before do
stub_feature_flags(mr_show_reports_immediately: project)
end
it { expect(subject).to be_truthy } context 'when pipeline status is running' do
let(:pipeline) { create(:ci_pipeline, :running) }
it { is_expected.to be_falsey }
end end
context 'with mr_show_reports_immediately flag disabled' do context 'when pipeline status is success' do
before do let(:pipeline) { create(:ci_pipeline, :success) }
stub_feature_flags(mr_show_reports_immediately: false)
end
it { expect(subject).to be_falsey } it { is_expected.to be_truthy }
end
context 'when pipeline status is running' do context 'when pipeline status is manual' do
let(:pipeline) { create(:ci_pipeline, :running) } let(:pipeline) { create(:ci_pipeline, :manual) }
it { is_expected.to be_falsey } it { is_expected.to be_truthy }
end
context 'when pipeline status is success' do
let(:pipeline) { create(:ci_pipeline, :success) }
it { is_expected.to be_truthy }
end
context 'when pipeline status is manual' do
let(:pipeline) { create(:ci_pipeline, :manual) }
it { is_expected.to be_truthy }
end
end end
end end
@ -4776,21 +4748,7 @@ RSpec.describe Ci::Pipeline, :mailer, factory_default: :keep, feature_category:
context 'when pipeline status is running' do context 'when pipeline status is running' do
let(:pipeline) { create(:ci_pipeline, :running) } let(:pipeline) { create(:ci_pipeline, :running) }
context 'with mr_show_reports_immediately flag enabled' do it { expect(subject).to be_falsey }
before do
stub_feature_flags(mr_show_reports_immediately: project)
end
it { expect(subject).to be_truthy }
end
context 'with mr_show_reports_immediately flag disabled' do
before do
stub_feature_flags(mr_show_reports_immediately: false)
end
it { expect(subject).to be_falsey }
end
end end
context 'when pipeline status is success' do context 'when pipeline status is success' do

View File

@ -3133,10 +3133,6 @@ RSpec.describe MergeRequest, factory_default: :keep, feature_category: :code_rev
end end
context 'when head pipeline is not finished and has terraform reports' do context 'when head pipeline is not finished and has terraform reports' do
before do
stub_feature_flags(mr_show_reports_immediately: false)
end
it 'returns true' do it 'returns true' do
merge_request = create(:merge_request, :with_terraform_reports) merge_request = create(:merge_request, :with_terraform_reports)
merge_request.diff_head_pipeline.update!(status: :running) merge_request.diff_head_pipeline.update!(status: :running)

View File

@ -584,10 +584,10 @@ RSpec.describe BulkImports::CreateService, :clean_gitlab_redis_shared_state, fea
expect(result).to be_a(ServiceResponse) expect(result).to be_a(ServiceResponse)
expect(result).to be_error expect(result).to be_error
expect(result.message).to eq("Validation failed: Source full path can't be blank, " \ expect(result.message).to eq("Validation failed: Source full path can't be blank, " \
"Source full path must have a relative path structure with " \ "Source full path must have a relative path with " \
"no HTTP protocol characters, or leading or trailing forward slashes. " \ "no HTTP protocol characters or leading or trailing forward slashes. " \
"Path segments must not start or end with a special character, and " \ "Path segments must not start or end with a special character or " \
"must not contain consecutive special characters") "contain consecutive special characters.")
end end
describe '#user-role' do describe '#user-role' do

View File

@ -19,7 +19,7 @@ RSpec.describe Ci::JobArtifacts::TrackArtifactReportService, feature_category: :
subject(:track_artifact_report) { described_class.new.execute(pipeline) } subject(:track_artifact_report) { described_class.new.execute(pipeline) }
context 'when pipeline has test reports' do context 'when pipeline has test reports' do
let_it_be(:pipeline) { create(:ci_pipeline, project: project, user: user1) } let_it_be(:pipeline) { create(:ci_pipeline, :success, project: project, user: user1) }
before do before do
2.times do 2.times do
@ -108,7 +108,7 @@ RSpec.describe Ci::JobArtifacts::TrackArtifactReportService, feature_category: :
end end
context 'when pipeline has coverage test reports' do context 'when pipeline has coverage test reports' do
let_it_be(:pipeline) { create(:ci_pipeline, project: project, user: user1) } let_it_be(:pipeline) { create(:ci_pipeline, :success, project: project, user: user1) }
before do before do
2.times do 2.times do