Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2025-04-22 18:10:16 +00:00
parent 16b13e3358
commit 0c0ac7652b
138 changed files with 1486 additions and 638 deletions

View File

@ -1 +1 @@
0526d03bec8ec0e642b8c32c7ece396e0ba914f6
98e4597b4ab1d5a87be725ae0aa58ba3f2566210

View File

@ -1,15 +1,12 @@
<script>
import { GlButton } from '@gitlab/ui';
import ManualJobForm from '~/ci/job_details/components/manual_job_form.vue';
import PipelineVariablesPermissionsMixin from '~/ci/mixins/pipeline_variables_permissions_mixin';
export default {
components: {
GlButton,
ManualJobForm,
},
mixins: [PipelineVariablesPermissionsMixin],
inject: ['projectPath', 'userRole'],
props: {
illustrationPath: {
type: String,
@ -73,9 +70,6 @@ export default {
shouldRenderManualVariables() {
return this.playable && !this.scheduled;
},
shouldRenderPipelineVariablesText() {
return this.canViewPipelineVariables && this.shouldRenderManualVariables && !this.isRetryable;
},
},
};
</script>
@ -97,11 +91,6 @@ export default {
</h2>
<p v-if="content" class="gl-mb-0 gl-mt-4" data-testid="job-empty-state-content">
{{ content }}
<template v-if="shouldRenderPipelineVariablesText">{{
s__(
'CiVariables|You can add CI/CD variables below for last-minute configuration changes before starting the job.',
)
}}</template>
</p>
<manual-job-form
v-if="shouldRenderManualVariables"
@ -109,7 +98,6 @@ export default {
:job-id="jobId"
:job-name="jobName"
:confirmation-message="confirmationMessage"
:can-view-pipeline-variables="canViewPipelineVariables"
@hideManualVariablesForm="$emit('hideManualVariablesForm')"
/>
<div

View File

@ -21,6 +21,7 @@ export default {
GlButton,
JobVariablesForm,
},
inject: ['canSetPipelineVariables'],
props: {
isRetryable: {
type: Boolean,
@ -39,11 +40,6 @@ export default {
required: false,
default: null,
},
canViewPipelineVariables: {
type: Boolean,
required: false,
default: false,
},
},
data() {
return {
@ -136,7 +132,7 @@ export default {
<template>
<div>
<job-variables-form
v-if="canViewPipelineVariables"
v-if="canSetPipelineVariables"
:job-id="jobId"
@update-variables="onVariablesUpdate"
/>

View File

@ -7,7 +7,6 @@ import { s__, __ } from '~/locale';
import axios from '~/lib/utils/axios_utils';
import { visitUrl } from '~/lib/utils/url_utility';
import { confirmJobConfirmationMessage } from '~/ci/pipeline_details/graph/utils';
import PipelineVariablesPermissionsMixin from '~/ci/mixins/pipeline_variables_permissions_mixin';
export default {
name: 'JobSidebarRetryButton',
@ -21,8 +20,7 @@ export default {
GlModal: GlModalDirective,
GlTooltip: GlTooltipDirective,
},
mixins: [PipelineVariablesPermissionsMixin],
inject: ['projectPath', 'userRole'],
inject: ['canSetPipelineVariables'],
props: {
modalId: {
type: String,
@ -96,7 +94,7 @@ export default {
/>
<div v-else-if="isManualJob" class="gl-flex gl-gap-3">
<gl-button
v-if="canViewPipelineVariables"
v-if="canSetPipelineVariables"
v-gl-tooltip.bottom
:title="$options.i18n.updateVariables"
:aria-label="$options.i18n.updateVariables"

View File

@ -34,7 +34,7 @@ export const initJobDetails = () => {
pipelineTestReportUrl,
logViewerPath,
duoFeaturesEnabled,
userRole,
canSetPipelineVariables,
} = el.dataset;
const fullScreenAPIAvailable = document.fullscreenEnabled;
@ -59,7 +59,7 @@ export const initJobDetails = () => {
aiRootCauseAnalysisAvailable: parseBoolean(aiRootCauseAnalysisAvailable),
duoFeaturesEnabled: parseBoolean(duoFeaturesEnabled),
pipelineTestReportUrl,
userRole,
canSetPipelineVariables: parseBoolean(canSetPipelineVariables),
},
render(h) {
return h(JobApp, {

View File

@ -50,6 +50,11 @@ export default {
required: false,
default: true,
},
customEmojiPath: {
type: String,
required: false,
default: '',
},
},
data() {
return {
@ -61,6 +66,9 @@ export default {
};
},
computed: {
newEmojiPath() {
return this.newCustomEmojiPath || this.customEmojiPath;
},
categoryNames() {
return CATEGORY_NAMES.filter((c) => {
if (c === FREQUENTLY_USED_KEY) return hasFrequentlyUsedEmojis();
@ -77,7 +85,7 @@ export default {
newCustomEmoji() {
return {
text: __('Create new emoji'),
href: this.newCustomEmojiPath,
href: this.newEmojiPath,
extraAttrs: {
'data-testid': 'create-new-emoji',
},
@ -225,12 +233,12 @@ export default {
</template>
</emoji-list>
<template v-if="newCustomEmojiPath" #footer>
<template v-if="newEmojiPath" #footer>
<div
class="gl-flex gl-flex-col gl-border-t-1 gl-border-t-dropdown !gl-p-2 !gl-pt-0 gl-border-t-solid"
>
<gl-button
:href="newCustomEmojiPath"
:href="newEmojiPath"
category="tertiary"
block
data-testid="create-new-emoji"

View File

@ -15,6 +15,7 @@ import {
import { WORK_ITEM_TYPE_NAME_EPIC } from '~/work_items/constants';
export default {
name: 'IssuePopover',
components: {
GlIcon,
GlPopover,
@ -31,7 +32,7 @@ export default {
mixins: [timeagoMixin],
props: {
target: {
type: HTMLAnchorElement,
type: [HTMLElement, Function, Object, String],
required: true,
},
namespacePath: {
@ -44,7 +45,13 @@ export default {
},
cachedTitle: {
type: String,
required: true,
required: false,
default: '',
},
show: {
type: Boolean,
required: false,
default: false,
},
},
data() {
@ -96,7 +103,7 @@ export default {
</script>
<template>
<gl-popover :target="target" boundary="viewport" placement="top" show>
<gl-popover :target="target" boundary="viewport" placement="top" :show="show">
<gl-skeleton-loader v-if="$apollo.queries.workItem.loading" :height="15">
<rect width="250" height="15" rx="4" />
</gl-skeleton-loader>
@ -115,7 +122,7 @@ export default {
{{ __('Opened') }} <time :datetime="workItem.createdAt">{{ formattedTime }}</time>
</span>
</div>
<div class="gl-heading-5 gl-my-3">{{ title }}</div>
<div class="gl-heading-5 gl-my-3" data-testid="popover-title">{{ title }}</div>
<div>
<work-item-type-icon :work-item-type="type" />
<span class="gl-text-subtle">{{ reference }}</span>

View File

@ -79,6 +79,7 @@ export const handleIssuablePopoverMount = ({
placement,
milestoneId: milestone,
cachedTitle: title || innerText,
show: true,
},
apolloProvider,
}).$mount();

View File

@ -24,6 +24,11 @@ export default {
SafeHtml,
},
props: {
customEmojiPath: {
type: String,
required: false,
default: '',
},
awards: {
type: Array,
required: true,
@ -194,6 +199,7 @@ export default {
<div v-if="canAwardEmoji" class="award-menu-holder gl-my-2">
<emoji-picker
:right="false"
:custom-emoji-path="customEmojiPath"
data-testid="emoji-picker"
@click="handleAward"
@shown="setIsMenuOpen(true)"

View File

@ -10,7 +10,7 @@ import * as Sentry from '~/sentry/sentry_browser_wrapper';
import { __, sprintf } from '~/locale';
import UserAccessRoleBadge from '~/vue_shared/components/user_access_role_badge.vue';
import ReplyButton from '~/notes/components/note_actions/reply_button.vue';
import { getMutation, optimisticAwardUpdate } from '../../notes/award_utils';
import { getMutation, optimisticAwardUpdate, getNewCustomEmojiPath } from '../../notes/award_utils';
export default {
name: 'WorkItemNoteActions',
@ -160,6 +160,13 @@ export default {
? __('Resolved by ') + this.resolvedBy.name
: this.$options.i18n.resolveThreadTitle;
},
customEmojiPath() {
return getNewCustomEmojiPath({
cache: this.$apollo.provider.clients.defaultClient,
fullPath: this.fullPath,
workItemIid: this.workItemIid,
});
},
},
methods: {
async setAwardEmoji(name) {
@ -244,6 +251,7 @@ export default {
v-if="showAwardEmoji"
toggle-class="add-reaction-button btn-default-tertiary"
data-testid="note-emoji-button"
:custom-emoji-path="customEmojiPath"
@click="setAwardEmoji"
/>
<reply-button v-if="showReply" ref="replyButton" @startReplying="$emit('startReplying')" />

View File

@ -2,7 +2,7 @@
import * as Sentry from '~/sentry/sentry_browser_wrapper';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import AwardsList from '~/vue_shared/components/awards_list.vue';
import { getMutation, optimisticAwardUpdate } from '../../notes/award_utils';
import { getMutation, optimisticAwardUpdate, getNewCustomEmojiPath } from '../../notes/award_utils';
export default {
components: {
@ -37,6 +37,13 @@ export default {
hasAwardEmojiPermission() {
return this.note.userPermissions.awardEmoji;
},
customEmojiPath() {
return getNewCustomEmojiPath({
cache: this.$apollo.provider.clients.defaultClient,
fullPath: this.fullPath,
workItemIid: this.workItemIid,
});
},
currentUserId() {
return window.gon.current_user_id;
},
@ -83,6 +90,7 @@ export default {
:awards="awards"
:can-award-emoji="hasAwardEmojiPermission"
:current-user-id="currentUserId"
:custom-emoji-path="customEmojiPath"
@award="handleAward($event)"
/>
</template>

View File

@ -37,6 +37,7 @@ export default {
},
data() {
return {
newCustomEmojiPath: '',
isLoading: false,
};
},
@ -63,6 +64,9 @@ export default {
},
}));
},
customEmojiPath() {
return this.newCustomEmojiPath;
},
pageInfo() {
return this.awardEmoji?.pageInfo;
},
@ -95,6 +99,8 @@ export default {
this.isLoading = false;
}
if (data) {
this.newCustomEmojiPath =
findAwardEmojiWidget(data.workspace?.workItem)?.newCustomEmojiPath || '';
this.$emit('emoji-updated', data.workspace?.workItem);
}
},
@ -244,6 +250,7 @@ export default {
:can-award-emoji="$options.isLoggedIn"
:current-user-id="currentUserId"
:default-awards="$options.defaultAwards"
:custom-emoji-path="customEmojiPath"
selected-class="selected"
@award="handleAward"
/>

View File

@ -90,8 +90,6 @@ import DesignUploadButton from './design_management/upload_button.vue';
import WorkItemDevelopment from './work_item_development/work_item_development.vue';
import WorkItemCreateBranchMergeRequestSplitButton from './work_item_development/work_item_create_branch_merge_request_split_button.vue';
const WorkItemErrorTracking = () => import('~/work_items/components/work_item_error_tracking.vue');
const defaultWorkspacePermissions = {
createDesign: false,
moveDesign: false,
@ -128,7 +126,7 @@ export default {
WorkItemTree,
WorkItemNotes,
WorkItemRelationships,
WorkItemErrorTracking,
WorkItemErrorTracking: () => import('~/work_items/components/work_item_error_tracking.vue'),
WorkItemStickyHeader,
WorkItemAncestors,
WorkItemTitle,

View File

@ -1,5 +1,5 @@
<script>
import { GlLink, GlIcon, GlPopover } from '@gitlab/ui';
import { GlIcon, GlLink, GlPopover } from '@gitlab/ui';
import * as Sentry from '~/sentry/sentry_browser_wrapper';
import { s__ } from '~/locale';
@ -15,31 +15,21 @@ import workItemsByReferencesQuery from '../graphql/work_items_by_references.quer
import workItemAllowedParentTypesQuery from '../graphql/work_item_allowed_parent_types.query.graphql';
import {
I18N_WORK_ITEM_ERROR_UPDATING,
NAME_TO_ENUM_MAP,
NO_WORK_ITEM_IID,
sprintfWorkItem,
WORK_ITEM_TYPE_ENUM_EPIC,
WORK_ITEM_TYPE_NAME_ISSUE,
NAME_TO_ENUM_MAP,
} from '../constants';
import { isReference, findHierarchyWidgetDefinition, newWorkItemId } from '../utils';
import { findHierarchyWidgetDefinition, isReference, newWorkItemId } from '../utils';
export default {
name: 'WorkItemParent',
inputId: 'work-item-parent-listbox-value',
noWorkItemId: 'no-work-item-id',
i18n: {
assignParentLabel: s__('WorkItem|Select parent'),
parentLabel: s__('WorkItem|Parent'),
none: s__('WorkItem|None'),
unAssign: s__('WorkItem|Clear'),
workItemsFetchError: s__(
'WorkItem|Something went wrong while fetching items. Please try again.',
),
searchPlaceholder: s__('WorkItem|Search or paste URL'),
},
components: {
GlLink,
GlIcon,
GlPopover,
IssuePopover: () => import('~/issuable/popover/components/issue_popover.vue'),
WorkItemSidebarDropdownWidget,
},
inject: ['fullPath'],
@ -108,12 +98,15 @@ export default {
return (
this.workItems.find(({ value }) => this.localSelectedItem === value)?.text ||
this.parent?.title ||
this.$options.i18n.none
s__('WorkItem|None')
);
},
workItems() {
return this.availableWorkItems?.map(({ id, title }) => ({ text: title, value: id })) || [];
},
parentFullPath() {
return this.parent?.namespace.fullPath;
},
parentWebUrl() {
return this.parent?.webUrl;
},
@ -159,7 +152,10 @@ export default {
return data.workspace.workItems.nodes.filter((wi) => this.workItemId !== wi.id) || [];
},
error() {
this.$emit('error', this.$options.i18n.workItemsFetchError);
this.$emit(
'error',
s__('WorkItem|Something went wrong while fetching items. Please try again.'),
);
},
},
workItemsByReference: {
@ -177,7 +173,10 @@ export default {
return data?.workItemsByReference?.nodes || [];
},
error() {
this.$emit('error', this.$options.i18n.workItemsFetchError);
this.$emit(
'error',
s__('WorkItem|Something went wrong while fetching items. Please try again.'),
);
},
},
allowedParentTypes: {
@ -255,9 +254,7 @@ export default {
id: this.workItemId,
hierarchyWidget: {
parentId:
this.localSelectedItem === this.$options.noWorkItemId
? null
: this.localSelectedItem,
this.localSelectedItem === NO_WORK_ITEM_IID ? null : this.localSelectedItem,
},
},
},
@ -272,7 +269,7 @@ export default {
if (errors.length) {
this.$emit('error', errors.join('\n'));
this.localSelectedItem = this.parent?.id || this.$options.noWorkItemId;
this.localSelectedItem = this.parent?.id || NO_WORK_ITEM_IID;
}
} catch (error) {
this.$emit('error', sprintfWorkItem(I18N_WORK_ITEM_ERROR_UPDATING, this.workItemType));
@ -289,7 +286,7 @@ export default {
this.updateParent();
},
unassignParent() {
this.localSelectedItem = this.$options.noWorkItemId;
this.localSelectedItem = NO_WORK_ITEM_IID;
this.updateParent();
},
onListboxShown() {
@ -311,11 +308,11 @@ export default {
:list-items="workItems"
:loading="isLoading"
:item-value="localSelectedItem"
:header-text="$options.i18n.assignParentLabel"
:header-text="s__('WorkItem|Select parent')"
:update-in-progress="updateInProgress"
:reset-button-label="$options.i18n.unAssign"
:reset-button-label="s__('WorkItem|Clear')"
:toggle-dropdown-text="listboxText"
:search-placeholder="$options.i18n.searchPlaceholder"
:search-placeholder="s__('WorkItem|Search or paste URL')"
data-testid="work-item-parent"
@dropdownShown="onListboxShown"
@dropdownHidden="onListboxHide"
@ -324,13 +321,21 @@ export default {
@reset="unassignParent"
>
<template #readonly>
<gl-link
v-if="localSelectedItem"
data-testid="work-item-parent-link"
class="gl-inline-block gl-max-w-full gl-overflow-hidden gl-text-ellipsis gl-whitespace-nowrap gl-align-top gl-text-default"
:href="parentWebUrl"
>{{ listboxText }}</gl-link
>
<template v-if="localSelectedItem">
<gl-link
ref="link"
data-testid="work-item-parent-link"
class="gl-inline-block gl-max-w-full gl-overflow-hidden gl-text-ellipsis gl-whitespace-nowrap gl-align-top gl-text-default"
:href="parentWebUrl"
>{{ listboxText }}</gl-link
>
<issue-popover
:cached-title="parent.title"
:iid="parent.iid"
:namespace-path="parentFullPath"
:target="() => $refs.link.$el"
/>
</template>
</template>
<template v-if="showCustomNoneValue" #none>
<span id="parent-not-available" class="gl-cursor-help">

View File

@ -265,8 +265,8 @@ export const RELATED_ITEM_ID_URL_QUERY_PARAM = 'related_item_id';
export const WORK_ITEM_REFERENCE_CHAR = '#';
export const NEW_WORK_ITEM_IID = 'new-work-item-iid';
export const NEW_WORK_ITEM_GID = 'gid://gitlab/WorkItem/new';
export const NO_WORK_ITEM_IID = 'no-work-item-iid';
export const NEW_EPIC_FEEDBACK_PROMPT_EXPIRY = '2024-12-31';
export const NEW_ISSUE_FEEDBACK_PROMPT_EXPIRY = '2025-04-25';

View File

@ -10,6 +10,7 @@ query projectWorkItemAwardEmojis($fullPath: ID!, $iid: String!, $after: String,
widgets {
... on WorkItemWidgetAwardEmoji {
type
newCustomEmojiPath
awardEmoji(first: $pageSize, after: $after) {
pageInfo {
...PageInfo

View File

@ -23,6 +23,10 @@ query groupWorkItems(
iid
title
confidential
namespace {
id
fullPath
}
workItemType {
id
name
@ -41,6 +45,10 @@ query groupWorkItems(
iid
title
confidential
namespace {
id
fullPath
}
workItemType {
id
name

View File

@ -15,6 +15,10 @@ query projectWorkItems(
iid
title
confidential
namespace {
id
fullPath
}
workItemType {
id
name
@ -28,6 +32,10 @@ query projectWorkItems(
iid
title
confidential
namespace {
id
fullPath
}
workItemType {
id
name

View File

@ -11,6 +11,10 @@ fragment WorkItemAncestors on WorkItem {
iid
title
confidential
namespace {
id
fullPath
}
webUrl
workItemType {
id

View File

@ -67,6 +67,10 @@ fragment WorkItemWidgets on WorkItemWidget {
iid
title
confidential
namespace {
id
fullPath
}
webUrl
workItemType {
id

View File

@ -5,6 +5,10 @@ query getWorkItemsByReferences($contextNamespacePath: ID!, $refs: [String!]!) {
iid
title
confidential
namespace {
id
fullPath
}
workItemType {
id
name

View File

@ -6,8 +6,10 @@ import {
updateCacheAfterRemovingAwardEmojiFromNote,
} from '~/work_items/graphql/cache_utils';
import workItemNotesByIidQuery from '../graphql/notes/work_item_notes_by_iid.query.graphql';
import workItemAwardEmojiQuery from '../graphql/award_emoji.query.graphql';
import addAwardEmojiMutation from '../graphql/notes/work_item_note_add_award_emoji.mutation.graphql';
import removeAwardEmojiMutation from '../graphql/notes/work_item_note_remove_award_emoji.mutation.graphql';
import { findAwardEmojiWidget } from '../utils';
function awardedByCurrentUser(note) {
return (note.awardEmoji?.nodes ?? [])
@ -66,3 +68,18 @@ export function optimisticAwardUpdate({ note, name, fullPath, workItemIid }) {
);
};
}
export const getNewCustomEmojiPath = ({ cache, fullPath, workItemIid }) => {
const query = {
query: workItemAwardEmojiQuery,
variables: { fullPath, iid: workItemIid, pageSize: 1 },
};
const sourceData = cache.readQuery(query);
if (!sourceData?.workspace?.workItem) {
return '';
}
return findAwardEmojiWidget(sourceData.workspace.workItem)?.newCustomEmojiPath || '';
};

View File

@ -39,7 +39,7 @@ class Admin::GroupsController < Admin::ApplicationController
def create
response = ::Groups::CreateService.new(current_user,
group_params.with_defaults(organization_id: Current.organization&.id)).execute
group_params.with_defaults(organization_id: Current.organization.id)).execute
@group = response[:group]
if response.success?

View File

@ -84,6 +84,6 @@ class Admin::TopicsController < Admin::ApplicationController
end
def organization_id
::Current.organization&.id
::Current.organization.id
end
end

View File

@ -82,7 +82,7 @@ class GroupsController < Groups::ApplicationController
def create
response = Groups::CreateService.new(
current_user,
group_params.merge(organization_id: Current.organization&.id)
group_params.merge(organization_id: Current.organization.id)
).execute
@group = response[:group]

View File

@ -112,7 +112,7 @@ class Import::BaseController < ApplicationController
group = Groups::NestedCreateService.new(
current_user,
organization_id: Current.organization&.id,
organization_id: Current.organization.id,
group_path: names
).execute

View File

@ -44,7 +44,7 @@ class Import::BitbucketServerController < Import::BaseController
result = Import::BitbucketServerService.new(
client,
current_user,
params.merge({ organization_id: Current.organization&.id })
params.merge({ organization_id: Current.organization.id })
).execute(credentials)
if result[:status] == :success

View File

@ -58,7 +58,7 @@ class Import::FogbugzController < Import::BaseController
service_params = params.merge({
umap: session[:fogbugz_user_map] || client.user_map,
organization_id: Current.organization&.id
organization_id: Current.organization.id
})
result = Import::FogbugzService.new(client, current_user, service_params).execute(credentials)

View File

@ -21,7 +21,7 @@ class Import::GitlabGroupsController < ApplicationController
visibility_level: closest_allowed_visibility_level,
import_export_upload: ImportExportUpload.new(import_file: group_params[:file], user: current_user)
)
.with_defaults(organization_id: Current.organization&.id)
.with_defaults(organization_id: Current.organization.id)
response = ::Groups::CreateService.new(current_user, group_data).execute

View File

@ -78,7 +78,7 @@ class Oauth::AuthorizationsController < Doorkeeper::AuthorizationsController
# Cannot be achieved with a before_action hook, due to the execution order.
downgrade_scopes! if action_name == 'new'
params[:organization_id] = ::Current.organization&.id
params[:organization_id] = ::Current.organization.id
super
end

View File

@ -53,7 +53,7 @@ module UserSettings
result = ::PersonalAccessTokens::CreateService.new(
current_user: current_user,
target_user: current_user,
organization_id: Current.organization&.id,
organization_id: Current.organization.id,
params: personal_access_token_params,
concatenate_errors: false
).execute

View File

@ -21,7 +21,6 @@ class TodosFinder
include FinderMethods
include Gitlab::Utils::StrongMemoize
include SafeFormatHelper
include Gitlab::InternalEventsTracking
requires_cross_project_access unless: -> { project? }
@ -49,8 +48,6 @@ class TodosFinder
return Todo.none if current_user.nil?
raise ArgumentError, invalid_type_message unless valid_types?
track_bot_user if current_user.bot?
items = current_user.todos
items = without_hidden(items)
items = by_action_id(items)
@ -264,17 +261,6 @@ class TodosFinder
def filter_done_only?
Array.wrap(params[:state]).map(&:to_sym) == [:done]
end
def track_bot_user
track_internal_event(
"request_todos_by_bot_user",
user: current_user,
additional_properties: {
label: 'user_type',
property: current_user.user_type
}
)
end
end
TodosFinder.prepend_mod_with('TodosFinder')

View File

@ -3,6 +3,7 @@
module Resolvers
class TodosResolver < BaseResolver
type Types::TodoType.connection_type, null: true
include Gitlab::InternalEventsTracking
alias_method :target, :object
@ -49,6 +50,8 @@ module Resolvers
return Todo.none unless current_user.present? && target.present?
return Todo.none if target.is_a?(User) && target != current_user
track_bot_user if current_user.bot?
TodosFinder.new(current_user, todo_finder_params(args)).execute.with_entity_associations
end
@ -75,5 +78,16 @@ module Resolvers
target_id: target.id
}
end
def track_bot_user
track_internal_event(
"request_todos_by_bot_user",
user: current_user,
additional_properties: {
label: 'user_type',
property: current_user.user_type
}
)
end
end
end

View File

@ -40,9 +40,9 @@ module Types
end
def new_custom_emoji_path
return unless context[:current_user]&.can?(:create_custom_emoji, object.work_item.project.namespace)
return unless context[:current_user]
::Gitlab::Routing.url_helpers.new_group_custom_emoji_path(object.work_item.project.namespace)
object.new_custom_emoji_path(context[:current_user])
end
end
# rubocop:enable Graphql/AuthorizeTypes

View File

@ -466,6 +466,7 @@ module ApplicationSettingsHelper
:throttle_protected_paths_enabled,
:throttle_protected_paths_period_in_seconds,
:throttle_protected_paths_requests_per_period,
:top_level_group_creation_enabled,
:protected_paths_raw,
:protected_paths_for_get_request_raw,
:time_tracking_limit_to_hours,

View File

@ -15,7 +15,7 @@ module Ci
"retry_outdated_job_docs_url" => help_page_path('ci/pipelines/settings.md', anchor: 'prevent-outdated-deployment-jobs'),
"pipeline_test_report_url" => test_report_project_pipeline_path(project, build.pipeline),
"log_viewer_path" => viewer_project_job_path(project, build),
"user_role" => project.team.human_max_access(current_user&.id)
"can_set_pipeline_variables" => Ability.allowed?(current_user, :set_pipeline_variables, project).to_s
}
end

View File

@ -679,6 +679,12 @@ class ApplicationSetting < ApplicationRecord
attribute :resource_usage_limits, ::Gitlab::Database::Type::IndifferentJsonb.new, default: -> { {} }
validates :resource_usage_limits, json_schema: { filename: 'resource_usage_limits' }
jsonb_accessor :group_settings,
top_level_group_creation_enabled: [:boolean, { default: true }]
validates :group_settings,
json_schema: { filename: "application_setting_group_settings" }
jsonb_accessor :clickhouse,
use_clickhouse_for_analytics: [:boolean, { default: false }]

View File

@ -324,6 +324,7 @@ module ApplicationSettingImplementation
scan_execution_policies_schedule_limit: 0,
seat_control: 0,
show_migrate_from_jenkins_banner: true,
top_level_group_creation_enabled: true,
ropc_without_client_credentials: true,
vscode_extension_marketplace_enabled: false,
reindexing_minimum_index_size: 1.gigabyte,

View File

@ -5,9 +5,6 @@ class ProjectPagesMetadatum < ApplicationRecord
include EachBatch
ignore_column :pages_deployment_id, remove_with: '17.11', remove_after: '2025-03-21'
ignore_column :deployed, remove_with: '17.11', remove_after: '2025-03-21'
self.primary_key = :project_id
belongs_to :project, inverse_of: :pages_metadatum

View File

@ -0,0 +1,12 @@
{
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Application settings for the group_setting JsonB column",
"type": "object",
"additionalProperties": false,
"properties": {
"top_level_group_creation_enabled": {
"type": "boolean",
"description": "Allows a user to create top-level-groups"
}
}
}

View File

@ -44,9 +44,8 @@
#{link_to _('View it on GitLab'), @target_url}.
%br
= notification_reason_text(reason: @reason, show_manage_notifications_link: !@labels_url, show_help_link: true, manage_label_subscriptions_url: @labels_url, unsubscribe_url: @unsubscribe_url, format: :html)
- if Feature.enabled?(:fix_gmail_footer_truncation, @project)
%span{ style: "color:transparent;font-size:0;display:none;overflow:hidden;opacity:0;width:0;height:0;max-width:0;max-height:0" }
= 'Notification message regarding ' + @target_url + " at #{Time.current.to_i}"
%span{ style: "color:transparent;font-size:0;display:none;overflow:hidden;opacity:0;width:0;height:0;max-width:0;max-height:0" }
= 'Notification message regarding ' + @target_url + " at #{Time.current.to_i}"
= email_action @target_url

View File

@ -0,0 +1,12 @@
---
api_type:
attr: group_settings
clusterwide: false
column: group_settings
db_type: jsonb
default: "'{}'::jsonb"
description: "A jsonb column that stores a hash of related group_settings on the application_settings table"
encrypted: false
gitlab_com_different_than_default: true
jihu: false
not_null: true

View File

@ -1,31 +0,0 @@
diff --git a/app/views/layouts/notify.html.haml b/app/views/layouts/notify.html.haml
index 826d822354b6..b713cee3266f 100644
--- a/app/views/layouts/notify.html.haml
+++ b/app/views/layouts/notify.html.haml
@@ -44,9 +44,8 @@
#{link_to _('View it on GitLab'), @target_url}.
%br
= notification_reason_text(reason: @reason, show_manage_notifications_link: !@labels_url, show_help_link: true, manage_label_subscriptions_url: @labels_url, unsubscribe_url: @unsubscribe_url, format: :html)
- - if Feature.enabled?(:fix_gmail_footer_truncation, @project)
- %span{ style: "color:transparent;font-size:0;display:none;overflow:hidden;opacity:0;width:0;height:0;max-width:0;max-height:0" }
- = 'Notification message regarding ' + @target_url + " at #{Time.current.to_i}"
+ %span{ style: "color:transparent;font-size:0;display:none;overflow:hidden;opacity:0;width:0;height:0;max-width:0;max-height:0" }
+ = 'Notification message regarding ' + @target_url + " at #{Time.current.to_i}"
= email_action @target_url
diff --git a/config/feature_flags/wip/fix_gmail_footer_truncation.yml b/config/feature_flags/wip/fix_gmail_footer_truncation.yml
deleted file mode 100644
index e092a0d092b6..000000000000
--- a/config/feature_flags/wip/fix_gmail_footer_truncation.yml
+++ /dev/null
@@ -1,9 +0,0 @@
----
-name: fix_gmail_footer_truncation
-feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/14072
-introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/177913
-rollout_issue_url:
-milestone: '17.11'
-group: group::ux paper cuts
-type: wip
-default_enabled: false

View File

@ -1,9 +0,0 @@
---
name: fix_gmail_footer_truncation
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/14072
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/177913
rollout_issue_url:
milestone: '17.11'
group: group::ux paper cuts
type: wip
default_enabled: false

View File

@ -0,0 +1,8 @@
---
migration_job_name: BackfillAmazonGroupAuditEventDestinationsFixed
description: Fixed version of BackfillAmazonGroupAuditEventDestinations BBM
feature_category: audit_events
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/186866
milestone: '18.0'
queued_migration_version: 20250403155730
finalized_by: # version of the migration that finalized this BBM

View File

@ -0,0 +1,8 @@
---
migration_job_name: BackfillAmazonInstanceAuditEventDestinationsFixed
description: Fixed version of BackfillAmazonInstanceAuditEventDestinations BBM
feature_category: audit_events
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/186866
milestone: '18.0'
queued_migration_version: 20250403155743
finalized_by: # version of the migration that finalized this BBM

View File

@ -0,0 +1,8 @@
---
migration_job_name: BackfillExternalGroupAuditEventDestinationsFixed
description: Fixed version of BackfillExternalGroupAuditEventDestinations BBM
feature_category: audit_events
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/186866
milestone: '18.0'
queued_migration_version: 20250403155636
finalized_by: # version of the migration that finalized this BBM

View File

@ -0,0 +1,8 @@
---
migration_job_name: BackfillExternalInstanceAuditEventDestinationsFixed
description: Fixed version of BackfillExternalInstanceAuditEventDestinations BBM
feature_category: audit_events
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/186866
milestone: '18.0'
queued_migration_version: 20250403155703
finalized_by: # version of the migration that finalized this BBM

View File

@ -0,0 +1,8 @@
---
migration_job_name: BackfillGoogleGroupAuditEventDestinationsFixed
description: Fixed version of BackfillGoogleGroupAuditEventDestinations BBM
feature_category: audit_events
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/186866
milestone: '18.0'
queued_migration_version: 20250403155756
finalized_by: # version of the migration that finalized this BBM

View File

@ -0,0 +1,8 @@
---
migration_job_name: BackfillGoogleInstanceAuditEventDestinationsFixed
description: Fixed version of BackfillGoogleInstanceAuditEventDestinations BBM
feature_category: audit_events
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/186866
milestone: '18.0'
queued_migration_version: 20250403155815
finalized_by: # version of the migration that finalized this BBM

View File

@ -0,0 +1,24 @@
# frozen_string_literal: true
class AddGroupSettingsToApplicationSettings < Gitlab::Database::Migration[2.2]
milestone '18.0'
disable_ddl_transaction!
CONSTRAINT_NAME = 'check_application_settings_group_settings_is_hash'
def up
with_lock_retries do
add_column :application_settings, :group_settings, :jsonb, default: {}, null: false
end
add_check_constraint :application_settings, "(jsonb_typeof(group_settings) = 'object')", CONSTRAINT_NAME
end
def down
remove_check_constraint :application_settings, CONSTRAINT_NAME
with_lock_retries do
remove_column :application_settings, :group_settings
end
end
end

View File

@ -0,0 +1,13 @@
# frozen_string_literal: true
class RemoveIndexWatermarkChangedEventWorker < Gitlab::Database::Migration[2.2]
milestone '18.0'
disable_ddl_transaction!
DEPRECATED_JOB_CLASSES = %w[Search::Zoekt::IndexWatermarkChangedEventWorker]
def up
sidekiq_remove_jobs(job_klasses: DEPRECATED_JOB_CLASSES)
end
def down; end
end

View File

@ -11,17 +11,9 @@ class QueueBackfillExternalGroupAuditEventDestinations < Gitlab::Database::Migra
SUB_BATCH_SIZE = 100
def up
queue_batched_background_migration(
MIGRATION,
:audit_events_external_audit_event_destinations,
:id,
job_interval: DELAY_INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
# no-op because there was a bug in the original migration (double JSON encoding),
# which has been fixed by QueueBackfillExternalGroupAuditEventDestinationsFixed
end
def down
delete_batched_background_migration(MIGRATION, :audit_events_external_audit_event_destinations, :id, [])
end
def down; end
end

View File

@ -11,17 +11,9 @@ class QueueBackfillAmazonGroupAuditEventDestinations < Gitlab::Database::Migrati
SUB_BATCH_SIZE = 100
def up
queue_batched_background_migration(
MIGRATION,
:audit_events_amazon_s3_configurations,
:id,
job_interval: DELAY_INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
# no-op because there was a bug in the original migration (double JSON encoding),
# which has been fixed by QueueBackfillAmazonGroupAuditEventDestinationsFixed
end
def down
delete_batched_background_migration(MIGRATION, :audit_events_amazon_s3_configurations, :id, [])
end
def down; end
end

View File

@ -11,17 +11,9 @@ class QueueBackfillAmazonInstanceAuditEventDestinations < Gitlab::Database::Migr
SUB_BATCH_SIZE = 100
def up
queue_batched_background_migration(
MIGRATION,
:audit_events_instance_amazon_s3_configurations,
:id,
job_interval: DELAY_INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
# no-op because there was a bug in the original migration (double JSON encoding),
# which has been fixed by QueueBackfillAmazonInstanceAuditEventDestinationsFixed
end
def down
delete_batched_background_migration(MIGRATION, :audit_events_instance_amazon_s3_configurations, :id, [])
end
def down; end
end

View File

@ -11,17 +11,9 @@ class QueueBackfillGoogleInstanceAuditEventDestinations < Gitlab::Database::Migr
SUB_BATCH_SIZE = 100
def up
queue_batched_background_migration(
MIGRATION,
:audit_events_instance_google_cloud_logging_configurations,
:id,
job_interval: DELAY_INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
# no-op because there was a bug in the original migration (double JSON encoding),
# which has been fixed by BackfillGoogleInstanceAuditEventDestinationsFixed
end
def down
delete_batched_background_migration(MIGRATION, :audit_events_instance_google_cloud_logging_configurations, :id, [])
end
def down; end
end

View File

@ -11,17 +11,9 @@ class QueueBackfillExternalInstanceAuditEventDestinations < Gitlab::Database::Mi
SUB_BATCH_SIZE = 100
def up
queue_batched_background_migration(
MIGRATION,
:audit_events_instance_external_audit_event_destinations,
:id,
job_interval: DELAY_INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
# no-op because there was a bug in the original migration (double JSON encoding),
# which has been fixed by BackfillExternalInstanceAuditEventDestinationsFixed
end
def down
delete_batched_background_migration(MIGRATION, :audit_events_instance_external_audit_event_destinations, :id, [])
end
def down; end
end

View File

@ -11,17 +11,9 @@ class QueueBackfillGoogleGroupAuditEventDestinations < Gitlab::Database::Migrati
SUB_BATCH_SIZE = 100
def up
queue_batched_background_migration(
MIGRATION,
:audit_events_google_cloud_logging_configurations,
:id,
job_interval: DELAY_INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
# no-op because there was a bug in the original migration (double JSON encoding),
# which has been fixed by BackfillGoogleGroupAuditEventDestinationsFixed
end
def down
delete_batched_background_migration(MIGRATION, :audit_events_google_cloud_logging_configurations, :id, [])
end
def down; end
end

View File

@ -0,0 +1,28 @@
# frozen_string_literal: true
class QueueBackfillExternalGroupAuditEventDestinationsFixed < Gitlab::Database::Migration[2.2]
milestone '18.0'
restrict_gitlab_migration gitlab_schema: :gitlab_main
ORIGINAL_MIGRATION = "BackfillExternalGroupAuditEventDestinations"
MIGRATION = "BackfillExternalGroupAuditEventDestinationsFixed"
BATCH_SIZE = 100
SUB_BATCH_SIZE = 10
def up
delete_batched_background_migration(ORIGINAL_MIGRATION, :audit_events_external_audit_event_destinations, :id, [])
queue_batched_background_migration(
MIGRATION,
:audit_events_external_audit_event_destinations,
:id,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
end
def down
delete_batched_background_migration(MIGRATION, :audit_events_external_audit_event_destinations, :id, [])
end
end

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
class QueueBackfillExternalInstanceAuditEventDestinationsFixed < Gitlab::Database::Migration[2.2]
milestone '18.0'
restrict_gitlab_migration gitlab_schema: :gitlab_main
ORIGINAL_MIGRATION = "BackfillExternalInstanceAuditEventDestinations"
MIGRATION = "BackfillExternalInstanceAuditEventDestinationsFixed"
BATCH_SIZE = 100
SUB_BATCH_SIZE = 10
def up
delete_batched_background_migration(ORIGINAL_MIGRATION, :audit_events_instance_external_audit_event_destinations,
:id, [])
queue_batched_background_migration(
MIGRATION,
:audit_events_instance_external_audit_event_destinations,
:id,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
end
def down
delete_batched_background_migration(MIGRATION, :audit_events_instance_external_audit_event_destinations, :id, [])
end
end

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
class QueueBackfillAmazonGroupAuditEventDestinationsFixed < Gitlab::Database::Migration[2.2]
milestone '18.0'
restrict_gitlab_migration gitlab_schema: :gitlab_main
ORIGINAL_MIGRATION = "BackfillAmazonGroupAuditEventDestinations"
MIGRATION = "BackfillAmazonGroupAuditEventDestinationsFixed"
BATCH_SIZE = 100
SUB_BATCH_SIZE = 10
def up
delete_batched_background_migration(ORIGINAL_MIGRATION, :audit_events_amazon_s3_configurations,
:id, [])
queue_batched_background_migration(
MIGRATION,
:audit_events_amazon_s3_configurations,
:id,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
end
def down
delete_batched_background_migration(MIGRATION, :audit_events_amazon_s3_configurations, :id, [])
end
end

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
class QueueBackfillAmazonInstanceAuditEventDestinationsFixed < Gitlab::Database::Migration[2.2]
milestone '18.0'
restrict_gitlab_migration gitlab_schema: :gitlab_main
ORIGINAL_MIGRATION = "BackfillAmazonInstanceAuditEventDestinations"
MIGRATION = "BackfillAmazonInstanceAuditEventDestinationsFixed"
BATCH_SIZE = 100
SUB_BATCH_SIZE = 10
def up
delete_batched_background_migration(ORIGINAL_MIGRATION, :audit_events_instance_amazon_s3_configurations,
:id, [])
queue_batched_background_migration(
MIGRATION,
:audit_events_instance_amazon_s3_configurations,
:id,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
end
def down
delete_batched_background_migration(MIGRATION, :audit_events_instance_amazon_s3_configurations, :id, [])
end
end

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
class QueueBackfillGoogleGroupAuditEventDestinationsFixed < Gitlab::Database::Migration[2.2]
milestone '18.0'
restrict_gitlab_migration gitlab_schema: :gitlab_main
ORIGINAL_MIGRATION = "BackfillGoogleGroupAuditEventDestinations"
MIGRATION = "BackfillGoogleGroupAuditEventDestinationsFixed"
BATCH_SIZE = 100
SUB_BATCH_SIZE = 10
def up
delete_batched_background_migration(ORIGINAL_MIGRATION, :audit_events_google_cloud_logging_configurations,
:id, [])
queue_batched_background_migration(
MIGRATION,
:audit_events_google_cloud_logging_configurations,
:id,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
end
def down
delete_batched_background_migration(MIGRATION, :audit_events_google_cloud_logging_configurations, :id, [])
end
end

View File

@ -0,0 +1,29 @@
# frozen_string_literal: true
class QueueBackfillGoogleInstanceAuditEventDestinationsFixed < Gitlab::Database::Migration[2.2]
milestone '18.0'
restrict_gitlab_migration gitlab_schema: :gitlab_main
ORIGINAL_MIGRATION = "BackfillGoogleInstanceAuditEventDestinations"
MIGRATION = "BackfillGoogleInstanceAuditEventDestinationsFixed"
BATCH_SIZE = 100
SUB_BATCH_SIZE = 10
def up
delete_batched_background_migration(ORIGINAL_MIGRATION, :audit_events_instance_google_cloud_logging_configurations,
:id, [])
queue_batched_background_migration(
MIGRATION,
:audit_events_instance_google_cloud_logging_configurations,
:id,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
end
def down
delete_batched_background_migration(MIGRATION, :audit_events_instance_google_cloud_logging_configurations, :id, [])
end
end

View File

@ -0,0 +1 @@
d8f12561559be060a125b7dd9571fe58f648cbb6dd9a7762867a634f900cfb87

View File

@ -0,0 +1 @@
737a0cca0456a39337177ac0edd90f15572ff3a96653c42f6540e06c60d1a0b7

View File

@ -0,0 +1 @@
e7d2c3264b4054cbd3f84dd9033fbddde33a6739878d956324c9a47debdb232d

View File

@ -0,0 +1 @@
b6645fd33972bc8e90d414fe57f64c00bec5be3b17bbb897ab46bc924ce4b0e5

View File

@ -0,0 +1 @@
3cd21442de47941d55da39188bc0fa29bde9ea36dce1efdf4963827b632bd166

View File

@ -0,0 +1 @@
a52b95ce6dd19c9249a06e1c60c04c13d9c10a31de8b2a3cd289f6a0cfce1473

View File

@ -0,0 +1 @@
175f392feadd6f457d887086267f7ac5c0cdbf3c934c76ef2eb5df37d64a5735

View File

@ -0,0 +1 @@
c037a0cbc72686ff14b2035651ad90f7188bafc100f113f5930a8795671b2b95

View File

@ -9185,6 +9185,7 @@ CREATE TABLE application_settings (
duo_nano_features_enabled boolean,
database_reindexing jsonb DEFAULT '{}'::jsonb NOT NULL,
duo_chat jsonb DEFAULT '{}'::jsonb NOT NULL,
group_settings jsonb DEFAULT '{}'::jsonb NOT NULL,
CONSTRAINT app_settings_container_reg_cleanup_tags_max_list_size_positive CHECK ((container_registry_cleanup_tags_service_max_list_size >= 0)),
CONSTRAINT app_settings_dep_proxy_ttl_policies_worker_capacity_positive CHECK ((dependency_proxy_ttl_group_policy_worker_capacity >= 0)),
CONSTRAINT app_settings_ext_pipeline_validation_service_url_text_limit CHECK ((char_length(external_pipeline_validation_service_url) <= 255)),
@ -9241,6 +9242,7 @@ CREATE TABLE application_settings (
CONSTRAINT check_application_settings_duo_chat_is_hash CHECK ((jsonb_typeof(duo_chat) = 'object'::text)),
CONSTRAINT check_application_settings_duo_workflow_is_hash CHECK ((jsonb_typeof(duo_workflow) = 'object'::text)),
CONSTRAINT check_application_settings_elasticsearch_is_hash CHECK ((jsonb_typeof(elasticsearch) = 'object'::text)),
CONSTRAINT check_application_settings_group_settings_is_hash CHECK ((jsonb_typeof(group_settings) = 'object'::text)),
CONSTRAINT check_application_settings_importers_is_hash CHECK ((jsonb_typeof(importers) = 'object'::text)),
CONSTRAINT check_application_settings_integrations_is_hash CHECK ((jsonb_typeof(integrations) = 'object'::text)),
CONSTRAINT check_application_settings_o11y_settings_is_hash CHECK ((jsonb_typeof(observability_settings) = 'object'::text)),

View File

@ -36,7 +36,8 @@ GET /projects/:id/dependencies?package_manager=yarn,bundler
| `package_manager` | string array | no | Returns dependencies belonging to specified package manager. Valid values: `bundler`, `composer`, `conan`, `go`, `gradle`, `maven`, `npm`, `nuget`, `pip`, `pipenv`, `pnpm`, `yarn`, `sbt`, or `setuptools`. |
```shell
curl --header "PRIVATE-TOKEN: <your_access_token>" "https://gitlab.example.com/api/v4/projects/4/dependencies"
curl --header "PRIVATE-TOKEN: <your_access_token>" \
--url "https://gitlab.example.com/api/v4/projects/4/dependencies"
```
Example response:

View File

@ -20979,7 +20979,6 @@ Requires ClickHouse. Premium and Ultimate with GitLab Duo Pro and Enterprise onl
| <a id="aimetricscodesuggestionsshowncount"></a>`codeSuggestionsShownCount` | [`Int`](#int) | Total count of code suggestions shown to code contributors. |
| <a id="aimetricsduoassigneduserscount"></a>`duoAssignedUsersCount` | [`Int`](#int) | Total assigned Duo Pro and Enterprise seats. Ignores time period filter. Returns current data. |
| <a id="aimetricsduochatcontributorscount"></a>`duoChatContributorsCount` | [`Int`](#int) | Number of contributors who used GitLab Duo Chat features. |
| <a id="aimetricsduoproassigneduserscount"></a>`duoProAssignedUsersCount` {{< icon name="warning-solid" >}} | [`Int`](#int) | **Deprecated** in GitLab 17.6. use duoAssignedUsersCount for the same behavior. |
| <a id="aimetricsduousedcount"></a>`duoUsedCount` | [`Int`](#int) | Number of contributors who used any GitLab Duo feature. |
| <a id="aimetricsrootcauseanalysisuserscount"></a>`rootCauseAnalysisUsersCount` | [`Int`](#int) | Number of users using troubleshoot within a failed pipeline. |

View File

@ -43671,10 +43671,10 @@ definitions:
type: string
repository_storage:
type: string
duo_base_features_enabled:
duo_core_features_enabled:
type: boolean
description: "[Experimental] Indicates whether GitLab Duo features are enabled
for the group"
description: "[Experimental] Indicates whether GitLab Duo Core features are
enabled for the group"
duo_features_enabled:
type: string
lock_duo_features_enabled:
@ -44201,10 +44201,10 @@ definitions:
service_access_tokens_expiration_enforced:
type: boolean
description: To enforce token expiration for Service accounts users for group
duo_base_features_enabled:
duo_core_features_enabled:
type: boolean
description: "[Experimental] Indicates whether GitLab Duo features are enabled
for the group"
description: "[Experimental] Indicates whether GitLab Duo Core features are
enabled for the group"
duo_features_enabled:
type: boolean
description: Indicates whether GitLab Duo features are enabled for the group
@ -44320,10 +44320,10 @@ definitions:
type: string
repository_storage:
type: string
duo_base_features_enabled:
duo_core_features_enabled:
type: boolean
description: "[Experimental] Indicates whether GitLab Duo features are enabled
for the group"
description: "[Experimental] Indicates whether GitLab Duo Core features are
enabled for the group"
duo_features_enabled:
type: string
lock_duo_features_enabled:

View File

@ -164,7 +164,8 @@ Example response:
"concurrent_github_import_jobs_limit": 1000,
"concurrent_bitbucket_import_jobs_limit": 100,
"concurrent_bitbucket_server_import_jobs_limit": 100,
"silent_admin_exports_enabled": false
"silent_admin_exports_enabled": false,
"top_level_group_creation_enabled": true
}
```
@ -755,6 +756,7 @@ to configure other related settings. These requirements are
| `throttle_unauthenticated_web_period_in_seconds` | integer | required by:<br>`throttle_unauthenticated_web_enabled` | Rate limit period in seconds. |
| `throttle_unauthenticated_web_requests_per_period` | integer | required by:<br>`throttle_unauthenticated_web_enabled` | Max requests per period per IP. |
| `time_tracking_limit_to_hours` | boolean | no | Limit display of time tracking units to hours. Default is `false`. |
| `top_level_group_creation_enabled` | boolean | no | Allows a user to create top-level-groups. Default is `true`. |
| `two_factor_grace_period` | integer | required by: `require_two_factor_authentication` | Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication. |
| `unconfirmed_users_delete_after_days` | integer | no | Specifies how many days after sign-up to delete users who have not confirmed their email. Only applicable if `delete_unconfirmed_users` is set to `true`. Must be `1` or greater. Default is `7`. [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/352514) in GitLab 16.1. GitLab Self-Managed, Premium and Ultimate only. |
| `unique_ips_limit_enabled` | boolean | no | (**If enabled, requires:** `unique_ips_limit_per_user` and `unique_ips_limit_time_window`) Limit sign in from multiple IPs. |

View File

@ -179,9 +179,10 @@ runUntagged: true
protected: true
```
The `runnerRegistrationToken` field replaces the `runnerToken` field. For GitLab Runner on Kubernetes, Helm deploy passes the runner `authentication token` to the runner worker pod and creates the runner configuration. In GitLab 17.0, if Kubernetes hosted runners attached to GitLab.com use `runnerRegistrationToken`, the runner worker pod uses an unsupported Registration API method at creation.
For GitLab Runner on Kubernetes, Helm deploy passes the runner authentication token to the runner worker pod and creates the runner configuration.
In GitLab 17.0 and later, if you use the `runnerRegistrationToken` token field on Kubernetes hosted runners attached to GitLab.com, the runner worker pod tries to use the unsupported Registration API method during creation.
If you store the runner authentication token in `secrets`, you must also modify them.
Replace the invalid `runnerRegistrationToken` field with the `runnerToken` field. You must also modify the runner authentication token stored in `secrets`.
In the legacy runner registration workflow, fields were specified with:

View File

@ -14,12 +14,12 @@ title: Application Settings analysis
## Statistics
- Number of attributes: 495
- Number of attributes: 497
- Number of encrypted attributes: 41 (8.0%)
- Number of attributes documented: 298 (60.0%)
- Number of attributes on GitLab.com different from the defaults: 222 (45.0%)
- Number of attributes with `clusterwide` set: 495 (100.0%)
- Number of attributes with `clusterwide: true` set: 126 (25.0%)
- Number of attributes with `clusterwide` set: 497 (100.0%)
- Number of attributes with `clusterwide: true` set: 128 (26.0%)
## Individual columns
@ -66,7 +66,7 @@ title: Application Settings analysis
| `can_create_group` | `false` | `boolean` | `boolean` | `true` | `true` | `false` | `false`| `true` |
| `can_create_organization` | `false` | `boolean` | `` | `true` | `true` | `false` | `false`| `false` |
| `check_namespace_plan` | `false` | `boolean` | `boolean` | `true` | `false` | `true` | `true`| `true` |
| `ci_cd_settings` | `false` | `jsonb` | `` | `true` | `'{}'::jsonb` | `false` | `true`| `false` |
| `ci_cd_settings` | `false` | `jsonb` | `` | `true` | `'{}'::jsonb` | `false` | `false`| `false` |
| `ci_job_token_signing_key` | `true` | `bytea` | `` | `false` | `null` | `true` | `true`| `false` |
| `ci_jwt_signing_key` | `true` | `text` | `` | `false` | `null` | `true` | `true`| `false` |
| `ci_max_includes` | `false` | `integer` | `integer` | `true` | `150` | `false` | `false`| `true` |
@ -147,8 +147,9 @@ title: Application Settings analysis
| `domain_denylist` | `false` | `text` | `array of strings` | `false` | `null` | `true` | `true`| `true` |
| `domain_denylist_enabled` | `false` | `boolean` | `boolean` | `false` | `false` | `true` | `true`| `true` |
| `dsa_key_restriction` | `false` | `integer` | `integer` | `true` | `'-1'::integer` | `false` | `false`| `true` |
| `duo_chat` | `false` | `jsonb` | `` | `true` | `'{}'::jsonb` | `true` | `true`| `false` |
| `duo_chat` | `false` | `jsonb` | `` | `true` | `'{}'::jsonb` | `false` | `true`| `false` |
| `duo_features_enabled` | `false` | `boolean` | `boolean` | `true` | `true` | `false` | `false`| `true` |
| `duo_nano_features_enabled` | `false` | `boolean` | `` | `false` | `null` | `false` | `true`| `false` |
| `duo_workflow` | `false` | `jsonb` | `` | `false` | `'{}'::jsonb` | `true` | `true`| `false` |
| `ecdsa_key_restriction` | `false` | `integer` | `integer` | `true` | `0` | `false` | `false`| `true` |
| `ecdsa_sk_key_restriction` | `false` | `integer` | `integer` | `true` | `0` | `false` | `false`| `true` |
@ -216,6 +217,7 @@ title: Application Settings analysis
| `group_import_limit` | `false` | `integer` | `` | `true` | `6` | `false` | `false`| `false` |
| `group_owners_can_manage_default_branch_protection` | `false` | `boolean` | `boolean` | `true` | `true` | `false` | `false`| `true` |
| `group_runner_token_expiration_interval` | `false` | `integer` | `integer` | `false` | `null` | `false` | `false`| `true` |
| `group_settings` | `false` | `jsonb` | `` | `true` | `'{}'::jsonb` | `false` | `true`| `false` |
| `hashed_storage_enabled` | `false` | `boolean` | `boolean` | `true` | `true` | `false` | `false`| `true` |
| `health_check_access_token` | `false` | `character` | `` | `false` | `null` | `true` | `true`| `false` |
| `help_page_documentation_base_url` | `false` | `text` | `` | `false` | `null` | `true` | `true`| `false` |

View File

@ -71,6 +71,167 @@ To fix this, set the appropriate certificate bundle path in the Docker container
Replace `/path/to/ca-bundle.pem` with the actual path to your certificate bundle.
## Docker-NGINX-SSL Setup
{{< alert type="note" >}}
This method of deploying NGINX or Caddy as a reverse proxy is a temporary workaround to support SSL
until [issue 455854](https://gitlab.com/gitlab-org/gitlab/-/issues/455854)
is implemented.
{{< /alert >}}
You can set up SSL for an AI gateway instance by using Docker,
NGINX as a reverse proxy, and Let's Encrypt for SSL certificates.
NGINX manages the secure connection with external clients, decrypting incoming HTTPS requests before
passing them to the AI Gateway.
Prerequisites:
- Docker and Docker Compose installed
- Registered and configured domain name
### Step 1: Create Configuration Files
Create the following files in your working directory:
1. `nginx.conf`:
```nginx
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
```
1. `default.conf`:
```nginx
# nginx/conf.d/default.conf
server {
listen 80;
server_name _;
# Forward all requests to the AI Gateway
location / {
proxy_pass http://gitlab-ai-gateway:5052;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
proxy_buffering off;
}
}
server {
listen 443 ssl;
server_name _;
# SSL configuration
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
# Configuration for self-signed certificates
ssl_verify_client off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
# Proxy headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# WebSocket support (if needed)
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Forward all requests to the AI Gateway
location / {
proxy_pass http://gitlab-ai-gateway:5052;
proxy_read_timeout 300s;
proxy_connect_timeout 75s;
proxy_buffering off;
}
}
```
### Step 2: SSL Certificate setup using Let's Encrypt
- For Docker-based NGINX servers, Certbot provides an automated way to implement Let's Encrypt certificates -
see the [guide here](https://phoenixnap.com/kb/letsencrypt-docker).
- Alternatively, you can use [Certbot's manual installation](https://eff-certbot.readthedocs.io/en/stable/using.html#manual)
process if you prefer that approach.
### Step 3: Create Docker-compose file
1. `docker-compose.yaml`:
```yaml
version: '3.8'
services:
nginx-proxy:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- /path/to/nginx.conf:/etc/nginx/nginx.conf:ro
- /path/to/default.conf:/etc/nginx/conf.d/default.conf:ro
- /path/to/fullchain.pem:/etc/nginx/ssl/server.crt:ro
- /path/to/privkey.pem:/etc/nginx/ssl/server.key:ro
networks:
- proxy-network
depends_on:
- gitlab-ai-gateway
gitlab-ai-gateway:
image: registry.gitlab.com/gitlab-org/modelops/applied-ml/code-suggestions/ai-assist/model-gateway:<ai-gateway-tag>
expose:
- "5052"
environment:
- AIGW_GITLAB_URL=<your_gitlab_instance>
- AIGW_GITLAB_API_URL=https://<your_gitlab_domain>/api/v4/
networks:
- proxy-network
restart: always
networks:
proxy-network:
driver: bridge
```
### Step 4: Deployment and validation
1. Start the `nginx` and `AIGW` containers and verify if they're running:
```shell
docker-compose up
docker ps
```
1. Configure your [GitLab instance to access the AI gateway](../administration/gitlab_duo_self_hosted/configure_duo_features.md#configure-your-gitlab-instance-to-access-the-ai-gateway).
1. Perform the health check and confirm that the AI gateway is accessible.
## Install using the AI gateway Helm chart
Prerequisites:

View File

@ -12,6 +12,12 @@ title: SAML SSO for GitLab Self-Managed
{{< /details >}}
{{< alert type="note" >}}
For GitLab.com, see [SAML SSO for GitLab.com groups](../user/group/saml_sso/_index.md).
{{< /alert >}}
This page describes how to set up instance-wide SAML single sign on (SSO) for
GitLab Self-Managed.
@ -19,8 +25,6 @@ You can configure GitLab to act as a SAML service provider (SP). This allows
GitLab to consume assertions from a SAML identity provider (IdP), such as
Okta, to authenticate users.
To set up SAML on GitLab.com, see [SAML SSO for GitLab.com groups](../user/group/saml_sso/_index.md).
For more information on:
- OmniAuth provider settings, see the [OmniAuth documentation](omniauth.md).

View File

@ -88,7 +88,7 @@ When running in this method, you provide a container image that has the required
```yaml
api_discovery:
extends: .api_discovery_java_spring_boot
image: openjdk:11-jre-slim
image: eclipse-temurin:17-jre-alpine
```
1. Provide the Java class path needed by your application. This includes your compatible build
@ -99,24 +99,24 @@ When running in this method, you provide a container image that has the required
```yaml
api_discovery:
extends: .api_discovery_java_spring_boot
image: openjdk:11-jre-slim
image: eclipse-temurin:17-jre-alpine
variables:
API_DISCOVERY_JAVA_CLASSPATH: build/libs/spring-boot-app-0.0.0.jar
```
1. Optional. If the image provided is missing a dependency needed by API Discovery, it can be added
using a `before_script`. In this example, the `openjdk:11-jre-slim` container doesn't include
using a `before_script`. In this example, the `eclipse-temurin:17-jre-alpine` container doesn't include
`curl` which is required by API Discovery. The dependency can be installed using the Debian
package manager `apt`:
```yaml
api_discovery:
extends: .api_discovery_java_spring_boot
image: openjdk:11-jre-slim
image: eclipse-temurin:17-jre-alpine
variables:
API_DISCOVERY_JAVA_CLASSPATH: build/libs/spring-boot-app-0.0.0.jar
before_script:
- apt-get update && apt-get install -y curl
- apk add --no-cache curl
```
1. Optional. If the image provided doesn't automatically set the `JAVA_HOME` environment variable,
@ -125,7 +125,7 @@ When running in this method, you provide a container image that has the required
```yaml
api_discovery:
extends: .api_discovery_java_spring_boot
image: openjdk:11-jre-slim
image: eclipse-temurin:17-jre-alpine
variables:
API_DISCOVERY_JAVA_CLASSPATH: build/libs/spring-boot-app-0.0.0.jar
API_DISCOVERY_JAVA_HOME: /opt/java
@ -141,7 +141,7 @@ When running in this method, you provide a container image that has the required
```yaml
api_discovery:
extends: .api_discovery_java_spring_boot
image: openjdk:8-jre-alpine
image: eclipse-temurin:17-jre-alpine
variables:
API_DISCOVERY_JAVA_CLASSPATH: build/libs/spring-boot-app-0.0.0.jar
API_DISCOVERY_PACKAGE_TOKEN: $GITLAB_READ_TOKEN
@ -182,8 +182,8 @@ When experiencing a behavior not working as expected, consider providing context
- GitLab version if using a GitLab Self-Managed instance.
- `.gitlab-ci.yml` job definition.
- Full job console output.
- Framework in use with version (for example Spring Boot v2.3.2).
- Language runtime with version (for example OpenJDK v17.0.1).
- Framework in use with version (for example "Spring Boot v2.3.2").
- Language runtime with version (for example "Eclipse Temurin v17.0.1").
<!-- - Scanner log file is available as a job artifact named `gl-api-discovery.log`. -->
{{< alert type="warning" >}}

View File

@ -57,7 +57,13 @@ To confirm that you can connect to the Workflow service:
1. In the address bar, enter `https://duo-workflow.runway.gitlab.net/DuoWorkflow/ExecuteWorkflow`.
1. Ensure the request was successful and the **Protocol** column includes `h2` in Chrome or `HTTP/2` in Firefox.
If the request fails, your network might be blocking the connection.
If the request fails or does not show the HTTP/2 protocol:
- A security system like Netskope or Zscaler might be configured to block or inspect traffic.
- The HTTP/2 protocol downgrades to HTTP/1.1, which prevents Duo Workflow from working correctly.
To correct this issue, ask your network administrator to put `https://duo-workflow.runway.gitlab.net/DuoWorkflow/ExecuteWorkflow`
on the correct allowlist, or to exempt it from traffic inspection.
## Docker setup

View File

@ -386,6 +386,10 @@ GitLab.com sets these requirements for passwords on new accounts and password ch
- All characters are accepted. For example, `~`, `!`, `@`, `#`, `$`, `%`, `^`, `&`, `*`, `()`,
`[]`, `_`, `+`, `=`, and `-`.
## Group creation
On GitLab.com, [top-level group creation](../../api/groups.md#create-a-group) is not available through the API. It must be performed through the UI.
## Project and group deletion
Settings related to the deletion of projects and groups.

View File

@ -12,6 +12,12 @@ title: SAML SSO for GitLab.com groups
{{< /details >}}
{{< alert type="note" >}}
For GitLab Self-Managed, see [SAML SSO for GitLab Self-Managed](../../../integration/saml.md).
{{< /alert >}}
Users can sign in to GitLab through their SAML identity provider.
[SCIM](scim_setup.md) synchronizes users with the group on GitLab.com.

View File

@ -79,6 +79,17 @@ module API
options[type] = { issuable_metadata: Gitlab::IssuableMetadata.new(current_user, targets).data, include_subscribed: false }
end
end
def track_bot_user
track_event(
"request_todos_by_bot_user",
user: current_user,
additional_properties: {
label: 'user_type',
property: current_user.user_type
}
)
end
end
desc 'Get a list of to-do items' do
@ -90,6 +101,7 @@ module API
get do
Gitlab::QueryLimiting.disable!('https://gitlab.com/gitlab-org/gitlab/-/issues/408576')
track_bot_user if current_user.bot?
todos = paginate(find_todos.with_entity_associations)
todos = ::Todos::AllowedTargetFilterService.new(todos, current_user).execute
options = { with: Entities::Todo, current_user: current_user }

View File

@ -5,9 +5,7 @@ module Gitlab
class BackfillAmazonGroupAuditEventDestinations < BatchedMigrationJob
feature_category :audit_events
def perform
# CE implementation is a no-op
end
def perform; end
end
end
end

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
class BackfillAmazonGroupAuditEventDestinationsFixed < BatchedMigrationJob
feature_category :audit_events
def perform
# This batched background migration is EE-only,
# see ee/lib/gitlab/background_migration/backfill_amazon_group_audit_event_destinations_fixed.rb for
# the actual migration code.
end
end
end
end
Gitlab::BackgroundMigration::BackfillAmazonGroupAuditEventDestinationsFixed.prepend_mod

View File

@ -5,9 +5,7 @@ module Gitlab
class BackfillAmazonInstanceAuditEventDestinations < BatchedMigrationJob
feature_category :audit_events
def perform
# CE implementation is a no-op
end
def perform; end
end
end
end

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
class BackfillAmazonInstanceAuditEventDestinationsFixed < BatchedMigrationJob
feature_category :audit_events
def perform
# This batched background migration is EE-only,
# see ee/lib/gitlab/background_migration/backfill_amazon_instance_audit_event_destinations_fixed.rb for
# the actual migration code.
end
end
end
end
Gitlab::BackgroundMigration::BackfillAmazonInstanceAuditEventDestinationsFixed.prepend_mod

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
class BackfillExternalGroupAuditEventDestinationsFixed < BatchedMigrationJob
feature_category :audit_events
def perform
# This batched background migration is EE-only,
# see ee/lib/gitlab/background_migration/backfill_external_group_audit_event_destinations_fixed.rb for
# the actual migration code.
end
end
end
end
Gitlab::BackgroundMigration::BackfillExternalGroupAuditEventDestinationsFixed.prepend_mod

View File

@ -5,9 +5,7 @@ module Gitlab
class BackfillExternalInstanceAuditEventDestinations < BatchedMigrationJob
feature_category :audit_events
def perform
# no-op, EE only migration
end
def perform; end
end
end
end

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
class BackfillExternalInstanceAuditEventDestinationsFixed < BatchedMigrationJob
feature_category :audit_events
def perform
# This batched background migration is EE-only,
# see ee/lib/gitlab/background_migration/backfill_external_instance_audit_event_destinations_fixed.rb for
# the actual migration code.
end
end
end
end
Gitlab::BackgroundMigration::BackfillExternalInstanceAuditEventDestinationsFixed.prepend_mod

View File

@ -5,9 +5,7 @@ module Gitlab
class BackfillGoogleGroupAuditEventDestinations < BatchedMigrationJob
feature_category :audit_events
def perform
# no-op, EE only migration
end
def perform; end
end
end
end

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
class BackfillGoogleGroupAuditEventDestinationsFixed < BatchedMigrationJob
feature_category :audit_events
def perform
# This batched background migration is EE-only,
# see ee/lib/gitlab/background_migration/backfill_google_group_audit_event_destinations_fixed.rb for
# the actual migration code.
end
end
end
end
Gitlab::BackgroundMigration::BackfillGoogleGroupAuditEventDestinationsFixed.prepend_mod

View File

@ -5,9 +5,7 @@ module Gitlab
class BackfillGoogleInstanceAuditEventDestinations < BatchedMigrationJob
feature_category :audit_events
def perform
# no-op, EE only migration
end
def perform; end
end
end
end

View File

@ -0,0 +1,17 @@
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
class BackfillGoogleInstanceAuditEventDestinationsFixed < BatchedMigrationJob
feature_category :audit_events
def perform
# This batched background migration is EE-only,
# see ee/lib/gitlab/background_migration/backfill_google_instance_audit_event_destinations_fixed.rb for
# the actual migration code.
end
end
end
end
Gitlab::BackgroundMigration::BackfillGoogleInstanceAuditEventDestinationsFixed.prepend_mod

View File

@ -31,8 +31,10 @@ module Gitlab
def manual_job_action_message
if subject.retryable?
_("You can modify this job's CI/CD variables before running it again.")
elsif can?(user, :set_pipeline_variables, subject.project)
_('This job does not start automatically and must be started manually. You can add CI/CD variables below for last-minute configuration changes before starting the job.')
else
_('This job does not start automatically and must be started manually.')
_("This job does not start automatically and must be started manually.")
end
end

View File

@ -51,17 +51,25 @@ variables:
- gl-api-discovery-openapi.json
- gl-*.log
rules:
- if: $API_DISCOVERY_DISABLED
- if: $API_DISCOVERY_DISABLED == 'true' || $API_DISCOVERY_DISABLED == '1'
when: never
- if: $API_DISCOVERY_DISABLED_FOR_DEFAULT_BRANCH &&
- if: $API_DISCOVERY_DISABLED_FOR_DEFAULT_BRANCH == 'true' &&
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
when: never
# Add the job to merge request pipelines if there's an open merge request.
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
# Don't add it to a *branch* pipeline if it's already in a merge request pipeline.
- if: $CI_OPEN_MERGE_REQUESTS
- if: $API_DISCOVERY_DISABLED_FOR_DEFAULT_BRANCH == '1' &&
$CI_DEFAULT_BRANCH == $CI_COMMIT_REF_NAME
when: never
# Add the job to branch pipelines.
# The following 3 blocks of rules define whether the job runs in a an *MR pipeline* or a *branch pipeline*
# when an MR exists. If the job has additional rules to observe they should be added in the blocks 1 and 3
# to cover both the *MR pipeline* and the *branch pipeline* workflows.
# 1. Run the job in an *MR* pipeline if MR pipelines for AST are enabled and there's an open merge request.
- if: $AST_ENABLE_MR_PIPELINES == "true" &&
$CI_PIPELINE_SOURCE == "merge_request_event"
# 2. Don't run the job in a *branch pipeline* if *MR pipelines* for AST are enabled and there's an open merge request.
- if: $AST_ENABLE_MR_PIPELINES == "true" &&
$CI_OPEN_MERGE_REQUESTS
when: never
# 3. Finally, run the job in a *branch pipeline* (When MR pipelines are disabled for AST, or it is enabled but no open MRs exist for the branch).
- if: $CI_COMMIT_BRANCH

View File

@ -13017,9 +13017,6 @@ msgstr ""
msgid "CiVariables|What are pipeline variables?"
msgstr ""
msgid "CiVariables|You can add CI/CD variables below for last-minute configuration changes before starting the job."
msgstr ""
msgid "CiVariables|You can use CI/CD variables with the same name in different places, but the variables might overwrite each other. %{linkStart}What is the order of precedence for variables?%{linkEnd}"
msgstr ""
@ -54997,6 +54994,9 @@ msgstr ""
msgid "SecurityOrchestration|Security policy projects store your organization's security policies. They are identified when policies are created, or when a project is linked as a security policy project. %{linkStart}Learn more%{linkEnd}."
msgstr ""
msgid "SecurityOrchestration|Select a cadence"
msgstr ""
msgid "SecurityOrchestration|Select a project to store your security policies in. %{linkStart}More information.%{linkEnd}"
msgstr ""
@ -61796,6 +61796,9 @@ msgstr ""
msgid "This job does not start automatically and must be started manually."
msgstr ""
msgid "This job does not start automatically and must be started manually. You can add CI/CD variables below for last-minute configuration changes before starting the job."
msgstr ""
msgid "This job has been canceled"
msgstr ""
@ -64716,18 +64719,9 @@ msgstr ""
msgid "UsageQuota|Excess storage usage"
msgstr ""
msgid "UsageQuota|Filter by runner"
msgstr ""
msgid "UsageQuota|Filter chart by year"
msgstr ""
msgid "UsageQuota|Filter charts by year"
msgstr ""
msgid "UsageQuota|Filter list by month"
msgstr ""
msgid "UsageQuota|Filter projects data by month"
msgstr ""
@ -68791,9 +68785,6 @@ msgstr ""
msgid "WorkItem|Options:"
msgstr ""
msgid "WorkItem|Parent"
msgstr ""
msgid "WorkItem|Parent item type %{parentWorkItemType} is not supported on %{workItemType}. Remove the parent item to change type."
msgstr ""

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