Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
b579182e26
commit
bf13bba8a2
|
|
@ -36,7 +36,9 @@ They are frequently updated, and everyone should make sure they are aware of the
|
|||
## EM/PM release post item checklist
|
||||
|
||||
- [ ] Set yourself as the Assignee, meaning you are the DRI.
|
||||
- [ ] If the deprecation is a [breaking change](https://handbook.gitlab.com/handbook/product/gitlab-the-product/#breaking-changes), add label `breaking change`.
|
||||
- [ ] For [breaking changes](https://handbook.gitlab.com/handbook/product/gitlab-the-product/#breaking-changes):
|
||||
- [ ] Add the `breaking change` label to the MR.
|
||||
- [ ] If the breaking change affects GitLab.com, add `window` with a value of `1`, `2`, or `3`. The value represents the planned release window for GitLab.com, typically in the three weeks before the major release date. You should intentionally plan this window ahead of time. If you're not sure, ask `@swiskow`.
|
||||
- [ ] Confirm this MR is labeled ~"release post item::deprecation"
|
||||
- [ ] Follow the process to [create a deprecation YAML file](https://handbook.gitlab.com/handbook/marketing/blog/release-posts/#creating-the-announcement).
|
||||
- [ ] Add reviewers by the 10th.
|
||||
|
|
|
|||
|
|
@ -229,7 +229,7 @@
|
|||
{"name":"gitlab-glfm-markdown","version":"0.0.21","platform":"ruby","checksum":"cb960ac1bc509d72b460c9dc934fb0a02cf061a5de6b1b00c72b794817d63b40"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.21","platform":"x86_64-darwin","checksum":"8425ee27e0b32b75619e08e1700c1302297b44928adc19a026bea243c96363f5"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.21","platform":"x86_64-linux","checksum":"9ea7d7a7a20c15960839521459a82edab787a4d8475ee412beba8362aa5fcd71"},
|
||||
{"name":"gitlab-kas-grpc","version":"17.5.0","platform":"ruby","checksum":"4b0af5619e3cc68d7293abb7dca96f5cab7d9700c42622e525e78d36d43a744c"},
|
||||
{"name":"gitlab-kas-grpc","version":"17.5.1","platform":"ruby","checksum":"88639bfaa9301d78a7fbff696ec262ed696a15a6f41c1b51bffe6b39c7a61ca7"},
|
||||
{"name":"gitlab-labkit","version":"0.36.1","platform":"ruby","checksum":"04fb6941b7e5fc1fdcee8f9971fa2086a4dc442e39e67a74b992403dd580c300"},
|
||||
{"name":"gitlab-license","version":"2.5.0","platform":"ruby","checksum":"4c166c469c2ad17876ca43188a4ccebe3feb0726c4c1770047f8dcef96573f4d"},
|
||||
{"name":"gitlab-mail_room","version":"0.0.25","platform":"ruby","checksum":"223ce7c3c0797b6015eaa37147884e6ddc7be9a7ee90a424358c96bc18613b1a"},
|
||||
|
|
|
|||
|
|
@ -739,7 +739,7 @@ GEM
|
|||
nokogiri (~> 1, >= 1.10.8)
|
||||
gitlab-glfm-markdown (0.0.21)
|
||||
rb_sys (= 0.9.94)
|
||||
gitlab-kas-grpc (17.5.0)
|
||||
gitlab-kas-grpc (17.5.1)
|
||||
grpc (~> 1.0)
|
||||
gitlab-labkit (0.36.1)
|
||||
actionpack (>= 5.0.0, < 8.0.0)
|
||||
|
|
|
|||
|
|
@ -230,7 +230,7 @@
|
|||
{"name":"gitlab-glfm-markdown","version":"0.0.21","platform":"ruby","checksum":"cb960ac1bc509d72b460c9dc934fb0a02cf061a5de6b1b00c72b794817d63b40"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.21","platform":"x86_64-darwin","checksum":"8425ee27e0b32b75619e08e1700c1302297b44928adc19a026bea243c96363f5"},
|
||||
{"name":"gitlab-glfm-markdown","version":"0.0.21","platform":"x86_64-linux","checksum":"9ea7d7a7a20c15960839521459a82edab787a4d8475ee412beba8362aa5fcd71"},
|
||||
{"name":"gitlab-kas-grpc","version":"17.5.0","platform":"ruby","checksum":"4b0af5619e3cc68d7293abb7dca96f5cab7d9700c42622e525e78d36d43a744c"},
|
||||
{"name":"gitlab-kas-grpc","version":"17.5.1","platform":"ruby","checksum":"88639bfaa9301d78a7fbff696ec262ed696a15a6f41c1b51bffe6b39c7a61ca7"},
|
||||
{"name":"gitlab-labkit","version":"0.36.1","platform":"ruby","checksum":"04fb6941b7e5fc1fdcee8f9971fa2086a4dc442e39e67a74b992403dd580c300"},
|
||||
{"name":"gitlab-license","version":"2.5.0","platform":"ruby","checksum":"4c166c469c2ad17876ca43188a4ccebe3feb0726c4c1770047f8dcef96573f4d"},
|
||||
{"name":"gitlab-mail_room","version":"0.0.25","platform":"ruby","checksum":"223ce7c3c0797b6015eaa37147884e6ddc7be9a7ee90a424358c96bc18613b1a"},
|
||||
|
|
|
|||
|
|
@ -749,7 +749,7 @@ GEM
|
|||
nokogiri (~> 1, >= 1.10.8)
|
||||
gitlab-glfm-markdown (0.0.21)
|
||||
rb_sys (= 0.9.94)
|
||||
gitlab-kas-grpc (17.5.0)
|
||||
gitlab-kas-grpc (17.5.1)
|
||||
grpc (~> 1.0)
|
||||
gitlab-labkit (0.36.1)
|
||||
actionpack (>= 5.0.0, < 8.0.0)
|
||||
|
|
|
|||
|
|
@ -400,6 +400,7 @@ export default {
|
|||
},
|
||||
submit() {
|
||||
this.$emit(this.isEditing ? 'update-variable' : 'add-variable', this.variableToEmit);
|
||||
this.$refs.drawer.$el.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
},
|
||||
trackVariableValidationErrors() {
|
||||
const property = this.getTrackingErrorProperty();
|
||||
|
|
@ -440,6 +441,7 @@ export default {
|
|||
<template>
|
||||
<div>
|
||||
<gl-drawer
|
||||
ref="drawer"
|
||||
open
|
||||
data-testid="ci-variable-drawer"
|
||||
:header-height="getDrawerHeaderHeight"
|
||||
|
|
@ -663,10 +665,9 @@ export default {
|
|||
>
|
||||
{{ $options.i18n.variableReferenceDescription }}
|
||||
</gl-alert>
|
||||
<div class="gl-flex">
|
||||
<div class="gl-mb-5 gl-flex gl-gap-3">
|
||||
<gl-button
|
||||
category="primary"
|
||||
class="gl-mr-3"
|
||||
variant="confirm"
|
||||
:disabled="!canSubmit"
|
||||
data-testid="ci-variable-confirm-button"
|
||||
|
|
@ -678,7 +679,6 @@ export default {
|
|||
v-gl-modal-directive="`delete-variable-${variable.key}`"
|
||||
variant="danger"
|
||||
category="secondary"
|
||||
class="gl-mr-3"
|
||||
data-testid="ci-variable-delete-button"
|
||||
>{{ $options.i18n.deleteVariable }}</gl-button
|
||||
>
|
||||
|
|
|
|||
|
|
@ -99,6 +99,7 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
ciVariables: [],
|
||||
environments: [],
|
||||
hasNextPage: false,
|
||||
isInitialLoading: true,
|
||||
isLoadingMoreItems: false,
|
||||
|
|
@ -158,7 +159,6 @@ export default {
|
|||
}
|
||||
},
|
||||
},
|
||||
// eslint-disable-next-line @gitlab/vue-no-undef-apollo-properties
|
||||
environments: {
|
||||
query() {
|
||||
return this.queryData?.environments?.query || {};
|
||||
|
|
|
|||
|
|
@ -6,10 +6,10 @@ export default {
|
|||
modal: {
|
||||
id: 'delete-pipeline-schedule-modal',
|
||||
deleteConfirmation: s__(
|
||||
'PipelineSchedules|Are you sure you want to delete this pipeline schedule?',
|
||||
'PipelineSchedules|Are you sure you want to delete this scheduled pipeline?',
|
||||
),
|
||||
actionPrimary: {
|
||||
text: s__('PipelineSchedules|Delete pipeline schedule'),
|
||||
text: s__('PipelineSchedules|Delete scheduled pipeline'),
|
||||
attributes: { variant: 'danger' },
|
||||
},
|
||||
actionCancel: {
|
||||
|
|
|
|||
|
|
@ -4,9 +4,9 @@ import { s__ } from '~/locale';
|
|||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
|
||||
export const i18n = {
|
||||
playTooltip: s__('PipelineSchedules|Run pipeline schedule'),
|
||||
editTooltip: s__('PipelineSchedules|Edit pipeline schedule'),
|
||||
deleteTooltip: s__('PipelineSchedules|Delete pipeline schedule'),
|
||||
playTooltip: s__('PipelineSchedules|Run scheduled pipeline'),
|
||||
editTooltip: s__('PipelineSchedules|Edit scheduled pipeline'),
|
||||
deleteTooltip: s__('PipelineSchedules|Delete scheduled pipeline'),
|
||||
takeOwnershipTooltip: s__('PipelineSchedules|Take ownership of pipeline schedule'),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ export default {
|
|||
<gl-button
|
||||
:disabled="disabled"
|
||||
category="primary"
|
||||
variant="confirm"
|
||||
variant="default"
|
||||
:href="template.link"
|
||||
data-testid="template-link"
|
||||
@click="trackEvent(template.name)"
|
||||
|
|
|
|||
|
|
@ -233,7 +233,6 @@ export default {
|
|||
icon: 'approval',
|
||||
token: UserToken,
|
||||
dataType: 'user',
|
||||
operators: OPERATORS_IS_NOT,
|
||||
fullPath: this.fullPath,
|
||||
isProject: true,
|
||||
recentSuggestionsStorageKey: `${this.fullPath}-merge_requests-recent-tokens-approved_by`,
|
||||
|
|
@ -259,7 +258,6 @@ export default {
|
|||
icon: 'user',
|
||||
token: UserToken,
|
||||
dataType: 'user',
|
||||
operators: OPERATORS_IS_NOT,
|
||||
fullPath: this.fullPath,
|
||||
isProject: true,
|
||||
recentSuggestionsStorageKey: `${this.fullPath}-merge-requests-recent-tokens-assignee`,
|
||||
|
|
@ -273,7 +271,6 @@ export default {
|
|||
icon: 'user',
|
||||
token: UserToken,
|
||||
dataType: 'user',
|
||||
operators: OPERATORS_IS_NOT,
|
||||
fullPath: this.fullPath,
|
||||
isProject: true,
|
||||
recentSuggestionsStorageKey: `${this.fullPath}-merge-requests-recent-tokens-reviewer`,
|
||||
|
|
@ -363,7 +360,6 @@ export default {
|
|||
title: TOKEN_TITLE_LABEL,
|
||||
icon: 'labels',
|
||||
token: LabelToken,
|
||||
operators: OPERATORS_IS_NOT,
|
||||
fetchLabels: this.fetchLabels,
|
||||
recentSuggestionsStorageKey: `${this.fullPath}-merge_requests-recent-tokens-label`,
|
||||
},
|
||||
|
|
@ -416,7 +412,6 @@ export default {
|
|||
title: TOKEN_TITLE_MY_REACTION,
|
||||
icon: 'thumb-up',
|
||||
token: EmojiToken,
|
||||
operators: OPERATORS_IS_NOT,
|
||||
unique: true,
|
||||
fetchEmojis: this.fetchEmojis,
|
||||
recentSuggestionsStorageKey: `${this.fullPath}-merge_requests-recent-tokens-my_reaction`,
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ export default ({ el, router }) => {
|
|||
const { projectPath, ref, isBlob, webIdeUrl, ...options } = convertObjectPropsToCamelCase(
|
||||
JSON.parse(el.dataset.options),
|
||||
);
|
||||
const { webIdePromoPopoverImg, cssClasses } = el.dataset;
|
||||
const { webIdePromoPopoverImg, cssClasses, defaultBranch } = el.dataset;
|
||||
|
||||
// eslint-disable-next-line no-new
|
||||
new Vue({
|
||||
|
|
@ -37,7 +37,15 @@ export default ({ el, router }) => {
|
|||
webIdeUrl: isBlob
|
||||
? webIdeUrl
|
||||
: webIDEUrl(
|
||||
joinPaths('/', projectPath, 'edit', ref, '-', this.$route?.params.path || '', '/'),
|
||||
joinPaths(
|
||||
'/',
|
||||
projectPath,
|
||||
'edit',
|
||||
ref || defaultBranch,
|
||||
'-',
|
||||
this.$route?.params.path || '',
|
||||
'/',
|
||||
),
|
||||
),
|
||||
projectPath,
|
||||
cssClasses,
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import initAmbiguousRefModal from '~/ref/init_ambiguous_ref_modal';
|
|||
import CodeDropdown from '~/vue_shared/components/code_dropdown/code_dropdown.vue';
|
||||
import initSourceCodeDropdowns from '~/vue_shared/components/download_dropdown/init_download_dropdowns';
|
||||
import EmptyProject from '~/pages/projects/show/empty_project';
|
||||
import initWebIdeLink from '~/pages/projects/shared/web_ide_link';
|
||||
import { initHomePanel } from '../home_panel';
|
||||
|
||||
// Project show page loads different overview content based on user preferences
|
||||
|
|
@ -94,3 +95,4 @@ initCodeDropdown();
|
|||
initSourceCodeDropdowns();
|
||||
initFindFileShortcut();
|
||||
initEmptyProjectTabs();
|
||||
initWebIdeLink({ el: document.getElementById('js-tree-web-ide-link') });
|
||||
|
|
|
|||
|
|
@ -145,7 +145,7 @@ export default {
|
|||
this.queryFilterValues = { ...data };
|
||||
},
|
||||
updateCounts() {
|
||||
this.$apollo.queries.todosCount.refetch();
|
||||
this.$apollo.queries.pendingTodosCount.refetch();
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
|||
|
|
@ -238,7 +238,7 @@ export default {
|
|||
return this.gitpodText || __('Gitpod');
|
||||
},
|
||||
computedShowGitpodButton() {
|
||||
return this.showGitpodButton && this.gitpodEnabled;
|
||||
return this.showGitpodButton && this.gitpodEnabled && this.gitpodUrl;
|
||||
},
|
||||
pipelineEditorAction() {
|
||||
if (!this.showPipelineEditorButton) {
|
||||
|
|
|
|||
|
|
@ -106,10 +106,10 @@ class Profiles::TwoFactorAuthsController < Profiles::ApplicationController
|
|||
|
||||
def skip
|
||||
if two_factor_grace_period_expired?
|
||||
redirect_to new_profile_two_factor_auth_path, alert: _('Cannot skip two factor authentication setup')
|
||||
redirect_to profile_two_factor_auth_url, alert: _('Cannot skip two factor authentication setup')
|
||||
else
|
||||
session[:skip_two_factor] = current_user.otp_grace_period_started_at + two_factor_grace_period.hours
|
||||
redirect_to root_path
|
||||
redirect_to root_url
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ module WebIdeButtonHelper
|
|||
end
|
||||
|
||||
def gitpod_url
|
||||
return "" unless Gitlab::CurrentSettings.gitpod_enabled
|
||||
return "" unless Gitlab::CurrentSettings.gitpod_enabled && @ref
|
||||
|
||||
"#{Gitlab::CurrentSettings.gitpod_url}##{project_tree_url(@project, tree_join(@ref, @path || ''))}"
|
||||
end
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ module Users
|
|||
SQL
|
||||
|
||||
::Gitlab::Database::LoadBalancing::SessionMap
|
||||
.current(connection.load_balancer).fallback_to_replicas_for_ambiguous_queries do
|
||||
.current(load_balancer).fallback_to_replicas_for_ambiguous_queries do
|
||||
connection.execute(sql).to_a
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@
|
|||
.project-clone-holder.gl-block.sm:gl-hidden
|
||||
= render "shared/mobile_clone_panel"
|
||||
|
||||
.project-clone-holder.gl-hidden.sm:gl-flex.gl-justify-end.gl-w-full
|
||||
.project-clone-holder.gl-hidden.sm:gl-flex.gl-justify-end.gl-w-full.gl-gap-3
|
||||
= render 'shared/web_ide_button', blob: nil
|
||||
= render "projects/buttons/code", ref: @ref
|
||||
|
||||
= render Pajamas::CardComponent.new(card_options: { class: 'gl-mb-5' }, body_options: { class: 'gl-bg-gray-10 gl-p-5 gl-rounded-base' }) do |c|
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@
|
|||
- page_title _("Edit"), @schedule.description, _("Pipeline Schedule")
|
||||
|
||||
%h1.page-title.gl-text-size-h-display
|
||||
= _("Edit Pipeline Schedule")
|
||||
= _("Edit Scheduled Pipeline")
|
||||
|
||||
#pipeline-schedules-form-edit{ data: js_pipeline_schedules_form_data(@project, @schedule) }
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
- return unless current_user && current_user.namespace
|
||||
|
||||
- type = blob ? 'blob' : 'tree'
|
||||
- button_data = web_ide_button_data({ blob: blob })
|
||||
- fork_options = fork_modal_options(@project, blob)
|
||||
- css_classes = false unless local_assigns[:css_classes]
|
||||
|
||||
.gl-inline-block{ data: { options: button_data.merge(fork_options).to_json, web_ide_promo_popover_img: image_path('web-ide-promo-popover.svg'), css_classes: css_classes }, id: "js-#{type}-web-ide-link" }
|
||||
.gl-inline-block{ data: { options: button_data.merge(fork_options).to_json, web_ide_promo_popover_img: image_path('web-ide-promo-popover.svg'), css_classes: css_classes, default_branch: @project.default_branch_or_main }, id: "js-#{type}-web-ide-link" }
|
||||
|
|
|
|||
|
|
@ -47,33 +47,73 @@
|
|||
}
|
||||
},
|
||||
"additional_properties": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"label": {
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "Only base additional properties are provided",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string"
|
||||
"label": {
|
||||
"$ref": "#additional_prop"
|
||||
},
|
||||
"property": {
|
||||
"$ref": "#additional_prop"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#additional_prop"
|
||||
}
|
||||
},
|
||||
"additionalProperties": {
|
||||
"type": "null",
|
||||
"x-error": "Either property/label or value must be used before defining other additional_properties"
|
||||
}
|
||||
},
|
||||
{
|
||||
"description": "All string-type base additional properties are provided, allowing custom properties",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"label": {
|
||||
"$ref": "#additional_prop"
|
||||
},
|
||||
"property": {
|
||||
"$ref": "#additional_prop"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#additional_prop"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"description"
|
||||
"property",
|
||||
"label"
|
||||
],
|
||||
"additionalProperties": false
|
||||
"additionalProperties": {
|
||||
"$ref": "#additional_prop"
|
||||
}
|
||||
},
|
||||
"property": {
|
||||
{
|
||||
"description": "All numeric-type base additional properties are provided, allowing custom properties",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
"type": "string"
|
||||
"label": {
|
||||
"$ref": "#additional_prop"
|
||||
},
|
||||
"property": {
|
||||
"$ref": "#additional_prop"
|
||||
},
|
||||
"value": {
|
||||
"$ref": "#additional_prop"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"description"
|
||||
"value"
|
||||
],
|
||||
"additionalProperties": false
|
||||
},
|
||||
"value": {
|
||||
"additionalProperties": {
|
||||
"$ref": "#additional_prop"
|
||||
}
|
||||
}
|
||||
],
|
||||
"$defs": {
|
||||
"additional_prop": {
|
||||
"$anchor": "additional_prop",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"description": {
|
||||
|
|
@ -85,8 +125,7 @@
|
|||
],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": true
|
||||
}
|
||||
},
|
||||
"iglu_schema_url": {
|
||||
"type": [
|
||||
|
|
|
|||
|
|
@ -1,9 +0,0 @@
|
|||
---
|
||||
name: use_load_balancing_session_map
|
||||
feature_issue_url: https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/3834
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/168642
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/496505
|
||||
milestone: '17.6'
|
||||
group: group::scalability
|
||||
type: gitlab_com_derisk
|
||||
default_enabled: false
|
||||
|
|
@ -1,7 +1,11 @@
|
|||
- title: "Self-managed certificate-based integration with Kubernetes"
|
||||
announcement_milestone: "14.5"
|
||||
removal_milestone: "18.0"
|
||||
removal_milestone: "19.0"
|
||||
breaking_change: true
|
||||
impact: high
|
||||
scope: [instance, group, project]
|
||||
resolution_role: Maintainer
|
||||
manual_task: true
|
||||
body: |
|
||||
The certificate-based integration with Kubernetes [will be deprecated and removed](https://about.gitlab.com/blog/2021/11/15/deprecating-the-cert-based-kubernetes-integration/).
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
scope: project
|
||||
resolution_role: Maintainer
|
||||
manual_task: true
|
||||
window: 1
|
||||
body: | # (required) Don't change this line.
|
||||
We introduces the OpenTofu CI/CD template in 16.8 as CI/CD components were not available for self-managed installations yet.
|
||||
With the introduction of [GitLab CI/CD components for self-managed users](https://docs.gitlab.com/ee/ci/components/#use-a-gitlabcom-component-in-a-self-managed-instance)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
scope: project
|
||||
resolution_role: Developer
|
||||
manual_task: true
|
||||
window: 2
|
||||
body: | # (required) Don't change this line.
|
||||
The cloud native buildpack (CNB) builder image was updated to `heroku/builder:24` in the Auto DevOps Build project. While we don't expect the changes to be disruptive for the most part, this might be a breaking change for some users of Auto DevOps, and especially users of Auto Build. To better understand the impact of you workloads, review the following:
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
# and a link to the deprecation issue
|
||||
reporter: dhershkovitch
|
||||
stage: verify
|
||||
window: "2"
|
||||
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/424417
|
||||
body: | # (required) Don't change this line.
|
||||
The `previousStageJobsOrNeeds` field in GraphQL will be removed as it has been replaced by the `previousStageJobs` and `needs` fields.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@
|
|||
# and a link to the deprecation issue
|
||||
reporter: joshlambert
|
||||
stage: systems
|
||||
window: "1"
|
||||
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/480914
|
||||
impact: low # Can be one of: [critical, high, medium, low]
|
||||
scope: instance # Can be one or a combination of: [instance, group, project]
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/472213
|
||||
impact: low
|
||||
scope: instance
|
||||
window: "3"
|
||||
resolution_role: Maintainer
|
||||
manual_task: true
|
||||
body: |
|
||||
|
|
|
|||
|
|
@ -26,9 +26,8 @@
|
|||
announcement_milestone: "XX.YY"
|
||||
# Change breaking_change to false if needed.
|
||||
breaking_change: true
|
||||
# The stage and GitLab username of the person reporting the change,
|
||||
# and a link to the deprecation issue
|
||||
reporter: exampleuser
|
||||
window: # Can be [1, 2, or 3] - The window when the breaking change will be deployed on GitLab.com
|
||||
reporter: exampleuser # The GitLab username of the person reporting the change
|
||||
stage: stage
|
||||
issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/000000
|
||||
# Use the impact calculator https://gitlab-com.gitlab.io/gl-infra/breaking-change-impact-calculator/?
|
||||
|
|
@ -36,7 +35,6 @@
|
|||
scope: # Can be one or a combination of: [instance, group, project]
|
||||
resolution_role: # Can be one of: [Admin, Owner, Maintainer, Developer]
|
||||
manual_task: # Can be true or false. Use this to denote whether a resolution action must be performed manually (true), or if it can be automated by using the API or other automation (false).
|
||||
window: # Can be "1", "2" or "3"
|
||||
body: | # (required) Don't change this line.
|
||||
<!-- START OF BODY COMMENT
|
||||
|
||||
|
|
|
|||
|
|
@ -5,4 +5,4 @@ feature_category: team_planning
|
|||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/167972
|
||||
milestone: '17.5'
|
||||
queued_migration_version: 20241002185804
|
||||
finalized_by: # version of the migration that finalized this BBM
|
||||
finalized_by: 20241030165330
|
||||
|
|
|
|||
|
|
@ -7,5 +7,4 @@ feature_categories:
|
|||
description: https://docs.gitlab.com/ee/user/project/deploy_tokens/
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/commit/db18993f652425b72c4b854e18a002e0ec44b196
|
||||
milestone: '10.7'
|
||||
gitlab_schema: gitlab_main
|
||||
sharding_key_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/477395
|
||||
gitlab_schema: gitlab_main_clusterwide
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddSoftwareLicenseIndexesToNameColumns < Gitlab::Database::Migration[2.2]
|
||||
disable_ddl_transaction!
|
||||
milestone '17.6'
|
||||
|
||||
CUSTOM_SOFTWARE_LICENSES_INDEX_NAME = 'idx_custom_software_licenses_lower_name'
|
||||
SOFTWARE_LICENSES_INDEX_NAME = 'idx_software_licenses_lower_name'
|
||||
|
||||
def up
|
||||
add_concurrent_index :custom_software_licenses, 'LOWER(name)', name: CUSTOM_SOFTWARE_LICENSES_INDEX_NAME
|
||||
add_concurrent_index :software_licenses, 'LOWER(name)', name: SOFTWARE_LICENSES_INDEX_NAME
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name :custom_software_licenses, CUSTOM_SOFTWARE_LICENSES_INDEX_NAME
|
||||
remove_concurrent_index_by_name :software_licenses, SOFTWARE_LICENSES_INDEX_NAME
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class FinalizeBackfillIssuesCorrectWorkItemTypeId < Gitlab::Database::Migration[2.2]
|
||||
disable_ddl_transaction!
|
||||
restrict_gitlab_migration gitlab_schema: :gitlab_main
|
||||
|
||||
milestone '17.6'
|
||||
|
||||
MIGRATION = "BackfillIssuesCorrectWorkItemTypeId"
|
||||
|
||||
def up
|
||||
ensure_batched_background_migration_is_finished(
|
||||
job_class_name: MIGRATION,
|
||||
table_name: :issues,
|
||||
column_name: :id,
|
||||
job_arguments: [],
|
||||
finalize: true
|
||||
)
|
||||
end
|
||||
|
||||
def down
|
||||
# no-op
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
eb07013a603f182a6c7ddb51a3bd6da91d655a1fff83791fbd978b4c09520a2c
|
||||
|
|
@ -0,0 +1 @@
|
|||
cc3ef05bcf103ea2e3a69a450eb71be8680fd6d4aa9d6538276667003eadd24b
|
||||
|
|
@ -27948,6 +27948,8 @@ CREATE UNIQUE INDEX idx_custom_field_select_options_on_custom_field_id_lower_val
|
|||
|
||||
CREATE UNIQUE INDEX idx_custom_fields_on_namespace_id_and_lower_name ON custom_fields USING btree (namespace_id, lower(name));
|
||||
|
||||
CREATE INDEX idx_custom_software_licenses_lower_name ON custom_software_licenses USING btree (lower(name));
|
||||
|
||||
CREATE INDEX idx_deletions_on_project_id_and_id_where_pending ON ONLY p_batched_git_ref_updates_deletions USING btree (project_id, id) WHERE (status = 1);
|
||||
|
||||
CREATE INDEX idx_dep_proxy_pkgs_settings_enabled_maven_on_project_id ON dependency_proxy_packages_settings USING btree (project_id) WHERE ((enabled = true) AND (maven_external_registry_url IS NOT NULL));
|
||||
|
|
@ -28178,6 +28180,8 @@ CREATE UNIQUE INDEX idx_software_license_policies_unique_on_custom_license_proje
|
|||
|
||||
CREATE UNIQUE INDEX idx_software_license_policies_unique_on_project_and_scan_policy ON software_license_policies USING btree (project_id, software_license_id, scan_result_policy_id);
|
||||
|
||||
CREATE INDEX idx_software_licenses_lower_name ON software_licenses USING btree (lower((name)::text));
|
||||
|
||||
CREATE INDEX idx_status_check_responses_on_id_and_status ON status_check_responses USING btree (id, status);
|
||||
|
||||
CREATE INDEX idx_streaming_group_namespace_filters_on_namespace_id ON audit_events_streaming_group_namespace_filters USING btree (namespace_id);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,111 @@
|
|||
---
|
||||
stage: AI-Powered
|
||||
group: Custom Models
|
||||
description: Get started with self-hosted AI models.
|
||||
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
|
||||
---
|
||||
|
||||
# Self-hosted model configuration and authentication
|
||||
|
||||
DETAILS:
|
||||
**Tier:** Ultimate with GitLab Duo Enterprise - [Start a trial](https://about.gitlab.com/solutions/gitlab-duo-pro/sales/?type=free-trial)
|
||||
**Offering:** Self-managed
|
||||
**Status:** Beta
|
||||
|
||||
> - [Introduced](https://gitlab.com/groups/gitlab-org/-/epics/12972) in GitLab 17.1 [with a flag](../../administration/feature_flags.md) named `ai_custom_model`. Disabled by default.
|
||||
> - [Enabled on self-managed](https://gitlab.com/groups/gitlab-org/-/epics/15176) in GitLab 17.6.
|
||||
> - Changed to require GitLab Duo add-on in GitLab 17.6 and later.
|
||||
|
||||
There are two configuration options for self-managed customers:
|
||||
|
||||
- **GitLab.com AI Gateway**: Use the GitLab-managed AI Gateway with default external
|
||||
large language model (LLM) providers (for example, Google Vertex or Anthropic).
|
||||
- **Self-hosted AI Gateway**: Deploy and manage your own AI Gateway and language models in your infrastructure,
|
||||
without depending on GitLab-provided external language providers.
|
||||
|
||||
## GitLab.com AI Gateway
|
||||
|
||||
In this configuration, your GitLab instance depends on and sends requests to the external GitLab AI Gateway, which communicates with external AI vendors such as Google Vertex or Anthropic. The response is then forwarded back to your GitLab instance.
|
||||
|
||||
```mermaid
|
||||
%%{init: { "theme": "default", "fontFamily": "GitLab Sans", "sequence": { "actorFontSize": 12, "participantFontSize": 12, "messageFontSize": 12 } }}%%
|
||||
sequenceDiagram
|
||||
actor User as User
|
||||
participant SelfHostedGitLab as Self-hosted GitLab (Your Instance)
|
||||
participant GitLabAIGateway as GitLab AI Gateway (External)
|
||||
participant GitLabAIVendor as GitLab AI Vendor (External)
|
||||
|
||||
User ->> SelfHostedGitLab: Send request
|
||||
SelfHostedGitLab ->> SelfHostedGitLab: Check if self-hosted model is configured
|
||||
SelfHostedGitLab ->> GitLabAIGateway: Forward request for AI processing
|
||||
GitLabAIGateway ->> GitLabAIVendor: Create prompt and send request to AI model server
|
||||
GitLabAIVendor -->> GitLabAIGateway: Respond to the prompt
|
||||
GitLabAIGateway -->> SelfHostedGitLab: Forward AI response
|
||||
SelfHostedGitLab -->> User: Forward AI response
|
||||
```
|
||||
|
||||
## Self-hosted AI Gateway
|
||||
|
||||
In this configuration, the entire system is isolated within the enterprise, ensuring a fully self-hosted environment that safeguards data privacy.
|
||||
|
||||
```mermaid
|
||||
%%{init: { "theme": "default", "fontFamily": "GitLab Sans", "sequence": { "actorFontSize": 12, "participantFontSize": 12, "messageFontSize": 12 } }}%%
|
||||
sequenceDiagram
|
||||
actor User as User
|
||||
participant SelfHostedGitLab as Self-hosted GitLab
|
||||
participant SelfHostedAIGateway as Self-hosted AI Gateway
|
||||
participant SelfHostedModel as Self-hosted model
|
||||
|
||||
User ->> SelfHostedGitLab: Send request
|
||||
SelfHostedGitLab ->> SelfHostedGitLab: Check if self-hosted model is configured
|
||||
SelfHostedAIGateway ->> SelfHostedModel: Create prompt and perform request to AI model server
|
||||
SelfHostedGitLab ->> SelfHostedAIGateway: Forward request for AI processing
|
||||
SelfHostedModel -->> SelfHostedAIGateway: Respond to the prompt
|
||||
SelfHostedAIGateway -->> SelfHostedGitLab: Forward AI response
|
||||
SelfHostedGitLab -->> User: Forward AI response
|
||||
```
|
||||
|
||||
For more information, see the [self-hosted model deployment blueprint](https://handbook.gitlab.com/handbook/engineering/architecture/design-documents/custom_models/).
|
||||
|
||||
## Authentication for self-hosted models
|
||||
|
||||
The authentication process for self-hosted models is secure, efficient, and made up of the following key components:
|
||||
|
||||
- **Self-issued tokens**: In this architecture, access credentials are not synchronized with `cloud.gitlab.com`. Instead, tokens are self-issued dynamically, similar to the functionality on GitLab.com. This method provides users with immediate access while maintaining a high level of security.
|
||||
|
||||
- **Offline environments**: In offline setups, there are no connections to `cloud.gitlab.com`. All requests are routed exclusively to the self-hosted AI Gateway.
|
||||
|
||||
- **Token minting and verification**: The GitLab self-managed instance mints the token, which is then verified by the AI Gateway against the GitLab instance.
|
||||
|
||||
- **Model configuration and security**: When an administrator configures a model, they can incorporate an API key to authenticate requests. Additionally, you can enhance security by specifying connection IP addresses within your network, ensuring that only trusted IPs can interact with the model.
|
||||
|
||||
As illustrated in the following diagram:
|
||||
|
||||
1. The authentication flow begins when the user configures the model through the GitLab instance and submits a request to access the GitLab Duo feature.
|
||||
1. The GitLab instance mints an access token, which the user forwards to GitLab and then to the AI Gateway for verification.
|
||||
1. Upon confirming the token's validity, the AI Gateway sends a request to the AI model, which uses the API key to authenticate the request and process it.
|
||||
1. The results are then relayed back to the GitLab instance, completing the flow by sending the response to the user, which is designed to be secure and efficient.
|
||||
|
||||
```mermaid
|
||||
%%{init: { "theme": "default", "fontFamily": "GitLab Sans", "sequence": { "actorFontSize": 12, "participantFontSize": 12, "messageFontSize": 12 } }}%%
|
||||
sequenceDiagram
|
||||
participant User as User
|
||||
participant GitLab as GitLab Instance
|
||||
participant AI Gateway as AI Gateway
|
||||
participant AIModel as AI Model
|
||||
|
||||
User->>GitLab: Configure Model
|
||||
User->>GitLab: Request Access
|
||||
GitLab->>GitLab: Mint Token
|
||||
GitLab->>User: Send Token
|
||||
User->>GitLab: Forward Minted Token
|
||||
GitLab->>AI Gateway: Verify Token
|
||||
AI Gateway->>GitLab: Token Validated
|
||||
GitLab->>AI Gateway: Send Request to Model
|
||||
AI Gateway->>AIModel: Send Request to Model
|
||||
AIModel->>AIModel: Authenticate using API Key
|
||||
AIModel->>AI Gateway: Process Request
|
||||
AI Gateway->>GitLab: Send Result to GitLab
|
||||
GitLab->>User: Send Response
|
||||
|
||||
```
|
||||
|
|
@ -18,7 +18,7 @@ DETAILS:
|
|||
|
||||
To configure your GitLab instance to access the available self-hosted models in your infrastructure:
|
||||
|
||||
1. Use a [locally hosted or GitLab.com AI Gateway](index.md#self-managed-customer-configuration-types).
|
||||
1. Use a [locally hosted or GitLab.com AI Gateway](index.md#choose-a-configuration-type).
|
||||
1. Configure your GitLab instance.
|
||||
1. Configure the self-hosted model.
|
||||
1. Configure the GitLab Duo features to use your self-hosted model.
|
||||
|
|
|
|||
|
|
@ -34,109 +34,30 @@ This setup ensures enterprise-level privacy and flexibility, allowing seamless i
|
|||
|
||||
### Prerequisites
|
||||
|
||||
The following are required:
|
||||
Before setting up a self-hosted model infrastructure, you must have:
|
||||
|
||||
- A [supported model](supported_models_and_hardware_requirements.md) (either cloud-based or on-premises).
|
||||
- A [supported serving platform](supported_llm_serving_platforms.md) (either cloud-based or on-premises).
|
||||
- A locally hosted or GitLab.com AI Gateway.
|
||||
- GitLab [Enterprise Edition license](../../administration/license.md).
|
||||
|
||||
## Self-managed customer configuration types
|
||||
## Choose a configuration type
|
||||
|
||||
There are two configuration options for self-managed customers:
|
||||
|
||||
- **GitLab.com AI Gateway customers**: Use the GitLab-hosted AI Gateway with external LLM providers (for example, Google Vertex or Anthropic).
|
||||
- **Self-hosted AI Gateway customers**: Deploy your own AI Gateway and LLMs within your infrastructure, without relying on external public services.
|
||||
- [**GitLab.com AI Gateway**](configuration_types.md#gitlabcom-ai-gateway):
|
||||
Use the GitLab-hosted AI Gateway with external
|
||||
LLM providers (for example, Google Vertex or Anthropic).
|
||||
- [**Self-hosted AI Gateway**](configuration_types.md#self-hosted-ai-gateway):
|
||||
Deploy your own AI Gateway and LLMs within
|
||||
your infrastructure, without relying on external public services.
|
||||
|
||||
### Fully self-hosted architecture
|
||||
|
||||
In this configuration, the entire system is isolated within the enterprise, ensuring a fully self-hosted environment that safeguards data privacy.
|
||||
|
||||
```mermaid
|
||||
%%{init: { "theme": "default", "fontFamily": "GitLab Sans", "sequence": { "actorFontSize": 12, "participantFontSize": 12, "messageFontSize": 12 } }}%%
|
||||
sequenceDiagram
|
||||
actor User as User
|
||||
participant SelfHostedGitLab as Self-hosted GitLab
|
||||
participant SelfHostedAIGateway as Self-hosted AI Gateway
|
||||
participant SelfHostedModel as Self-hosted model
|
||||
|
||||
User ->> SelfHostedGitLab: Send request
|
||||
SelfHostedGitLab ->> SelfHostedGitLab: Check if self-hosted model is configured
|
||||
SelfHostedGitLab ->> SelfHostedAIGateway: Forward request for AI processing
|
||||
SelfHostedAIGateway ->> SelfHostedModel: Create prompt and perform request to AI model server
|
||||
SelfHostedModel -->> SelfHostedAIGateway: Respond to the prompt
|
||||
SelfHostedAIGateway -->> SelfHostedGitLab: Forward AI response
|
||||
SelfHostedGitLab -->> User: Forward AI response
|
||||
```
|
||||
|
||||
### GitLab AI vendor architecture
|
||||
|
||||
In this configuration, your GitLab instance depends on and sends requests to the external GitLab AI Gateway, which communicates with external AI vendors such as Google Vertex or Anthropic. The response is then forwarded back to your GitLab instance.
|
||||
|
||||
```mermaid
|
||||
%%{init: { "theme": "default", "fontFamily": "GitLab Sans", "sequence": { "actorFontSize": 12, "participantFontSize": 12, "messageFontSize": 12 } }}%%
|
||||
sequenceDiagram
|
||||
actor User as User
|
||||
participant SelfHostedGitLab as Self-hosted GitLab (Your Instance)
|
||||
participant GitLabAIGateway as GitLab AI Gateway (External)
|
||||
participant GitLabAIVendor as GitLab AI Vendor (External)
|
||||
|
||||
User ->> SelfHostedGitLab: Send request
|
||||
SelfHostedGitLab ->> SelfHostedGitLab: Check if self-hosted model is configured
|
||||
SelfHostedGitLab ->> GitLabAIGateway: Forward request for AI processing
|
||||
GitLabAIGateway ->> GitLabAIVendor: Create prompt and send request to AI model server
|
||||
GitLabAIVendor -->> GitLabAIGateway: Respond to the prompt
|
||||
GitLabAIGateway -->> SelfHostedGitLab: Forward AI response
|
||||
SelfHostedGitLab -->> User: Forward AI response
|
||||
```
|
||||
|
||||
For more details, see the [Blueprint](https://handbook.gitlab.com/handbook/engineering/architecture/design-documents/custom_models/).
|
||||
|
||||
## Authentication for self-hosted models
|
||||
|
||||
The authentication process for self-hosted models is designed to be secure and efficient, comprising the following key components:
|
||||
|
||||
- **Self-issued tokens**: In this architecture, access credentials are not synchronized with `cloud.gitlab.com`. Instead, tokens are self-issued dynamically, similar to the functionality on GitLab.com. This method provides users with immediate access while maintaining a high level of security.
|
||||
|
||||
- **Offline environments**: In offline setups, there are no connections to `cloud.gitlab.com`. All requests are routed exclusively to the self-hosted AI Gateway.
|
||||
|
||||
- **Token minting and verification**: The GitLab self-managed instance mints the token, which is then verified by the AI Gateway against the GitLab instance.
|
||||
- **Model configuration and security**: When an administrator configures a model, they can incorporate an API key to authenticate requests. Additionally, you can enhance security by specifying connection IP addresses within your network, ensuring that only trusted IPs can interact with the model.
|
||||
|
||||
As illustrated in the following diagram:
|
||||
|
||||
1. The authentication flow begins when the user configures the model through the GitLab instance and submits a request to access the GitLab Duo feature.
|
||||
1. The GitLab instance mints an access token, which the user forwards to GitLab and then to the AI Gateway for verification.
|
||||
1. Upon confirming the token's validity, the AI Gateway sends a request to the AI model, which uses the API key to authenticate the request and process it.
|
||||
1. The results are then relayed back to the GitLab instance, completing the flow by sending the response to the user, which is designed to be secure and efficient.
|
||||
|
||||
```mermaid
|
||||
%%{ init : { "theme" : "default", "themeVariables": { "actorBackground": "#ffffff", "actorBorder": "#34495e", "actorTextColor": "#34495e", "participantBackground": "#e0f7fa", "participantBorder": "#00796b", "participantTextColor": "#00796b", "sequenceNumberColor": "#00796b", "noteTextColor": "#34495e" } } }%%
|
||||
sequenceDiagram
|
||||
participant User as User
|
||||
participant GitLab as GitLab Instance
|
||||
participant AI Gateway as AI Gateway
|
||||
participant AIModel as AI Model
|
||||
|
||||
User->>GitLab: Configure Model
|
||||
User->>GitLab: Request Access
|
||||
GitLab->>GitLab: Mint Token
|
||||
GitLab->>User: Send Token
|
||||
User->>GitLab: Forward Minted Token
|
||||
GitLab->>AI Gateway: Verify Token
|
||||
AI Gateway->>GitLab: Token Validated
|
||||
GitLab->>AI Gateway: Send Request to Model
|
||||
AI Gateway->>AIModel: Send Request to Model
|
||||
AIModel->>AIModel: Authenticate using API Key
|
||||
AIModel->>AI Gateway: Process Request
|
||||
AI Gateway->>GitLab: Send Result to GitLab
|
||||
GitLab->>User: Send Response
|
||||
|
||||
```
|
||||
Before setting up a self-hosted model infrastructure, you must decide which
|
||||
configuration type to implement.
|
||||
|
||||
## Set up a self-hosted infrastructure
|
||||
|
||||
To establish a fully isolated self-hosted infrastructure:
|
||||
To set up a fully isolated self-hosted model infrastructure:
|
||||
|
||||
1. **Install a Large Language Model (LLM) Serving Infrastructure**
|
||||
|
||||
|
|
@ -155,9 +76,5 @@ To establish a fully isolated self-hosted infrastructure:
|
|||
|
||||
## Related topics
|
||||
|
||||
- AWS Bedrock
|
||||
- [Import Custom Models Into Amazon Bedrock](https://www.youtube.com/watch?v=CA2AXfWWdpA)
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
To begin troubleshooting, run the debugging scripts to verify your self-hosted model setup. For further guidance on other actions you can take, see the [troubleshooting documentation](troubleshooting.md).
|
||||
- [Import custom models into Amazon Bedrock](https://www.youtube.com/watch?v=CA2AXfWWdpA)
|
||||
- [Troubleshooting](troubleshooting.md)
|
||||
|
|
|
|||
|
|
@ -100,6 +100,32 @@ Related Handbook pages:
|
|||
- <https://handbook.gitlab.com/handbook/marketing/blog/release-posts/#deprecations-removals-and-breaking-changes>
|
||||
- <https://handbook.gitlab.com/handbook/marketing/blog/release-posts/#update-the-deprecations-doc>
|
||||
|
||||
## Update the breaking change windows documentation
|
||||
|
||||
The [breaking change windows](../../update/breaking_windows.md)
|
||||
documentation is generated based on the `window` value in the YAML files located in
|
||||
[`gitlab/data/deprecations`](https://gitlab.com/gitlab-org/gitlab/-/tree/master/data/deprecations).
|
||||
|
||||
To update the breaking change windows page when a YAML file is added,
|
||||
edited, or removed:
|
||||
|
||||
1. From the command line, go to your local clone of the [`gitlab-org/gitlab`](https://gitlab.com/gitlab-org/gitlab) project.
|
||||
1. Create, edit, or remove the YAML file under [`data/deprecations`](https://gitlab.com/gitlab-org/gitlab/-/tree/master/data/deprecations).
|
||||
1. Compile the breaking change windows documentation:
|
||||
|
||||
```shell
|
||||
bin/rake gitlab:docs:compile_windows
|
||||
```
|
||||
|
||||
1. If needed, you can verify the documentation is up to date with:
|
||||
|
||||
```shell
|
||||
bin/rake gitlab:docs:check_windows
|
||||
```
|
||||
|
||||
1. Commit the updated documentation and push the changes.
|
||||
1. Create a merge request.
|
||||
|
||||
## Update the related documentation
|
||||
|
||||
When features are deprecated and removed, [update the related documentation](../documentation/styleguide/deprecations_and_removals.md).
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@ that are coded across multiple repositories.
|
|||
|---|---|---|
|
||||
| [All feature flags in GitLab](../../../user/feature_flags.md) | [Generated during docs build](https://gitlab.com/gitlab-org/gitlab-docs/-/blob/main/doc/raketasks.md#generate-the-feature-flag-tables) | [Technical Writing](https://handbook.gitlab.com/handbook/product/ux/technical-writing/) |
|
||||
| [GitLab Runner feature flags](https://docs.gitlab.com/runner/configuration/feature-flags.html) | [Page source](https://gitlab.com/gitlab-org/gitlab-runner/-/blob/ec6e1797d2173a95c8ac7f726bd62f6f110b7211/docs/configuration/feature-flags.md?plain=1#L39) | [Runner](https://handbook.gitlab.com/handbook/engineering/development/ops/verify/runner/) |
|
||||
| [Deprecations and removals by version](../../../update/deprecations.md) | [Deprecating GitLab features](../../deprecation_guidelines/index.md) | |
|
||||
| [Deprecations and removals by version](../../../update/deprecations.md) | [Update the deprecations and removals documentation](../../deprecation_guidelines/index.md#update-the-deprecations-and-removals-documentation) | |
|
||||
| [Breaking change windows](../../../update/breaking_windows.md) | [Update the breaking change windows documentation](../../deprecation_guidelines/index.md#update-the-breaking-change-windows-documentation) | |
|
||||
| [GraphQL API resources](../../../api/graphql/reference/index.md) | [GraphQL API style guide](../../api_graphql_styleguide.md#documentation-and-schema) | [Import and Integrate](https://handbook.gitlab.com/handbook/engineering/development/dev/foundations/import-and-integrate/) |
|
||||
| [Audit event types](../../../user/compliance/audit_event_types.md) | [Audit event development guidelines](../../audit_event_guide/index.md) | [Compliance](https://handbook.gitlab.com/handbook/engineering/development/sec/govern/compliance/) |
|
||||
| [Available custom role permissions](../../../user/custom_roles/abilities.md) | [Generated by Rake task](https://gitlab.com/gitlab-org/gitlab/-/blob/master/tooling/custom_roles/docs/templates/custom_abilities.md.erb) | [Authorization](https://handbook.gitlab.com/handbook/product/categories/#authorization-group)|
|
||||
|
|
|
|||
|
|
@ -305,8 +305,11 @@ and is not affected by the current search.
|
|||
## Add seats to subscription
|
||||
|
||||
Your subscription cost is based on the maximum number of seats you use during the billing period.
|
||||
Even if you reach the number of seats in your subscription, you can continue to add users.
|
||||
GitLab [bills you for the overage](../quarterly_reconciliation.md).
|
||||
|
||||
- If [restricted access](../../administration/settings/sign_up_restrictions.md#turn-on-restricted-access)
|
||||
is turned on, when there are no seats left in your subscription you must purchase more seats for groups to add new billable users.
|
||||
- If restricted access is turned off, when there are no seats left in your subscription groups can continue to add billable
|
||||
users. GitLab [bills you for the overage](../quarterly_reconciliation.md).
|
||||
|
||||
To add seats to a subscription:
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@ This window takes place on April 21 - 23, 2025 from 09:00 UTC to 22:00 UTC.
|
|||
|
||||
| Deprecation | Impact | Stage | Scope |
|
||||
|-------------|--------|-------|-------|
|
||||
| [Rate limits for common User, Project, and Group API endpoints](https://gitlab.com/gitlab-org/gitlab/-/issues/480914) | Low | Systems | Instance |
|
||||
|
||||
## Window 2
|
||||
|
||||
|
|
@ -33,7 +32,6 @@ This window takes place on April 28 - 30, 2025 from 09:00 UTC to 22:00 UTC.
|
|||
|
||||
| Deprecation | Impact | Stage | Scope |
|
||||
|-------------|--------|-------|-------|
|
||||
| [Remove `previousStageJobsOrNeeds` from GraphQL](https://gitlab.com/gitlab-org/gitlab/-/issues/424417) | | Verify | |
|
||||
|
||||
## Window 3
|
||||
|
||||
|
|
@ -41,4 +39,3 @@ This window takes place on May 5 - 7, 2025 from 09:00 UTC to 22:00 UTC.
|
|||
|
||||
| Deprecation | Impact | Stage | Scope |
|
||||
|-------------|--------|-------|-------|
|
||||
| [Limited `scan` actions in a scan execution policy](https://gitlab.com/gitlab-org/gitlab/-/issues/472213) | Low | Govern | Instance |
|
||||
|
|
@ -99,6 +99,34 @@ Before upgrading to GitLab 19.0, please ensure you have [migrated](https://docs.
|
|||
|
||||
<div class="deprecation breaking-change" data-milestone="19.0">
|
||||
|
||||
### Self-managed certificate-based integration with Kubernetes
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
||||
- Announced in GitLab <span class="milestone">14.5</span>
|
||||
- Removal in GitLab <span class="milestone">19.0</span> ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
|
||||
- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/groups/gitlab-org/configure/-/epics/8).
|
||||
|
||||
</div>
|
||||
|
||||
The certificate-based integration with Kubernetes [will be deprecated and removed](https://about.gitlab.com/blog/2021/11/15/deprecating-the-cert-based-kubernetes-integration/).
|
||||
|
||||
As a self-managed customer, we are introducing the [feature flag](https://docs.gitlab.com/ee/administration/feature_flags.html#enable-or-disable-the-feature) `certificate_based_clusters` in GitLab 15.0 so you can keep your certificate-based integration enabled. However, the feature flag will be disabled by default, so this change is a **breaking change**.
|
||||
|
||||
In GitLab 18.0 we will remove both the feature and its related code. Until the final removal in 18.0, features built on this integration will continue to work, if you enable the feature flag. Until the feature is removed, GitLab will continue to fix security and critical issues as they arise.
|
||||
|
||||
For a more robust, secure, forthcoming, and reliable integration with Kubernetes, we recommend you use the
|
||||
[agent for Kubernetes](https://docs.gitlab.com/ee/user/clusters/agent/) to connect Kubernetes clusters with GitLab. [How do I migrate?](https://docs.gitlab.com/ee/user/infrastructure/clusters/migrate_to_gitlab_agent.html)
|
||||
|
||||
Although an explicit removal date is set, we don't plan to remove this feature until the new solution has feature parity.
|
||||
For more information about the blockers to removal, see [this issue](https://gitlab.com/gitlab-org/configure/general/-/issues/199).
|
||||
|
||||
For updates and details about this deprecation, follow [this epic](https://gitlab.com/groups/gitlab-org/configure/-/epics/8).
|
||||
|
||||
</div>
|
||||
|
||||
<div class="deprecation breaking-change" data-milestone="19.0">
|
||||
|
||||
### Single database connection is deprecated
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
|
@ -768,34 +796,6 @@ Occurrences of the `active` identifier in the GitLab GraphQL API endpoints will
|
|||
|
||||
<div class="deprecation breaking-change" data-milestone="18.0">
|
||||
|
||||
### Self-managed certificate-based integration with Kubernetes
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
||||
- Announced in GitLab <span class="milestone">14.5</span>
|
||||
- Removal in GitLab <span class="milestone">18.0</span> ([breaking change](https://docs.gitlab.com/ee/update/terminology.html#breaking-change))
|
||||
- To discuss this change or learn more, see the [deprecation issue](https://gitlab.com/groups/gitlab-org/configure/-/epics/8).
|
||||
|
||||
</div>
|
||||
|
||||
The certificate-based integration with Kubernetes [will be deprecated and removed](https://about.gitlab.com/blog/2021/11/15/deprecating-the-cert-based-kubernetes-integration/).
|
||||
|
||||
As a self-managed customer, we are introducing the [feature flag](https://docs.gitlab.com/ee/administration/feature_flags.html#enable-or-disable-the-feature) `certificate_based_clusters` in GitLab 15.0 so you can keep your certificate-based integration enabled. However, the feature flag will be disabled by default, so this change is a **breaking change**.
|
||||
|
||||
In GitLab 18.0 we will remove both the feature and its related code. Until the final removal in 18.0, features built on this integration will continue to work, if you enable the feature flag. Until the feature is removed, GitLab will continue to fix security and critical issues as they arise.
|
||||
|
||||
For a more robust, secure, forthcoming, and reliable integration with Kubernetes, we recommend you use the
|
||||
[agent for Kubernetes](https://docs.gitlab.com/ee/user/clusters/agent/) to connect Kubernetes clusters with GitLab. [How do I migrate?](https://docs.gitlab.com/ee/user/infrastructure/clusters/migrate_to_gitlab_agent.html)
|
||||
|
||||
Although an explicit removal date is set, we don't plan to remove this feature until the new solution has feature parity.
|
||||
For more information about the blockers to removal, see [this issue](https://gitlab.com/gitlab-org/configure/general/-/issues/199).
|
||||
|
||||
For updates and details about this deprecation, follow [this epic](https://gitlab.com/groups/gitlab-org/configure/-/epics/8).
|
||||
|
||||
</div>
|
||||
|
||||
<div class="deprecation breaking-change" data-milestone="18.0">
|
||||
|
||||
### Slack notifications integration
|
||||
|
||||
<div class="deprecation-notes">
|
||||
|
|
|
|||
|
|
@ -141,6 +141,18 @@ see [Packaged PostgreSQL deployed in an HA/Geo Cluster](https://docs.gitlab.com/
|
|||
| 17.1 | All | None |
|
||||
| 17.2 | All | None |
|
||||
|
||||
- Geo replication details for secondary sites appear to be empty even if Geo replication is working. See [issue 468509](https://gitlab.com/gitlab-org/gitlab/-/issues/468509). There is no known workaround. The bug is fixed in GitLab 17.4.
|
||||
|
||||
**Affected releases**:
|
||||
|
||||
| Affected minor releases | Affected patch releases | Fixed in |
|
||||
| ----------------------- | ----------------------- | -------- |
|
||||
| 16.11 | 16.11.5 - 16.11.10 | None |
|
||||
| 17.0 | All | 17.0.7 |
|
||||
| 17.1 | All | 17.1.7 |
|
||||
| 17.2 | All | 17.2.5 |
|
||||
| 17.3 | All | 17.3.1 |
|
||||
|
||||
## 16.10.0
|
||||
|
||||
You might encounter the following error while upgrading to GitLab 16.10 or later:
|
||||
|
|
|
|||
|
|
@ -263,6 +263,7 @@ The OpenSSL 3 upgrade has been postponed to GitLab 17.7.0.
|
|||
|
||||
| Affected minor releases | Affected patch releases | Fixed in |
|
||||
| ----------------------- | ----------------------- | -------- |
|
||||
| 16.11 | 16.11.5 - 16.11.10 | None |
|
||||
| 17.0 | All | 17.0.7 |
|
||||
| 17.1 | All | 17.1.7 |
|
||||
| 17.2 | All | 17.2.5 |
|
||||
|
|
@ -322,6 +323,7 @@ The OpenSSL 3 upgrade has been postponed to GitLab 17.7.0.
|
|||
|
||||
| Affected minor releases | Affected patch releases | Fixed in |
|
||||
| ----------------------- | ----------------------- | -------- |
|
||||
| 16.11 | 16.11.5 - 16.11.10 | None |
|
||||
| 17.0 | All | 17.0.7 |
|
||||
| 17.1 | All | 17.1.7 |
|
||||
| 17.2 | All | 17.2.5 |
|
||||
|
|
@ -359,6 +361,7 @@ The OpenSSL 3 upgrade has been postponed to GitLab 17.7.0.
|
|||
|
||||
| Affected minor releases | Affected patch releases | Fixed in |
|
||||
| ----------------------- | ----------------------- | -------- |
|
||||
| 16.11 | 16.11.5 - 16.11.10 | None |
|
||||
| 17.0 | All | 17.0.7 |
|
||||
| 17.1 | All | 17.1.7 |
|
||||
| 17.2 | All | 17.2.5 |
|
||||
|
|
@ -385,6 +388,7 @@ The OpenSSL 3 upgrade has been postponed to GitLab 17.7.0.
|
|||
|
||||
| Affected minor releases | Affected patch releases | Fixed in |
|
||||
| ----------------------- | ----------------------- | -------- |
|
||||
| 16.11 | 16.11.5 - 16.11.10 | None |
|
||||
| 17.0 | All | 17.0.7 |
|
||||
| 17.1 | All | 17.1.7 |
|
||||
| 17.2 | All | 17.2.5 |
|
||||
|
|
|
|||
|
|
@ -20,17 +20,25 @@ To minimize the risk of exposing your secrets, always store secrets outside of t
|
|||
repositories. After a sensitive value is pushed to a remote
|
||||
repository, anyone with access to the repository can use the secret to
|
||||
impersonate the authorized user.
|
||||
Secret detection monitors your activity to help prevent your secrets
|
||||
from being exposed. GitLab has three methods for detecting secrets, which
|
||||
you can use simultaneously:
|
||||
|
||||
- The [pipeline](pipeline/index.md) method detects secrets during the project's CI/CD pipeline.
|
||||
Pipeline secret detection works with all text files, regardless of language or framework.
|
||||
This method cannot reject pushes.
|
||||
- The [secret push protection](secret_push_protection/index.md) method detects secrets when users push changes to the
|
||||
remote Git branch. This method can reject pushes if a secret is detected.
|
||||
- The [client-side](client/index.md) method runs in your browser, and warns you if the content of text you're about
|
||||
to post contains a potential secret.
|
||||
Secret detection monitors your activity to both:
|
||||
|
||||
- Help prevent your secrets from being leaked.
|
||||
- Help you respond if a secret is leaked.
|
||||
|
||||
You should take a multi-layered security approach and enable all available secret detection methods:
|
||||
|
||||
- [Secret push protection](secret_push_protection/index.md) scans commits for secrets when you
|
||||
push changes to GitLab. The push is blocked if secrets are detected, unless you skip secret push protection.
|
||||
This method reduces the risk of secrets being leaked.
|
||||
- [Pipeline secret detection](pipeline/index.md) runs as part of a project's CI/CD pipeline. Commits
|
||||
to the repository's default branch are scanned for secrets. If pipeline secret detection is
|
||||
enabled in merge request pipelines, commits to the development branch are scanned for secrets,
|
||||
enabling you to respond before they're committed to the default branch.
|
||||
- [Client-side secret detection](client/index.md) scans descriptions and comments in both issues and
|
||||
merge requests for secrets before they're saved to GitLab. When a secret is detected you can
|
||||
choose to edit the input and remove the secret or, if it's a false positive, save the description
|
||||
or comment.
|
||||
|
||||
If a secret is committed to a repository, GitLab records the exposure
|
||||
in the Vulnerability Report. For some secret types, GitLab can even
|
||||
|
|
|
|||
|
|
@ -9,20 +9,6 @@ module Gitlab
|
|||
# has been completed. Sessions can be used to keep track of what hosts
|
||||
# should be used for queries.
|
||||
class Session
|
||||
CACHE_KEY = :gitlab_load_balancer_session
|
||||
|
||||
def self.current
|
||||
RequestStore[CACHE_KEY] ||= new
|
||||
end
|
||||
|
||||
def self.clear_session
|
||||
RequestStore.delete(CACHE_KEY)
|
||||
end
|
||||
|
||||
def self.without_sticky_writes(&block)
|
||||
current.ignore_writes(&block)
|
||||
end
|
||||
|
||||
def initialize
|
||||
@use_primary = false
|
||||
@performed_write = false
|
||||
|
|
|
|||
|
|
@ -10,45 +10,24 @@ module Gitlab
|
|||
|
||||
# lb - Gitlab::Database::LoadBalancing::LoadBalancer instance
|
||||
def self.current(load_balancer)
|
||||
return Session.current unless use_session_map?
|
||||
|
||||
cached_instance.lookup(load_balancer)
|
||||
end
|
||||
|
||||
# models - Array<ActiveRecord::Base>
|
||||
def self.with_sessions(models)
|
||||
return Session.current unless use_session_map?
|
||||
|
||||
dbs = models.map { |m| m.load_balancer.name }.uniq
|
||||
dbs.each { |db| cached_instance.validate_db_name(db) }
|
||||
ScopedSessions.new(dbs, cached_instance.session_map)
|
||||
end
|
||||
|
||||
def self.clear_session
|
||||
return Session.clear_session unless use_session_map?
|
||||
|
||||
RequestStore.delete(CACHE_KEY)
|
||||
end
|
||||
|
||||
def self.without_sticky_writes(&)
|
||||
return Session.without_sticky_writes(&) unless use_session_map?
|
||||
|
||||
with_sessions(Gitlab::Database::LoadBalancing.base_models).ignore_writes(&)
|
||||
end
|
||||
|
||||
def self.use_session_map?
|
||||
::Feature.enabled?(:use_load_balancing_session_map, :current_request, type: :gitlab_com_derisk)
|
||||
rescue ActiveRecord::StatementInvalid,
|
||||
Gitlab::Database::QueryAnalyzers::Base::QueryAnalyzerError
|
||||
# If the feature_gates table is missing, we should default to a false.
|
||||
# In a migration scope, we also rescue and default to false.
|
||||
false
|
||||
rescue StandardError => e
|
||||
::Gitlab::ErrorTracking.track_exception(e)
|
||||
false
|
||||
end
|
||||
private_class_method :use_session_map?
|
||||
|
||||
def self.cached_instance
|
||||
RequestStore[CACHE_KEY] ||= new
|
||||
end
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ module Gitlab
|
|||
|
||||
def self.for_tables(tables)
|
||||
Gitlab::Database::LoadBalancing::SessionMap
|
||||
.current(connection.load_balancer)
|
||||
.current(load_balancer)
|
||||
.use_primary do
|
||||
# calling `.to_a` here to execute the query in the primary's scope
|
||||
# and to avoid having the scope chained and re-executed
|
||||
|
|
|
|||
|
|
@ -541,7 +541,8 @@ module Gitlab
|
|||
h[k] = {
|
||||
signature: +''.b,
|
||||
signed_text: +''.b,
|
||||
signer: :SIGNER_UNSPECIFIED
|
||||
signer: :SIGNER_UNSPECIFIED,
|
||||
author_email: +''.b
|
||||
}
|
||||
end
|
||||
|
||||
|
|
@ -552,6 +553,7 @@ module Gitlab
|
|||
|
||||
signatures[current_commit_id][:signature] << message.signature
|
||||
signatures[current_commit_id][:signed_text] << message.signed_text
|
||||
signatures[current_commit_id][:author_email] << message.author.email if message.author.present?
|
||||
|
||||
# The actual value is send once. All the other chunks send SIGNER_UNSPECIFIED
|
||||
signatures[current_commit_id][:signer] = message.signer unless message.signer == :SIGNER_UNSPECIFIED
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ module Gitlab
|
|||
class EventDefinitionValidator
|
||||
EVENT_SCHEMA_PATH = Rails.root.join('config/events/schema.json')
|
||||
SCHEMA = ::JSONSchemer.schema(EVENT_SCHEMA_PATH)
|
||||
NOT_VALIDATED_PROPERTIES = [:value].freeze
|
||||
|
||||
def initialize(definition)
|
||||
@attributes = definition.attributes
|
||||
|
|
@ -13,37 +12,6 @@ module Gitlab
|
|||
end
|
||||
|
||||
def validation_errors
|
||||
(validate_schema << validate_additional_properties).compact
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :attributes, :path
|
||||
|
||||
def validate_additional_properties
|
||||
additional_props = attributes[:additional_properties]&.map { |k, _| k }
|
||||
|
||||
return unless additional_props.present?
|
||||
|
||||
extra_props = additional_props - Gitlab::Tracking::EventValidator::BASE_ADDITIONAL_PROPERTIES.keys
|
||||
unused_props = prioritized_properties - additional_props
|
||||
|
||||
return unless extra_props.present? && unused_props.present?
|
||||
|
||||
<<~ERROR_MSG
|
||||
--------------- VALIDATION ERROR ---------------
|
||||
Definition file: #{path}
|
||||
Error type: consider using the built-in additional properties:
|
||||
"#{prioritized_properties.join(', ')}"
|
||||
before adding custom extra properties: #{extra_props.join(', ')}
|
||||
ERROR_MSG
|
||||
end
|
||||
|
||||
def prioritized_properties
|
||||
Gitlab::Tracking::EventValidator::BASE_ADDITIONAL_PROPERTIES.keys - NOT_VALIDATED_PROPERTIES
|
||||
end
|
||||
|
||||
def validate_schema
|
||||
SCHEMA.validate(attributes.deep_stringify_keys).map do |error|
|
||||
<<~ERROR_MSG
|
||||
--------------- VALIDATION ERROR ---------------
|
||||
|
|
@ -51,10 +19,14 @@ module Gitlab
|
|||
Error type: #{error['type']}
|
||||
Data: #{error['data']}
|
||||
Path: #{error['data_pointer']}
|
||||
Details: #{error['details']}
|
||||
Details: #{error['details'] || error['error']}
|
||||
ERROR_MSG
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
attr_reader :attributes, :path
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
OUTPUT_FILE = 'doc/update/breaking_window.md'
|
||||
OUTPUT_FILE = 'doc/update/breaking_windows.md'
|
||||
DEPRECATIONS_PATH = 'data/deprecations'
|
||||
TARGET_MILESTONE = '18.0'
|
||||
|
||||
|
|
@ -37,7 +37,7 @@ def write_metadata(file)
|
|||
stage: none
|
||||
group: none
|
||||
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
|
||||
noindex: false
|
||||
noindex: true
|
||||
---
|
||||
|
||||
# Breaking change deployments on GitLab.com
|
||||
|
|
|
|||
|
|
@ -20656,10 +20656,10 @@ msgstr ""
|
|||
msgid "Edit Password"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit Pipeline Schedule"
|
||||
msgid "Edit Release"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit Release"
|
||||
msgid "Edit Scheduled Pipeline"
|
||||
msgstr ""
|
||||
|
||||
msgid "Edit Slack integration"
|
||||
|
|
@ -40193,7 +40193,7 @@ msgstr ""
|
|||
msgid "PipelineSchedules|An error occurred while updating the pipeline schedule."
|
||||
msgstr ""
|
||||
|
||||
msgid "PipelineSchedules|Are you sure you want to delete this pipeline schedule?"
|
||||
msgid "PipelineSchedules|Are you sure you want to delete this scheduled pipeline?"
|
||||
msgstr ""
|
||||
|
||||
msgid "PipelineSchedules|Can have custom CI/CD variables."
|
||||
|
|
@ -40208,13 +40208,13 @@ msgstr ""
|
|||
msgid "PipelineSchedules|Cron timezone"
|
||||
msgstr ""
|
||||
|
||||
msgid "PipelineSchedules|Delete pipeline schedule"
|
||||
msgid "PipelineSchedules|Delete scheduled pipeline"
|
||||
msgstr ""
|
||||
|
||||
msgid "PipelineSchedules|Description"
|
||||
msgstr ""
|
||||
|
||||
msgid "PipelineSchedules|Edit pipeline schedule"
|
||||
msgid "PipelineSchedules|Edit scheduled pipeline"
|
||||
msgstr ""
|
||||
|
||||
msgid "PipelineSchedules|Explore plan limits"
|
||||
|
|
@ -40262,7 +40262,7 @@ msgstr ""
|
|||
msgid "PipelineSchedules|Provide a short description for this pipeline"
|
||||
msgstr ""
|
||||
|
||||
msgid "PipelineSchedules|Run pipeline schedule"
|
||||
msgid "PipelineSchedules|Run scheduled pipeline"
|
||||
msgstr ""
|
||||
|
||||
msgid "PipelineSchedules|Runs for a specific branch or tag."
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
ARG GDK_SHA=f14f8f3445959818c1272a9767fefa3b282f59c2
|
||||
ARG GDK_SHA=4d74dc68619bb2f81fb22216fa9ca5d3b15b67bc
|
||||
# Use tag prefix when running on 'stable' branch to make sure 'protected' image is used which is not deleted by registry cleanup
|
||||
ARG GDK_BASE_TAG_PREFIX
|
||||
|
||||
|
|
|
|||
|
|
@ -204,8 +204,6 @@ spec/frontend/ci/catalog/components/ci_catalog_home_spec.js
|
|||
spec/frontend/ci/catalog/components/list/ci_resources_list_item_spec.js
|
||||
spec/frontend/ci/catalog/components/pages/ci_resource_details_page_spec.js
|
||||
spec/frontend/ci/catalog/index_spec.js
|
||||
spec/frontend/ci/ci_variable_list/components/ci_variable_drawer_spec.js
|
||||
spec/frontend/ci/ci_variable_list/components/ci_variable_shared_spec.js
|
||||
spec/frontend/ci/job_details/components/log/line_header_spec.js
|
||||
spec/frontend/ci/job_details/components/log/line_spec.js
|
||||
spec/frontend/ci/job_details/components/log/log_spec.js
|
||||
|
|
@ -426,7 +424,6 @@ spec/frontend/usage_quotas/storage/components/namespace_storage_app_spec.js
|
|||
spec/frontend/users_select/index_spec.js
|
||||
spec/frontend/vue_alerts_spec.js
|
||||
spec/frontend/vue_merge_request_widget/components/checks/conflicts_spec.js
|
||||
spec/frontend/vue_merge_request_widget/components/merge_checks_spec.js
|
||||
spec/frontend/vue_merge_request_widget/components/mr_widget_pipeline_spec.js
|
||||
spec/frontend/vue_merge_request_widget/components/states/merge_failed_pipeline_confirmation_dialog_spec.js
|
||||
spec/frontend/vue_merge_request_widget/components/states/mr_widget_merging_spec.js
|
||||
|
|
|
|||
|
|
@ -489,4 +489,31 @@ RSpec.describe Profiles::TwoFactorAuthsController, feature_category: :system_acc
|
|||
|
||||
it_behaves_like 'user must enter a valid current password'
|
||||
end
|
||||
|
||||
describe 'PATCH skip' do
|
||||
let(:user) { create(:user, otp_grace_period_started_at: Time.zone.now) }
|
||||
|
||||
def request
|
||||
patch :skip
|
||||
end
|
||||
|
||||
before do
|
||||
stub_application_setting(require_two_factor_authentication: true)
|
||||
stub_application_setting(two_factor_grace_period: 24)
|
||||
end
|
||||
|
||||
it 'redirects the user to the root url' do
|
||||
request
|
||||
|
||||
expect(response).to redirect_to root_url
|
||||
end
|
||||
|
||||
it 'redirects back to 2fa page if grace period expired' do
|
||||
travel_to(27.hours.from_now) do
|
||||
request
|
||||
|
||||
expect(response).to redirect_to profile_two_factor_auth_url
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -97,6 +97,22 @@ RSpec.describe 'Two factor auths', feature_category: :system_access do
|
|||
stub_application_setting(require_two_factor_authentication: true)
|
||||
end
|
||||
|
||||
context 'when a grace period is set' do
|
||||
before do
|
||||
stub_application_setting(two_factor_grace_period: 24.hours)
|
||||
end
|
||||
|
||||
it 'allows the user to skip enabling within the grace period', :js do
|
||||
visit root_path
|
||||
|
||||
expect(page).to have_current_path(profile_two_factor_auth_path, ignore_query: true)
|
||||
|
||||
click_link 'Configure it later'
|
||||
|
||||
expect(page).to have_current_path(root_path)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when invalid pin is provided' do
|
||||
let_it_be(:user) { create(:omniauth_user) }
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,7 @@ RSpec.describe 'Pipeline Schedules', :js, feature_category: :continuous_integrat
|
|||
it 'edits the pipeline' do
|
||||
find_by_testid('edit-pipeline-schedule-btn').click
|
||||
|
||||
expect(page).to have_content(s_('PipelineSchedules|Edit Pipeline Schedule'))
|
||||
expect(page).to have_content(s_('PipelineSchedules|Edit Scheduled Pipeline'))
|
||||
expect(page).to have_button(s_('PipelineSchedules|Save changes'))
|
||||
end
|
||||
|
||||
|
|
@ -147,10 +147,10 @@ RSpec.describe 'Pipeline Schedules', :js, feature_category: :continuous_integrat
|
|||
|
||||
it 'deletes the pipeline' do
|
||||
within_testid('pipeline-schedule-table-row') do
|
||||
click_button s_('PipelineSchedules|Delete pipeline schedule')
|
||||
click_button s_('PipelineSchedules|Delete scheduled pipeline')
|
||||
end
|
||||
|
||||
accept_gl_confirm(button_text: s_('PipelineSchedules|Delete pipeline schedule'))
|
||||
accept_gl_confirm(button_text: s_('PipelineSchedules|Delete scheduled pipeline'))
|
||||
|
||||
expect(page).not_to have_css('[data-testid="pipeline-schedule-table-row"]')
|
||||
end
|
||||
|
|
|
|||
|
|
@ -9,6 +9,8 @@ identifiers:
|
|||
additional_properties:
|
||||
label:
|
||||
description: TODO
|
||||
property:
|
||||
description: TODO
|
||||
custom_key1:
|
||||
description: The extra custom property name 1
|
||||
custom_key2:
|
||||
|
|
|
|||
|
|
@ -379,6 +379,7 @@
|
|||
- "\e[B\e[B\e[B" # Arrow down to: Weekly count of unique users where label/value is...
|
||||
- "\n" # Select: Weekly count of unique users where label/value is...
|
||||
- "failure\n" # Input value for "label" filter
|
||||
- " \n" # Ignore whitespace to skip "property" filter
|
||||
- "metrics\n" # Input value for "custom_key1" filter
|
||||
- "\n" # Skip "custom_key2" filter
|
||||
- "30,13\n" # Input value for "custom_key3" filter
|
||||
|
|
|
|||
|
|
@ -254,7 +254,7 @@ describe('CI Variable Drawer', () => {
|
|||
},
|
||||
});
|
||||
|
||||
expect(findVisibilityRadioGroup().attributes('disabled')).toBe('true');
|
||||
expect(findVisibilityRadioGroup().attributes().disabled).toBe('true');
|
||||
});
|
||||
});
|
||||
|
||||
|
|
@ -609,6 +609,7 @@ describe('CI Variable Drawer', () => {
|
|||
],
|
||||
]);
|
||||
expect(wrapper.emitted('close-form')).toBeUndefined();
|
||||
expect(wrapper.findComponent(GlDrawer).element.scrollTo).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import waitForPromises from 'helpers/wait_for_promises';
|
|||
import TodosApp from '~/todos/components/todos_app.vue';
|
||||
import TodoItem from '~/todos/components/todo_item.vue';
|
||||
import TodosFilterBar from '~/todos/components/todos_filter_bar.vue';
|
||||
import TodosMarkAllDoneButton from '~/todos/components/todos_mark_all_done_button.vue';
|
||||
import getTodosQuery from '~/todos/components/queries/get_todos.query.graphql';
|
||||
import { INSTRUMENT_TAB_LABELS, STATUS_BY_TAB } from '~/todos/constants';
|
||||
import { mockTracking, unmockTracking } from 'jest/__helpers__/tracking_helper';
|
||||
|
|
@ -37,6 +38,7 @@ describe('TodosApp', () => {
|
|||
const findTodoItems = () => wrapper.findAllComponents(TodoItem);
|
||||
const findGlTabs = () => wrapper.findComponent(GlTabs);
|
||||
const findFilterBar = () => wrapper.findComponent(TodosFilterBar);
|
||||
const findMarkAllDoneButton = () => wrapper.findComponent(TodosMarkAllDoneButton);
|
||||
const findPendingTodosCount = () => wrapper.findByTestId('pending-todos-count');
|
||||
|
||||
it('should have a tracking event for each tab', () => {
|
||||
|
|
@ -83,6 +85,17 @@ describe('TodosApp', () => {
|
|||
expect(todosCountsQuerySuccessHandler).toHaveBeenLastCalledWith(filters);
|
||||
});
|
||||
|
||||
it('re-fetches the pending todos count when mark all done button is clicked', async () => {
|
||||
createComponent();
|
||||
await waitForPromises();
|
||||
|
||||
expect(todosCountsQuerySuccessHandler).toHaveBeenCalledTimes(1);
|
||||
|
||||
findMarkAllDoneButton().vm.$emit('change');
|
||||
|
||||
expect(todosCountsQuerySuccessHandler).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
|
||||
it('shows the pending todos count once it has been fetched', async () => {
|
||||
createComponent();
|
||||
|
||||
|
|
|
|||
|
|
@ -177,7 +177,7 @@ describe('Merge request merge checks component', () => {
|
|||
});
|
||||
|
||||
it('sorts merge checks', async () => {
|
||||
mountComponent({
|
||||
shallowMountComponent({
|
||||
mergeabilityChecks: [
|
||||
{ identifier: 'discussions_not_resolved', status: 'SUCCESS' },
|
||||
{ identifier: 'status_checks_must_pass', status: 'INACTIVE' },
|
||||
|
|
@ -187,15 +187,11 @@ describe('Merge request merge checks component', () => {
|
|||
|
||||
await waitForPromises();
|
||||
|
||||
await wrapper.findByTestId('widget-toggle').trigger('click');
|
||||
wrapper.vm.toggleCollapsed();
|
||||
|
||||
const mergeChecks = wrapper.findAllByTestId('merge-check');
|
||||
|
||||
expect(mergeChecks.length).toBe(2);
|
||||
expect(mergeChecks.at(0).props('check')).toEqual(expect.objectContaining({ status: 'FAILED' }));
|
||||
expect(mergeChecks.at(1).props('check')).toEqual(
|
||||
expect.objectContaining({ status: 'SUCCESS' }),
|
||||
);
|
||||
expect(wrapper.vm.sortedChecks.length).toBe(2);
|
||||
expect(wrapper.vm.sortedChecks[0].status).toBe('FAILED');
|
||||
expect(wrapper.vm.sortedChecks[1].status).toBe('SUCCESS');
|
||||
});
|
||||
|
||||
it('does not render check component if no message exists', async () => {
|
||||
|
|
@ -210,6 +206,8 @@ describe('Merge request merge checks component', () => {
|
|||
|
||||
await wrapper.findByTestId('widget-toggle').trigger('click');
|
||||
|
||||
await waitForPromises();
|
||||
|
||||
const mergeChecks = wrapper.findAllByTestId('merge-check');
|
||||
|
||||
expect(mergeChecks.length).toBe(1);
|
||||
|
|
@ -266,7 +264,7 @@ describe('Merge request merge checks component', () => {
|
|||
});
|
||||
|
||||
it('renders checking text', () => {
|
||||
expect(wrapper.text()).toBe('Checking if merge request can be merged...');
|
||||
expect(wrapper.text()).toContain('Checking if merge request can be merged...');
|
||||
});
|
||||
|
||||
it('renders checks expanded by default', () => {
|
||||
|
|
|
|||
|
|
@ -560,11 +560,6 @@ RSpec.describe Feature, :clean_gitlab_redis_feature_flag, stub_feature_flags: fa
|
|||
|
||||
context 'and feature has been disabled' do
|
||||
before do
|
||||
# TODO: revert changes to .once when removing use_load_balancing_session_map feature flag
|
||||
# We stub SessionMap.current since it uses a feature flag. Within this spec, all feature flags
|
||||
# definitions are missing due to the stubbed Feature::Definition.definitions method.
|
||||
allow(Gitlab::Database::LoadBalancing::SessionMap)
|
||||
.to receive(:current).and_return(Gitlab::Database::LoadBalancing::Session.current)
|
||||
described_class.disable(:my_feature_flag)
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -13,8 +13,7 @@ RSpec.describe Gitlab::Auth::TokenExpirationBanner, feature_category: :system_ac
|
|||
# for specs, we need to reset it each time
|
||||
before do
|
||||
described_class.instance_variable_set(:@show_token_expiration_banner, nil)
|
||||
# TODO: revert changes to .twice when removing use_load_balancing_session_map feature flag https://gitlab.com/gitlab-org/gitlab/-/issues/496505
|
||||
allow(Gitlab).to receive(:version_info).at_least(:twice).and_return(gitlab_version)
|
||||
allow(Gitlab).to receive(:version_info).twice.and_return(gitlab_version)
|
||||
end
|
||||
|
||||
it { is_expected.to be(false) }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::BackgroundMigration::BackfillIssuesCorrectWorkItemTypeId, feature_category: :team_planning do
|
||||
RSpec.describe Gitlab::BackgroundMigration::BackfillIssuesCorrectWorkItemTypeId,
|
||||
feature_category: :team_planning,
|
||||
schema: 20241030165330 do
|
||||
let(:batch_column) { 'id' }
|
||||
let(:sub_batch_size) { 2 }
|
||||
let(:pause_ms) { 0 }
|
||||
|
|
|
|||
|
|
@ -12,29 +12,6 @@ RSpec.describe Gitlab::Database::LoadBalancing::SessionMap, feature_category: :d
|
|||
described_class.clear_session
|
||||
end
|
||||
|
||||
context 'when feature flag is disabled' do
|
||||
before do
|
||||
described_class.current(lb) # initialise a SessionMap
|
||||
stub_feature_flags(use_load_balancing_session_map: false)
|
||||
end
|
||||
|
||||
it 'returns sessions from Gitlab::Database::LoadBalancing::Session.current' do
|
||||
expect(described_class.current(lb)).to eq(Gitlab::Database::LoadBalancing::Session.current)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when feature flag lookup returns unexpected error' do
|
||||
before do
|
||||
allow(Feature).to receive(:enabled?).and_raise(StandardError)
|
||||
end
|
||||
|
||||
it 'tracks exception and return false' do
|
||||
# behaves as if feature flag is disabled
|
||||
expect(Gitlab::ErrorTracking).to receive(:track_exception).with(StandardError)
|
||||
expect(described_class.current(lb)).to eq(Gitlab::Database::LoadBalancing::Session.current)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when already initialised' do
|
||||
before do
|
||||
described_class.current(lb)
|
||||
|
|
@ -141,21 +118,6 @@ RSpec.describe Gitlab::Database::LoadBalancing::SessionMap, feature_category: :d
|
|||
|
||||
expect(RequestStore[described_class::CACHE_KEY]).to eq(nil)
|
||||
end
|
||||
|
||||
context 'when feature flag is disabled' do
|
||||
before do
|
||||
described_class.current(lb) # initialise a SessionMap
|
||||
stub_feature_flags(use_load_balancing_session_map: false)
|
||||
end
|
||||
|
||||
it 'clears session from Gitlab::Database::LoadBalancing::Session.current' do
|
||||
expect(Gitlab::Database::LoadBalancing::Session.current).not_to eq(nil)
|
||||
|
||||
described_class.clear_session
|
||||
|
||||
expect(RequestStore[Gitlab::Database::LoadBalancing::Session::CACHE_KEY]).to eq(nil)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.without_sticky_writes' do
|
||||
|
|
@ -181,20 +143,6 @@ RSpec.describe Gitlab::Database::LoadBalancing::SessionMap, feature_category: :d
|
|||
# exact logic for ignore_writes is tested in `.with_sessions` test suite
|
||||
end
|
||||
end
|
||||
|
||||
context 'when feature flag is disabled' do
|
||||
before do
|
||||
stub_feature_flags(use_load_balancing_session_map: false)
|
||||
end
|
||||
|
||||
it 'calls Gitlab::Database::LoadBalancing::Session instead' do
|
||||
expect(Gitlab::Database::LoadBalancing::Session).to receive(:without_sticky_writes).and_yield
|
||||
|
||||
described_class.without_sticky_writes do
|
||||
# exact logic for ignore_writes is tested in `.with_sessions` test suite
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '.with_sessions' do
|
||||
|
|
@ -231,17 +179,6 @@ RSpec.describe Gitlab::Database::LoadBalancing::SessionMap, feature_category: :d
|
|||
end.to raise_error(instance_of(described_class::InvalidLoadBalancerNameError))
|
||||
end
|
||||
|
||||
context 'when use_load_balancing_session_map is disabled' do
|
||||
before do
|
||||
stub_feature_flags(use_load_balancing_session_map: false)
|
||||
end
|
||||
|
||||
it 'returns Session instead of ScopedSession' do
|
||||
expect(with_sessions)
|
||||
.to be_an_instance_of(Gitlab::Database::LoadBalancing::Session)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when calling use_primary!' do
|
||||
it 'applies use_primary! to all sessions' do
|
||||
with_sessions.use_primary!
|
||||
|
|
|
|||
|
|
@ -3,47 +3,6 @@
|
|||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Gitlab::Database::LoadBalancing::Session do
|
||||
after do
|
||||
described_class.clear_session
|
||||
end
|
||||
|
||||
describe '.current' do
|
||||
it 'returns the current session' do
|
||||
expect(described_class.current).to be_an_instance_of(described_class)
|
||||
end
|
||||
end
|
||||
|
||||
describe '.clear_session' do
|
||||
it 'clears the current session' do
|
||||
described_class.current
|
||||
described_class.clear_session
|
||||
|
||||
expect(RequestStore[described_class::CACHE_KEY]).to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '.without_sticky_writes' do
|
||||
it 'ignores sticky write events sent by a connection proxy' do
|
||||
described_class.without_sticky_writes do
|
||||
described_class.current.write!
|
||||
end
|
||||
|
||||
session = described_class.current
|
||||
|
||||
expect(session).not_to be_using_primary
|
||||
end
|
||||
|
||||
it 'still is aware of write that happened' do
|
||||
described_class.without_sticky_writes do
|
||||
described_class.current.write!
|
||||
end
|
||||
|
||||
session = described_class.current
|
||||
|
||||
expect(session.performed_write?).to be true
|
||||
end
|
||||
end
|
||||
|
||||
describe '#use_primary?' do
|
||||
it 'returns true when the primary should be used' do
|
||||
instance = described_class.new
|
||||
|
|
|
|||
|
|
@ -1251,12 +1251,14 @@ RSpec.describe Gitlab::GitalyClient::CommitService, feature_category: :gitaly do
|
|||
[large_signed_text, *signed_by_user].each do |commit_id|
|
||||
expect(signatures[commit_id][:signature]).to be_present
|
||||
expect(signatures[commit_id][:signer]).to eq(:SIGNER_USER)
|
||||
expect(signatures[commit_id][:author_email]).to be_present
|
||||
end
|
||||
|
||||
signed_by_user.each do |commit_id|
|
||||
commit = project.commit(commit_id)
|
||||
expect(signatures[commit_id][:signed_text]).to include(commit.message)
|
||||
expect(signatures[commit_id][:signed_text]).to include(commit.description)
|
||||
expect(signatures[commit_id][:author_email]).to eq(commit.author_email)
|
||||
end
|
||||
|
||||
expect(signatures[large_signed_text][:signed_text].size).to eq(4971878)
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ RSpec.describe Gitlab::Tracking::EventDefinitionValidator, feature_category: :se
|
|||
|
||||
let(:path) { File.join('events', 'issues_create.yml') }
|
||||
let(:definition) { Gitlab::Tracking::EventDefinition.new(path, attributes) }
|
||||
# let(:yaml_content) { attributes.deep_stringify_keys.to_yaml }
|
||||
|
||||
describe '#validate' do
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
|
@ -69,15 +68,21 @@ RSpec.describe Gitlab::Tracking::EventDefinitionValidator, feature_category: :se
|
|||
where(:label, :property, :value, :custom, :error?) do
|
||||
true | true | true | true | false
|
||||
true | true | true | false | false
|
||||
true | true | false | false | false
|
||||
true | true | false | true | false
|
||||
true | false | false | false | false
|
||||
false | true | false | false | false
|
||||
false | true | true | false | false
|
||||
true | false | true | true | true
|
||||
true | true | false | false | false
|
||||
true | false | true | true | false
|
||||
true | false | true | false | false
|
||||
true | false | false | true | true
|
||||
false | true | true | true | true
|
||||
false | false | true | true | true
|
||||
true | false | false | false | false
|
||||
false | true | true | true | false
|
||||
false | true | true | false | false
|
||||
false | true | false | true | true
|
||||
false | true | false | false | false
|
||||
false | false | true | true | false
|
||||
false | false | true | false | false
|
||||
false | false | false | true | true
|
||||
false | false | false | false | false
|
||||
nil | nil | nil | nil | false
|
||||
end
|
||||
|
||||
with_them do
|
||||
|
|
@ -86,6 +91,8 @@ RSpec.describe Gitlab::Tracking::EventDefinitionValidator, feature_category: :se
|
|||
attributes[:additional_properties][:property] = { description: "button state" } if property
|
||||
attributes[:additional_properties][:value] = { description: "package version" } if value
|
||||
attributes[:additional_properties][:custom] = { description: "custom" } if custom
|
||||
|
||||
attributes.delete(:additional_properties) if [label, property, value, custom].all?(&:nil?)
|
||||
end
|
||||
|
||||
subject { described_class.new(definition).validation_errors.any? }
|
||||
|
|
|
|||
Loading…
Reference in New Issue