Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-11-25 18:15:41 +00:00
parent 3fac94e4e2
commit 06a3c48b66
46 changed files with 233 additions and 122 deletions

View File

@ -93,6 +93,7 @@ release-environments-qa:
parallel: 3
variables:
QA_SCENARIO: "Test::Instance::Smoke"
QA_NO_ADMIN_ENV: true
RELEASE: "${CI_REGISTRY}/${CI_PROJECT_PATH}/gitlab-ee-qa:${CI_COMMIT_SHA}"
GITLAB_QA_OPTS: --address "https://gitlab.${ENVIRONMENT}.release.gke.gitlab.net"
GITLAB_INITIAL_ROOT_PASSWORD: "${RELEASE_ENVIRONMENTS_ROOT_PASSWORD}"

View File

@ -385,7 +385,6 @@ RSpec/FeatureCategory:
- 'ee/spec/helpers/ee/system_note_helper_spec.rb'
- 'ee/spec/helpers/ee/todos_helper_spec.rb'
- 'ee/spec/helpers/ee/users/callouts_helper_spec.rb'
- 'ee/spec/helpers/ee/wiki_helper_spec.rb'
- 'ee/spec/helpers/epics_helper_spec.rb'
- 'ee/spec/helpers/gitlab_subscriptions/upcoming_reconciliation_helper_spec.rb'
- 'ee/spec/helpers/groups/ldap_sync_helper_spec.rb'
@ -1924,7 +1923,6 @@ RSpec/FeatureCategory:
- 'spec/lib/api/entities/release_spec.rb'
- 'spec/lib/api/entities/user_counts_spec.rb'
- 'spec/lib/api/entities/user_spec.rb'
- 'spec/lib/api/entities/wiki_page_spec.rb'
- 'spec/lib/api/helpers/authentication_spec.rb'
- 'spec/lib/api/helpers/caching_spec.rb'
- 'spec/lib/api/helpers/common_helpers_spec.rb'
@ -2376,7 +2374,6 @@ RSpec/FeatureCategory:
- 'spec/lib/gitlab/data_builder/feature_flag_spec.rb'
- 'spec/lib/gitlab/data_builder/issuable_spec.rb'
- 'spec/lib/gitlab/data_builder/push_spec.rb'
- 'spec/lib/gitlab/data_builder/wiki_page_spec.rb'
- 'spec/lib/gitlab/database/background_migration/batch_metrics_spec.rb'
- 'spec/lib/gitlab/database/background_migration/batch_optimizer_spec.rb'
- 'spec/lib/gitlab/database/background_migration/batched_job_spec.rb'
@ -3156,7 +3153,6 @@ RSpec/FeatureCategory:
- 'spec/lib/gitlab/webpack/file_loader_spec.rb'
- 'spec/lib/gitlab/webpack/graphql_known_operations_spec.rb'
- 'spec/lib/gitlab/webpack/manifest_spec.rb'
- 'spec/lib/gitlab/wiki_pages/front_matter_parser_spec.rb'
- 'spec/lib/gitlab/word_diff/chunk_collection_spec.rb'
- 'spec/lib/gitlab/word_diff/line_processor_spec.rb'
- 'spec/lib/gitlab/word_diff/parser_spec.rb'
@ -3435,7 +3431,6 @@ RSpec/FeatureCategory:
- 'spec/models/integrations/chat_message/wiki_page_message_spec.rb'
- 'spec/models/integrations/emails_on_push_spec.rb'
- 'spec/models/integrations/ewm_spec.rb'
- 'spec/models/integrations/external_wiki_spec.rb'
- 'spec/models/integrations/harbor_spec.rb'
- 'spec/models/integrations/issue_tracker_data_spec.rb'
- 'spec/models/integrations/jira_tracker_data_spec.rb'
@ -3564,7 +3559,6 @@ RSpec/FeatureCategory:
- 'spec/models/web_ide_terminal_spec.rb'
- 'spec/models/webauthn_registration_spec.rb'
- 'spec/models/wiki_directory_spec.rb'
- 'spec/models/wiki_page/slug_spec.rb'
- 'spec/models/work_items/hierarchy_restriction_spec.rb'
- 'spec/models/work_items/widgets/assignees_spec.rb'
- 'spec/models/work_items/widgets/base_spec.rb'
@ -4152,7 +4146,6 @@ RSpec/FeatureCategory:
- 'spec/views/shared/snippets/_snippet.html.haml_spec.rb'
- 'spec/views/shared/ssh_keys/_key_delete.html.haml_spec.rb'
- 'spec/views/shared/web_hooks/_web_hook_disabled_alert.html.haml_spec.rb'
- 'spec/views/shared/wikis/_sidebar.html.haml_spec.rb'
- 'spec/workers/concerns/reenqueuer_spec.rb'
- 'spec/workers/packages/maven/metadata/sync_worker_spec.rb'
- 'spec/workers/propagate_integration_project_worker_spec.rb'

View File

@ -770,7 +770,7 @@
{"name":"webauthn","version":"3.0.0","platform":"ruby","checksum":"3f77d422c2a8a4b31e56cf42f83414bd066e0506e9896936e1730262dc4a20e6"},
{"name":"webfinger","version":"2.1.3","platform":"ruby","checksum":"567a52bde77fb38ca6b67e55db755f988766ec4651c1d24916a65aa70540695c"},
{"name":"webmock","version":"3.24.0","platform":"ruby","checksum":"be01357f6fc773606337ca79f3ba332b7d52cbe5c27587671abc0572dbec7122"},
{"name":"webrick","version":"1.8.1","platform":"ruby","checksum":"19411ec6912911fd3df13559110127ea2badd0c035f7762873f58afc803e158f"},
{"name":"webrick","version":"1.8.2","platform":"ruby","checksum":"431746a349199546ff9dd272cae10849c865f938216e41c402a6489248f12f21"},
{"name":"websocket","version":"1.2.10","platform":"ruby","checksum":"2cc1a4a79b6e63637b326b4273e46adcddf7871caa5dc5711f2ca4061a629fa8"},
{"name":"websocket-driver","version":"0.7.6","platform":"java","checksum":"bc894b9e9d5aee55ac04b61003e1957c4ef411a5a048199587d0499785b505c3"},
{"name":"websocket-driver","version":"0.7.6","platform":"ruby","checksum":"f69400be7bc197879726ad8e6f5869a61823147372fd8928836a53c2c741d0db"},

View File

@ -1943,7 +1943,7 @@ GEM
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.8.1)
webrick (1.8.2)
websocket (1.2.10)
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)

View File

@ -782,7 +782,7 @@
{"name":"webauthn","version":"3.0.0","platform":"ruby","checksum":"3f77d422c2a8a4b31e56cf42f83414bd066e0506e9896936e1730262dc4a20e6"},
{"name":"webfinger","version":"2.1.3","platform":"ruby","checksum":"567a52bde77fb38ca6b67e55db755f988766ec4651c1d24916a65aa70540695c"},
{"name":"webmock","version":"3.24.0","platform":"ruby","checksum":"be01357f6fc773606337ca79f3ba332b7d52cbe5c27587671abc0572dbec7122"},
{"name":"webrick","version":"1.8.1","platform":"ruby","checksum":"19411ec6912911fd3df13559110127ea2badd0c035f7762873f58afc803e158f"},
{"name":"webrick","version":"1.8.2","platform":"ruby","checksum":"431746a349199546ff9dd272cae10849c865f938216e41c402a6489248f12f21"},
{"name":"websocket","version":"1.2.10","platform":"ruby","checksum":"2cc1a4a79b6e63637b326b4273e46adcddf7871caa5dc5711f2ca4061a629fa8"},
{"name":"websocket-driver","version":"0.7.6","platform":"java","checksum":"bc894b9e9d5aee55ac04b61003e1957c4ef411a5a048199587d0499785b505c3"},
{"name":"websocket-driver","version":"0.7.6","platform":"ruby","checksum":"f69400be7bc197879726ad8e6f5869a61823147372fd8928836a53c2c741d0db"},

View File

@ -1970,7 +1970,7 @@ GEM
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.8.1)
webrick (1.8.2)
websocket (1.2.10)
websocket-driver (0.7.6)
websocket-extensions (>= 0.1.0)

View File

@ -1,15 +1,24 @@
<script>
import { GlDisclosureDropdown, GlButton, GlIcon, GlForm, GlFormRadioGroup } from '@gitlab/ui';
import {
GlDisclosureDropdown,
GlButton,
GlIcon,
GlForm,
GlFormRadioGroup,
GlLoadingIcon,
} from '@gitlab/ui';
// eslint-disable-next-line no-restricted-imports
import { mapGetters, mapActions, mapState } from 'vuex';
import { __ } from '~/locale';
import { createAlert } from '~/alert';
import MarkdownEditor from '~/vue_shared/components/markdown/markdown_editor.vue';
import MarkdownHeaderDivider from '~/vue_shared/components/markdown/header_divider.vue';
import { scrollToElement } from '~/lib/utils/common_utils';
import { fetchPolicies } from '~/lib/graphql';
import { CLEAR_AUTOSAVE_ENTRY_EVENT } from '~/vue_shared/constants';
import { CLEAR_AUTOSAVE_ENTRY_EVENT, CONTENT_EDITOR_PASTE } from '~/vue_shared/constants';
import markdownEditorEventHub from '~/vue_shared/components/markdown/eventhub';
import { trackSavedUsingEditor } from '~/vue_shared/components/markdown/tracking';
import { updateText } from '~/lib/utils/text_markdown';
import userCanApproveQuery from '../queries/can_approve.query.graphql';
export default {
@ -35,7 +44,9 @@ export default {
GlIcon,
GlForm,
GlFormRadioGroup,
GlLoadingIcon,
MarkdownEditor,
MarkdownHeaderDivider,
ApprovalPassword: () => import('ee_component/batch_comments/components/approval_password.vue'),
SummarizeMyReview: () =>
import('ee_component/batch_comments/components/summarize_my_review.vue'),
@ -46,6 +57,7 @@ export default {
data() {
return {
isSubmitting: false,
summarizeReviewLoading: false,
dropdownVisible: false,
noteData: {
noteable_type: '',
@ -183,7 +195,18 @@ export default {
}
},
updateNote(note) {
this.noteData.note = note;
const textArea = this.$el.querySelector('textarea');
if (textArea) {
updateText({
textArea,
tag: note,
cursorOffset: 0,
wrap: false,
});
} else {
markdownEditorEventHub.$emit(CONTENT_EDITOR_PASTE, note);
}
},
onBeforeClose({ originalEvent: { target }, preventDefault }) {
if (
@ -231,12 +254,6 @@ export default {
<label for="review-note-body" class="gl-mb-0">
{{ __('Summary comment (optional)') }}
</label>
<summarize-my-review
v-if="canSummarize"
:id="getNoteableData.id"
class="gl-ml-auto"
@input="updateNote"
/>
</div>
<div class="common-note-form gfm-form">
<markdown-editor
@ -257,7 +274,22 @@ export default {
@input="$emit('input', $event)"
@keydown.meta.enter="submitReview"
@keydown.ctrl.enter="submitReview"
/>
>
<template v-if="canSummarize" #header-buttons>
<markdown-header-divider class="gl-ml-2" />
<summarize-my-review
:id="getNoteableData.id"
v-model="summarizeReviewLoading"
@input="updateNote"
/>
</template>
<template v-if="summarizeReviewLoading" #toolbar>
<div class="gl-ml-auto gl-mr-2 gl-inline-flex">
{{ __('Generating review summary') }}
<gl-loading-icon class="gl-ml-2 gl-mt-2" />
</div>
</template>
</markdown-editor>
</div>
<gl-form-radio-group
v-model="noteData.reviewer_state"

View File

@ -263,7 +263,9 @@ export default {
:supports-quick-actions="supportsQuickActions"
:hide-attachment-button="disableAttachments"
@enableMarkdownEditor="$emit('enableMarkdownEditor')"
/>
>
<template #header-buttons><slot name="header-buttons"></slot></template>
</formatting-toolbar>
<div v-if="showPlaceholder" class="gl-absolute gl-px-5 gl-pt-4 gl-text-gray-400">
{{ placeholder }}
</div>
@ -283,6 +285,7 @@ export default {
class="gl-border-t gl-flex gl-flex-row gl-items-center gl-justify-between gl-rounded-bl-base gl-rounded-br-base gl-border-gray-100 gl-px-2 gl-text-secondary"
>
<editor-mode-switcher size="small" value="richText" @switch="handleEditorModeChanged" />
<slot name="toolbar"></slot>
<gl-button
v-gl-tooltip
icon="markdown-mark"

View File

@ -214,5 +214,6 @@ export default {
<header-divider />
<summarize-code-changes />
</div>
<slot name="header-buttons"></slot>
</div>
</template>

View File

@ -139,7 +139,7 @@ export default {
:disabled="disabled"
searchable
class="dropdown-target-project gl-w-full"
:toggle-class="['!gl-items-start !gl-justify-start mr-compare-dropdown', toggleClass]"
:toggle-class="['mr-compare-dropdown', toggleClass]"
@shown="fetchData"
@search="searchData"
@select="selectItem"

View File

@ -99,7 +99,7 @@ export default {
return this.queryVariables;
},
update(data) {
return data[this.graphqlResource]?.containerRepositories.nodes;
return data[this.graphqlResource]?.containerRepositories?.nodes ?? [];
},
result({ data }) {
if (!data) {
@ -122,7 +122,7 @@ export default {
return this.queryVariables;
},
update(data) {
return data[this.graphqlResource]?.containerRepositories.nodes;
return data[this.graphqlResource]?.containerRepositories?.nodes ?? [];
},
error() {
createAlert({ message: FETCH_IMAGES_LIST_ERROR_MESSAGE });

View File

@ -242,7 +242,7 @@ export default {
category="secondary"
data-testid="subscribe-button"
:title="notificationTooltip"
class="sidebar-collapsed-icon sidebar-collapsed-container !gl-rounded-none !gl-shadow-none"
class="sidebar-collapsed-icon sidebar-collapsed-container !gl-rounded-none !gl-border-0"
@click="toggleSubscribed"
>
<gl-animated-notification-icon

View File

@ -392,7 +392,9 @@ export default {
@showPreview="showPreview"
@hidePreview="hidePreview"
@handleSuggestDismissed="() => $emit('handleSuggestDismissed')"
/>
>
<template #header-buttons><slot name="header-buttons"></slot></template>
</markdown-header>
<div v-show="!previewMarkdown" class="md-write-holder">
<div class="zen-backdrop">
<slot name="textarea"></slot>
@ -410,7 +412,9 @@ export default {
:show-comment-tool-bar="showCommentToolBar"
:show-content-editor-switcher="showContentEditorSwitcher"
@enableContentEditor="$emit('enableContentEditor')"
/>
>
<template #toolbar><slot name="toolbar"></slot></template>
</markdown-toolbar>
</div>
</div>
<div

View File

@ -568,6 +568,7 @@ export default {
<header-divider />
<summarize-code-changes />
</template>
<slot v-if="!previewMarkdown" name="header-buttons"></slot>
</div>
<div v-if="!previewMarkdown" class="full-screen gl-flex gl-grow gl-justify-end">
<toolbar-button

View File

@ -347,6 +347,8 @@ export default {
@enableContentEditor="onEditingModeChange('contentEditor')"
@handleSuggestDismissed="() => $emit('handleSuggestDismissed')"
>
<template #header-buttons><slot name="header-buttons"></slot></template>
<template #toolbar><slot name="toolbar"></slot></template>
<template #textarea>
<textarea
v-bind="formFieldProps"
@ -383,7 +385,10 @@ export default {
@change="updateMarkdownFromContentEditor"
@keydown="onKeydown"
@enableMarkdownEditor="onEditingModeChange('markdownField')"
/>
>
<template #header-buttons><slot name="header-buttons"></slot></template>
<template #toolbar><slot name="toolbar"></slot></template>
</content-editor>
<input v-bind="formFieldProps" :value="markdown" type="hidden" />
</div>
</div>

View File

@ -124,6 +124,7 @@ export default {
{{ __('Cancel') }}
</gl-button>
</div>
<slot name="toolbar"></slot>
<gl-button
v-if="markdownDocsPath"
v-gl-tooltip

View File

@ -90,12 +90,6 @@
outline: 0;
}
&.btn-sm {
padding: 4px 10px;
font-size: $gl-btn-small-font-size;
line-height: $gl-btn-small-line-height;
}
&.btn-inverted:not(.disabled):not(:disabled) {
&.btn-danger {
@include btn-outline($white, $red-500, $red-500, $red-100, $red-700, $red-500, $red-200, $red-600, $red-800);

View File

@ -597,7 +597,7 @@
height: $sidebar-toggle-height;
margin-top: 0;
margin-left: 0;
border-bottom: 1px solid $border-color;
border-bottom: 1px solid $border-color !important;
border-radius: 0;
}

View File

@ -781,7 +781,7 @@
.submit-review-dropdown-form {
width: calc(100vw - 20px);
max-width: 680px;
max-width: 756px;
}
.submit-review-dropdown-animated {

View File

@ -439,7 +439,6 @@ module ProjectsHelper
end
def show_lfs_misconfiguration_banner?(project)
return false unless Feature.enabled?(:lfs_misconfiguration_banner)
return false unless project.repository
return false unless project.lfs_enabled?

View File

@ -20,6 +20,7 @@ class ProjectMember < Member
joins('INNER JOIN projects ON projects.id = members.source_id')
.where(projects: { namespace_id: groups.select(:id) })
end
scope :with_roles, ->(roles) { where(access_level: roles) }
class << self
def truncate_teams(project_ids)

View File

@ -14,7 +14,7 @@
%aside.right-sidebar.js-right-sidebar.js-issuable-sidebar{ data: { auto_collapse: true, always_show_toggle: true, signed: { in: signed_in }, issuable_type: issuable_type }, class: "#{sidebar_gutter_collapsed_class(is_merge_request)} #{'right-sidebar-merge-requests' if is_merge_request}", 'aria-live' => 'polite', 'aria-label': issuable_type }
.issuable-sidebar{ class: "#{'is-merge-request' if is_merge_request}" }
.issuable-sidebar-header{ class: sidebar_header_classes }
= render Pajamas::ButtonComponent.new(button_options: { class: "gutter-toggle gl-float-right js-sidebar-toggle has-tooltip !gl-shadow-none gl-block #{'gl-mt-2' if notifications_todos_buttons_enabled?}" , type: 'button', 'aria-label' => _('Toggle sidebar'), title: sidebar_gutter_tooltip_text, data: { container: 'body', placement: 'left', boundary: 'viewport' } }) do
= render Pajamas::ButtonComponent.new(button_options: { class: "gutter-toggle gl-float-right js-sidebar-toggle has-tooltip !gl-border-0 gl-block #{'gl-mt-2' if notifications_todos_buttons_enabled?}" , type: 'button', 'aria-label' => _('Toggle sidebar'), title: sidebar_gutter_tooltip_text, data: { container: 'body', placement: 'left', boundary: 'viewport' } }) do
= sidebar_gutter_toggle_icon
- if signed_in
- if !is_merge_request

View File

@ -1,31 +0,0 @@
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index 04591476b72d..aecb81bb664b 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -404,7 +404,6 @@ def show_terraform_banner?(project)
end
def show_lfs_misconfiguration_banner?(project)
- return false unless Feature.enabled?(:lfs_misconfiguration_banner)
return false unless project.repository
return false unless project.lfs_enabled?
diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb
index a6ea3ec16179..ea2fdf3f4ba7 100644
--- a/spec/helpers/projects_helper_spec.rb
+++ b/spec/helpers/projects_helper_spec.rb
@@ -903,14 +903,6 @@ def license_name
it { is_expected.to be_falsey }
end
-
- context 'when lfs_misconfiguration_banner feature flag is disabled' do
- before do
- stub_feature_flags(lfs_misconfiguration_banner: false)
- end
-
- it { is_expected.to be_falsey }
- end
end
context 'when it does have a .gitattributes file' do

View File

@ -1,9 +0,0 @@
---
name: lfs_misconfiguration_banner
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/429467
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/162123
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/477892
milestone: '17.4'
group: group::source code
type: gitlab_com_derisk
default_enabled: false

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
class AddRoleApproversToApprovalMergeRequestRules < Gitlab::Database::Migration[2.2]
milestone '17.6'
disable_ddl_transaction!
CONSTRAINT_NAME = 'check_approval_m_r_rules_allowed_role_approvers_valid_entries'
def up
add_column :approval_merge_request_rules, :role_approvers, :integer, array: true, default: [], null: false
check = "(role_approvers = '{}' OR role_approvers <@ ARRAY[20, 30, 40, 50, 60])"
add_check_constraint :approval_merge_request_rules, check, CONSTRAINT_NAME
end
def down
remove_column :approval_merge_request_rules, :role_approvers
remove_check_constraint :approval_merge_request_rules, CONSTRAINT_NAME
end
end

View File

@ -0,0 +1 @@
65620668f1c525a13ac396adc548b94690d6bdec539b1b705b1c7765f3a818b6

View File

@ -7142,7 +7142,9 @@ CREATE TABLE approval_merge_request_rules (
applicable_post_merge boolean,
project_id bigint,
approval_policy_rule_id bigint,
CONSTRAINT check_6fca5928b2 CHECK ((char_length(section) <= 255))
role_approvers integer[] DEFAULT '{}'::integer[] NOT NULL,
CONSTRAINT check_6fca5928b2 CHECK ((char_length(section) <= 255)),
CONSTRAINT check_approval_m_r_rules_allowed_role_approvers_valid_entries CHECK (((role_approvers = '{}'::integer[]) OR (role_approvers <@ ARRAY[20, 30, 40, 50, 60])))
);
CREATE TABLE approval_merge_request_rules_approved_approvers (

View File

@ -273,6 +273,8 @@ processing is done in a background worker and requires **no downtime**.
::EndTabs
1. If [Geo](../geo/index.md) is enabled, [reverify all job artifacts](../geo/replication/troubleshooting/synchronization_verification.md#reverify-all-components-or-any-ssf-data-type-which-supports-verification).
In some cases, you need to run the [orphan artifact file cleanup Rake task](../../raketasks/cleanup.md#remove-orphan-artifact-files)
to clean up orphaned artifacts.

View File

@ -784,10 +784,10 @@ POST /projects/:id/statuses/:sha
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](rest/index.md#namespaced-paths) |
| `sha` | string | yes | The commit SHA |
| `state` | string | yes | The state of the status. Can be one of the following: `pending`, `running`, `success`, `failed`, `canceled`, `skipped` |
| `ref` | string | no | The `ref` (branch or tag) to which the status refers |
| `ref` | string | no | The `ref` (branch or tag) to which the status refers. Must be 255 characters or fewer. |
| `name` or `context` | string | no | The label to differentiate this status from the status of other systems. Default value is `default` |
| `target_url` | string | no | The target URL to associate with this status |
| `description` | string | no | The short description of the status |
| `target_url` | string | no | The target URL to associate with this status. Must be 255 characters or fewer. |
| `description` | string | no | The short description of the status. Must be 255 characters or fewer. |
| `coverage` | float | no | The total code coverage |
| `pipeline_id` | integer | no | The ID of the pipeline to set status. Use in case of several pipeline on same SHA. |

View File

@ -5125,6 +5125,7 @@ job4:
**Additional details**:
- The stage name must be 255 characters or fewer.
- Jobs can run in parallel if they run on different runners.
- If you have only one runner, jobs can run in parallel if the runner's
[`concurrent` setting](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#the-global-section)

View File

@ -1006,6 +1006,11 @@ The **upstream project** (also known as the **source project**) and the **fork**
If the **fork relationship** is removed, the
**fork** is **unlinked** from the **upstream project**.
## Free
Use **Free**, in uppercase, for the subscription tier. When you refer to **Free**
in the context of other subscription tiers, follow [the subscription tier](#subscription-tier) guidance.
## full screen
Use two words for **full screen**.

View File

@ -85,10 +85,10 @@ You are excluded from quarterly reconciliation if you:
- Purchased your subscription with a purchasing order.
- Are a public sector customer.
- Have an offline environment and used a license file to activate your subscription.
- Are enrolled in a program that provides a free tier such as the GitLab for Education,
- Are enrolled in a program that provides a Free tier such as the GitLab for Education,
GitLab for Open Source Program, or GitLab for Startups.
If you are excluded from quarterly reconciliation and not on a free tier, your true-ups are reconciled annually.
If you are excluded from quarterly reconciliation and not on a Free tier, your true-ups are reconciled annually.
## Troubleshooting

View File

@ -28,6 +28,19 @@ Please do not rely on this information for purchasing or planning purposes.
The development, release, and timing of any products, features, or functionality may be subject to change or delay and remain at the
sole discretion of GitLab Inc.
Duo Workflow is an AI-powered coding agent in the VS Code IDE. It helps you solve coding tasks more quickly.
Use it to speed up routine tasks, to improve your work, or to learn different approaches or technologies.
Duo Workflow works in the project you have open in your IDE, and helps you with coding tasks like:
- Draft code to implement your issue or improve your merge request, so you can get started more quickly.
- Refactor or simplify your code, to improve its structure and make it easier to maintain.
- Write or extend your tests, to improve test coverage and code reliability.
After you describe your goal, Duo Workflow generates and executes on a plan to address it. While it executes, you can pause or ask it to adjust the plan.
To improve its accuracy, be specific in your goal. Outline any changes you'd like to see. Reference related files, issues, or merge requests.
## Risks of Duo Workflow and AI Agents
Duo Workflow is an experimental product and users should consider their

View File

@ -94,6 +94,32 @@ To enter the new names, you must edit the file.
Organizations using SAML SSO can [set usernames](../../../integration/saml.md#set-a-username) to
prevent users from being able to change their usernames.
### Add a role as a Code Owner
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/371711) in GitLab 17.6 [with a flag](../../../administration/feature_flags.md) named `codeowner_role_approvers`. Disabled by default.
You can add or set a role for direct project members as Code Owners:
- Use the `@@` prefix to set a role.
- Only Developer, Maintainer, and Owner roles are available.
- Roles are not inclusive of higher roles. For example, specifying `@@developer`
does not include users with Maintainer or Owner roles.
- Only direct project members with the specified roles are eligible Code Owners.
- It is possible to specify plural roles. For example, `@@developers` will be accepted.
The following example sets all direct project members with the Developer or Maintainer
role as Code Owners for `file.md`:
1. Open the `CODEOWNERS` file.
1. Add a line using the following pattern:
```plaintext
file.md @@developer @@maintainer
```
1. Save the file.
1. Commit and merge the changes.
### Add a group as a Code Owner
To set the members of a group or subgroup as a Code Owner:

View File

@ -203,7 +203,7 @@ GEM
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.8.1)
webrick (1.8.2)
zeitwerk (2.6.8)
PLATFORMS

View File

@ -3405,6 +3405,9 @@ msgstr ""
msgid "Add suggestion to batch"
msgstr ""
msgid "Add summary"
msgstr ""
msgid "Add tag"
msgstr ""
@ -8841,9 +8844,6 @@ msgstr ""
msgid "BillingPlans|Start a free GitLab Duo Enterprise Trial"
msgstr ""
msgid "BillingPlans|Start a free GitLab Duo Pro trial"
msgstr ""
msgid "BillingPlans|Start an Ultimate trial with GitLab Duo Enterprise to try the complete set of features from GitLab. GitLab Duo Enterprise gives you access to the full product offering from GitLab, including AI-powered features."
msgstr ""
@ -13394,9 +13394,6 @@ msgstr ""
msgid "CodeSuggestions|Before you can buy GitLab Duo seats, you'll need a Premium or Ultimate subscription."
msgstr ""
msgid "CodeSuggestions|Boost productivity across the software development life cycle by using Code Suggestions and GitLab Duo Chat as part of the %{duoLinkStart}GitLab Duo Pro%{duoLinkEnd} add-on. You can now try GitLab Duo Pro for free for 60 days, no credit card required."
msgstr ""
msgid "CodeSuggestions|Code Explanations"
msgstr ""
@ -13430,9 +13427,6 @@ msgstr ""
msgid "CodeSuggestions|Introducing GitLab Duo"
msgstr ""
msgid "CodeSuggestions|Introducing the GitLab Duo Pro add-on"
msgstr ""
msgid "CodeSuggestions|Manage seat assignments for %{addOnName} within your group."
msgstr ""
@ -24187,6 +24181,9 @@ msgstr ""
msgid "Generated with JSON data"
msgstr ""
msgid "Generating review summary"
msgstr ""
msgid "Generic"
msgstr ""
@ -50022,6 +50019,9 @@ msgstr ""
msgid "SecurityOrchestration|If any scanner finds a vulnerability that was previously detected but no longer found in a subsequent scan, then automatically set the status to Resolved."
msgstr ""
msgid "SecurityOrchestration|In each pipeline, a %{boldStart}maximum of 1000%{boldEnd} vulnerabilities that are %{italicStart}no longer detected%{italicEnd} will be set to status %{italicStart}Resolved%{italicEnd} until all have been auto-resolved."
msgstr ""
msgid "SecurityOrchestration|Individual users"
msgstr ""
@ -53186,7 +53186,7 @@ msgstr ""
msgid "Source branch"
msgstr ""
msgid "Source branch (%{branch})"
msgid "Source branch (%{branch}): %{pipelines}"
msgstr ""
msgid "Source branch does not exist"
@ -54247,9 +54247,6 @@ msgstr ""
msgid "Summarize comments"
msgstr ""
msgid "Summarize my pending comments"
msgstr ""
msgid "Summarize the comments in the current issue."
msgstr ""
@ -54706,7 +54703,7 @@ msgstr ""
msgid "Target branch"
msgstr ""
msgid "Target branch (%{branch})"
msgid "Target branch (%{branch}): %{pipelines}"
msgstr ""
msgid "Target branch: %{target_branch}"

View File

@ -112,8 +112,6 @@ ee/spec/frontend/security_dashboard/components/shared/vulnerability_report/conta
ee/spec/frontend/security_dashboard/components/shared/vulnerability_report/vulnerability_list_graphql_spec.js
ee/spec/frontend/security_dashboard/components/shared/vulnerability_report/vulnerability_report_spec.js
ee/spec/frontend/security_dashboard/components/shared/vulnerability_report/vulnerability_report_tabs_spec.js
ee/spec/frontend/security_orchestration/components/policy_editor/pipeline_execution/action/action_section_spec.js
ee/spec/frontend/security_orchestration/components/policy_editor/pipeline_execution/action/code_block_file_path_spec.js
ee/spec/frontend/security_orchestration/components/policy_editor/pipeline_execution/rule/rule_section_spec.js
ee/spec/frontend/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/status_filter_spec.js
ee/spec/frontend/security_orchestration/components/policy_editor/scan_result/rule/scan_filters/status_filters_spec.js
@ -281,7 +279,6 @@ spec/frontend/notes/components/timeline_toggle_spec.js
spec/frontend/organizations/groups_and_projects/components/app_spec.js
spec/frontend/organizations/shared/components/new_edit_form_spec.js
spec/frontend/packages_and_registries/container_registry/explorer/components/list_page/image_list_row_spec.js
spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js
spec/frontend/packages_and_registries/dependency_proxy/app_spec.js
spec/frontend/packages_and_registries/infrastructure_registry/components/details/components/app_spec.js
spec/frontend/packages_and_registries/package_registry/components/details/package_files_spec.js

View File

@ -100,6 +100,28 @@ export const graphQLEmptyGroupImageListMock = {
},
};
export const graphQLImageListNullContainerRepositoriesMock = {
data: {
project: {
__typename: 'Project',
id: '1',
containerRepositoriesCount: 0,
containerRepositories: null,
},
},
};
export const graphQLGroupImageListNullContainerRepositoriesMock = {
data: {
group: {
__typename: 'Group',
id: '1',
containerRepositoriesCount: 0,
containerRepositories: null,
},
},
};
export const deletedContainerRepository = {
id: 'gid://gitlab/ContainerRepository/11',
status: 'DELETE_SCHEDULED',

View File

@ -19,6 +19,7 @@ import {
GRAPHQL_PAGE_SIZE_METADATA_ENABLED,
SORT_FIELDS,
SETTINGS_TEXT,
FETCH_IMAGES_LIST_ERROR_MESSAGE,
} from '~/packages_and_registries/container_registry/explorer/constants';
import deleteContainerRepositoryMutation from '~/packages_and_registries/container_registry/explorer/graphql/mutations/delete_container_repository.mutation.graphql';
import getContainerRepositoriesDetails from '~/packages_and_registries/container_registry/explorer/graphql/queries/get_container_repositories_details.query.graphql';
@ -30,20 +31,25 @@ import MetadataDatabaseAlert from '~/packages_and_registries/shared/components/c
import { FILTERED_SEARCH_TERM } from '~/vue_shared/components/filtered_search_bar/constants';
import TitleArea from '~/vue_shared/components/registry/title_area.vue';
import { helpPagePath } from '~/helpers/help_page_helper';
import { createAlert } from '~/alert';
import { $toast } from 'jest/packages_and_registries/shared/mocks';
import {
graphQLImageListMock,
graphQLImageListNullContainerRepositoriesMock,
graphQLImageDeleteMock,
deletedContainerRepository,
graphQLEmptyImageListMock,
graphQLEmptyGroupImageListMock,
graphQLGroupImageListNullContainerRepositoriesMock,
pageInfo,
graphQLProjectImageRepositoriesDetailsMock,
dockerCommands,
} from '../mock_data';
import { GlEmptyState, DeleteModal } from '../stubs';
jest.mock('~/alert');
describe('List Page', () => {
let wrapper;
let apolloProvider;
@ -105,6 +111,7 @@ describe('List Page', () => {
RegistryHeader,
TitleArea,
DeleteImage,
ImageList,
MetadataContainerScanning: true,
ContainerScanningCounts: true,
},
@ -304,7 +311,7 @@ describe('List Page', () => {
it('cli commands are not visible', async () => {
mountComponent({ resolver });
fireFirstSortUpdate();
await waitForApolloRequestRender();
expect(findCliCommands().exists()).toBe(false);
@ -312,7 +319,7 @@ describe('List Page', () => {
it('project empty state is visible', async () => {
mountComponent({ resolver });
fireFirstSortUpdate();
await waitForApolloRequestRender();
expect(findProjectEmptyState().exists()).toBe(true);
@ -328,7 +335,7 @@ describe('List Page', () => {
it('group empty state is visible', async () => {
mountComponent({ resolver, config });
fireFirstSortUpdate();
await waitForApolloRequestRender();
expect(findGroupEmptyState().exists()).toBe(true);
@ -336,7 +343,7 @@ describe('List Page', () => {
it('cli commands are not visible', async () => {
mountComponent({ resolver, config });
fireFirstSortUpdate();
await waitForApolloRequestRender();
expect(findCliCommands().exists()).toBe(false);
@ -344,7 +351,7 @@ describe('List Page', () => {
it('link to settings is not visible', async () => {
mountComponent({ resolver, config });
fireFirstSortUpdate();
await waitForApolloRequestRender();
expect(findSettingsLink().exists()).toBe(false);
@ -352,6 +359,38 @@ describe('List Page', () => {
});
});
describe('GraphQL query returns null', () => {
describe.each`
pageType | config | response | emptyStateFinder
${'project'} | ${{ isGroupPage: false }} | ${graphQLImageListNullContainerRepositoriesMock} | ${findProjectEmptyState}
${'group'} | ${{ isGroupPage: true }} | ${graphQLGroupImageListNullContainerRepositoriesMock} | ${findGroupEmptyState}
`('$pageType page', ({ pageType, config, response, emptyStateFinder }) => {
beforeEach(async () => {
mountComponent({
config,
detailsResolver: jest.fn().mockResolvedValue(response),
resolver: jest.fn().mockResolvedValue(response),
});
fireFirstSortUpdate();
await waitForApolloRequestRender();
});
it('cli commands are not visible', () => {
expect(findCliCommands().exists()).toBe(false);
});
it(`${pageType} empty state is visible`, () => {
expect(emptyStateFinder().exists()).toBe(true);
});
it('createAlert is not called', () => {
expect(createAlert).not.toHaveBeenCalledWith({
message: FETCH_IMAGES_LIST_ERROR_MESSAGE,
});
});
});
});
describe('list is not empty', () => {
describe('unfiltered state', () => {
it('quick start is visible', async () => {

View File

@ -903,14 +903,6 @@ RSpec.describe ProjectsHelper, feature_category: :source_code_management do
it { is_expected.to be_falsey }
end
context 'when lfs_misconfiguration_banner feature flag is disabled' do
before do
stub_feature_flags(lfs_misconfiguration_banner: false)
end
it { is_expected.to be_falsey }
end
end
context 'when it does have a .gitattributes file' do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe API::Entities::WikiPage do
RSpec.describe API::Entities::WikiPage, feature_category: :wiki do
let_it_be_with_reload(:wiki_page) { create(:wiki_page) }
let(:params) { {} }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Gitlab::DataBuilder::WikiPage do
RSpec.describe Gitlab::DataBuilder::WikiPage, feature_category: :wiki do
let_it_be(:project) { create(:project, :repository, :wiki_repo) }
let_it_be(:wiki_page) { create(:wiki_page, wiki: project.wiki) }
let_it_be(:user) { create(:user) }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Gitlab::WikiPages::FrontMatterParser do
RSpec.describe Gitlab::WikiPages::FrontMatterParser, feature_category: :wiki do
subject(:parser) { described_class.new(raw_content) }
let(:content) { 'This is the content' }

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe Integrations::ExternalWiki do
RSpec.describe Integrations::ExternalWiki, feature_category: :integrations do
describe 'Validations' do
context 'when integration is active' do
before do

View File

@ -2,7 +2,7 @@
require 'spec_helper'
RSpec.describe WikiPage::Slug do
RSpec.describe WikiPage::Slug, feature_category: :wiki do
let_it_be(:meta) { create(:wiki_page_meta) }
describe 'Associations' do

View File

@ -1,7 +1,7 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'shared/wikis/_sidebar.html.haml' do
RSpec.describe 'shared/wikis/_sidebar.html.haml', feature_category: :wiki do
let_it_be(:project) { create(:project) }
let_it_be(:wiki) { Wiki.for_container(project, project.first_owner) }