Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2025-06-28 00:10:12 +00:00
parent 0a56f5aadb
commit 4da4d596a8
12 changed files with 211 additions and 184 deletions

View File

@ -2316,16 +2316,9 @@ class MergeRequest < ApplicationRecord
end
end
# Overridden in EE
def use_merge_base_pipeline_for_comparison?(_)
return true if Feature.enabled?(:use_merge_base_for_all_report_comparisons, project)
false
end
def comparison_base_pipeline(service_class)
target_shas = [
(diff_head_pipeline&.target_sha if use_merge_base_pipeline_for_comparison?(service_class)),
diff_head_pipeline&.target_sha,
diff_base_sha,
diff_start_sha
]

View File

@ -1,10 +0,0 @@
---
name: use_merge_base_for_all_report_comparisons
description:
feature_issue_url:
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/192288
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/549351
milestone: '18.1'
group: group::security insights
type: gitlab_com_derisk
default_enabled: false

View File

@ -8,14 +8,6 @@ description: Debian project-level component files
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/52885
milestone: '13.9'
gitlab_schema: gitlab_main_cell
desired_sharding_key:
project_id:
references: projects
backfill_via:
parent:
foreign_key: component_id
table: packages_debian_project_components
sharding_key: project_id
belongs_to: component
sharding_key:
project_id: projects
table_size: small
desired_sharding_key_migration_job_name: BackfillPackagesDebianProjectComponentFilesProjectId

View File

@ -0,0 +1,14 @@
# frozen_string_literal: true
class AddPackagesDebianProjectComponentFilesProjectIdNotNull < Gitlab::Database::Migration[2.3]
milestone '18.2'
disable_ddl_transaction!
def up
add_not_null_constraint :packages_debian_project_component_files, :project_id
end
def down
remove_not_null_constraint :packages_debian_project_component_files, :project_id
end
end

View File

@ -0,0 +1 @@
f6c692554287c5a8aea8f361522568fbd419dd71c83096a842f678efd59179f2

View File

@ -19614,6 +19614,7 @@ CREATE TABLE packages_debian_project_component_files (
file text NOT NULL,
file_sha256 bytea NOT NULL,
project_id bigint,
CONSTRAINT check_4eafc9503d CHECK ((project_id IS NOT NULL)),
CONSTRAINT check_e5af03fa2d CHECK ((char_length(file) <= 255))
);

View File

@ -241,11 +241,13 @@ To request acceleration of a feature, check if an issue already exists in [epic
## Disable secondary site HTTP proxying
Secondary site HTTP proxying is enabled by default on a secondary site when it uses a unified URL, meaning, it is configured with the same `external_url` as the primary site. Disabling proxying in this case tends not to be helpful due to completely different behavior being served at the same URL, depending on routing.
Secondary site HTTP proxying is enabled by default on a secondary site when it uses a unified URL, meaning, it is configured with the same `external_url` as the primary site. Disabling proxying in this case tends not to be helpful due to completely different behavior being served at the same URL, depending on routing. When HTTP proxying is disabled on a secondary Geo site, the site operates in read-only mode, with several important limitations you should be aware of.
### What happens if you disable secondary proxying
Disabling the proxying feature flag has the following general effects:
Disabling the proxying feature flag has the following general effects.
#### HTTP and Git requests
- The secondary site does not proxy HTTP requests to the primary site. Instead, it attempts to serve them itself, or fail.
- Git requests generally succeed. Git pushes are redirected or proxied to the primary site.
@ -271,7 +273,24 @@ Disabling the proxying feature flag has the following general effects:
You should use the feature flag over using the `GEO_SECONDARY_PROXY` environment variable.
HTTP proxying is enabled by default in GitLab 15.1 on a secondary site even without a unified URL. If proxying needs to be disabled on all secondary sites, it is easiest to disable the feature flag:
HTTP proxying is enabled by default in GitLab 15.1 on a secondary site even without a unified URL.
#### Terms of service acceptance
When proxying is disabled, users who access only the secondary site cannot properly accept terms of service or other legal agreements. This creates the following issues:
- **No record of acceptance**: If an employee only logs into the secondary site, their acceptance of terms and conditions is not recorded in the primary database because write operations (including terms acceptance) are not proxied when secondary proxying is disabled, even though they may be presented with the terms message.
- **Legal compliance concerns**: Organizations may lack proper legal coverage if employees use GitLab services through a secondary-only access pattern, since there's no verifiable record of their agreement to the terms and conditions.
As a workaround, you must access the primary site at least once to properly accept terms and conditions. After accepted on the primary, this information is replicated to secondary sites through normal Geo synchronization.
{{< alert type="note" >}}
This limitation affects organizations that require documented acceptance of terms and conditions for compliance or legal purposes. Ensure users have access to the primary site for the initial terms acceptance.
{{< /alert >}}
### Disable proxy on all secondary sites
If you need to disable proxying on all secondary sites, it is easiest to disable the feature flag:
{{< tabs >}}

View File

@ -0,0 +1,97 @@
---
stage: AI-powered
group: Duo Workflow
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
description: Describes Model Context Protocol and how to use it
title: Use Model Context Protocol with AI-native features
---
{{< details >}}
- Tier: Ultimate
- Offering: GitLab.com
- Status: Experiment
{{< /details >}}
{{< history >}}
- [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/519938) in GitLab 18.1 [with a flag](../../../administration/feature_flags/_index.md) named `duo_workflow_mcp_support`. Disabled by default.
- [Enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/545956) in GitLab 18.2. Feature flag `duo_workflow_mcp_support` removed.
{{< /history >}}
The Model Context Protocol (MCP) provides a standardized way for AI-native features
to securely connect to different external data sources and tools.
The following GitLab Duo AI-native features can act as MCP clients, and connect to and run
external tools from MCP servers:
- [GitLab Duo Agentic Chat](../../gitlab_duo_chat/agentic_chat.md)
This means that, in addition to GitLab information, these AI-native features
can now use context and information external to GitLab to generate more powerful
answers for customers.
To use a GitLab Duo AI-native feature with MCP:
- Turn on MCP for your group.
- Specify the MCP servers you want the feature to connect to.
## Prerequisites
Before you can use an AI-native feature with MCP, you must:
- [Install Visual Studio Code](https://code.visualstudio.com/download) (VS Code).
- [Set up the GitLab Workflow extension for VS Code](https://marketplace.visualstudio.com/items?itemName=GitLab.gitlab-workflow#setup).
- Meet the following AI-native feature prerequisites:
- [Agentic Chat prerequisites](../../gitlab_duo_chat/agentic_chat.md#use-agentic-chat-in-vs-code).
## Turn on MCP for your group
To turn MCP on or off for your group:
1. On the left sidebar, select **Search or go to** and find your group.
1. Select **Settings > GitLab Duo**.
1. Select **Change configuration**.
1. Under **Model Context Protocol**, select or clear the
**Turn on Model Context Protocol (MCP) support** checkbox.
1. Select **Save changes**.
## Specify the MCP servers
To specify the MCP servers you want the AI-native feature to connect to:
1. In VS Code, create an `mcp.json` file in `~/gitlab/duo/`.
1. Populate this file with the MCP servers you want the feature to connect to.
For more information and examples, see the [MCP example servers documentation](https://modelcontextprotocol.io/examples). You can also find other example servers at [Smithery.ai](https://smithery.ai/)
and [Awesome MCP Servers](https://mcpservers.org/).
1. Save the file.
## Use AI-native features with MCP
When an AI-native feature wants to call an external tool to answer
the question you have asked, you must review and approve or deny the tool before
the feature can use that tool:
1. Open VS Code.
1. On the left sidebar, select the feature.
1. In the text box, enter a question or specify a code task.
1. Submit the question or code task.
1. The **Tool Approval Required** dialog appears.
Review the tool and select **Approve** or **Deny**.
- If you approve the tool, the feature connects to the tool and
generates an answer.
- If you deny the tool, the **Provide Rejection Reason** dialog appears.
Optional: Enter a rejection reason into the text box and select
**Submit Rejection**.
## Related topics
- [Get started with the Model Context Protocol](https://modelcontextprotocol.io/introduction)
- [Demo - Agentic Chat MCP Tool Call Approval](https://www.youtube.com/watch?v=_cHoTmG8Yj8)

View File

@ -85,7 +85,8 @@ Agentic Chat extends Chat capabilities with the following features:
- **Resource Retrieval**: Can automatically retrieve detailed information about
issues, merge requests, and pipeline logs of your current project.
- **Multi-source Analysis**: Can combine information from multiple sources to
provide more complete answers to complex questions.
provide more complete answers to complex questions. You can use [Model Context Protocol](../gitlab_duo/model_context_protocol/_index.md) to connect Agentic Chat to
external data sources and tools.
### Chat feature comparison

View File

@ -128,12 +128,18 @@ module API
end
def automatically_mergeable?(auto_merge, merge_request)
return unless auto_merge
available_strategies = AutoMergeService.new(merge_request.project,
current_user).available_strategies(merge_request)
available_strategies.include?(merge_request.default_auto_merge_strategy)
auto_merge && available_strategies.include?(merge_request.default_auto_merge_strategy)
end
def immediately_mergeable?(auto_merge, merge_request)
if auto_merge
merge_request.diff_head_pipeline_success?
else
merge_request.mergeable_state?
end
end
def serializer_options_for(merge_requests)
@ -751,7 +757,7 @@ module API
auto_merge = to_boolean(params[:merge_when_pipeline_succeeds]) || to_boolean(params[:auto_merge])
automatically_mergeable = automatically_mergeable?(auto_merge, merge_request)
immediately_mergeable = merge_request.mergeable?
immediately_mergeable = immediately_mergeable?(auto_merge, merge_request)
not_allowed! if !immediately_mergeable && !automatically_mergeable

View File

@ -5045,24 +5045,6 @@ RSpec.describe MergeRequest, factory_default: :keep, feature_category: :code_rev
end
end
describe '#use_merge_base_pipeline_for_comparison?' do
let(:project) { create(:project, :public, :repository) }
let(:merge_request) { create(:merge_request, :with_codequality_reports, source_project: project) }
let(:service_class) { Ci::CompareReportsBaseService }
subject { merge_request.use_merge_base_pipeline_for_comparison?(service_class) }
it { is_expected.to eq(true) }
context 'when use_merge_base_for_all_report_comparisons is disabled' do
before do
stub_feature_flags(use_merge_base_for_all_report_comparisons: false)
end
it { is_expected.to eq(false) }
end
end
describe '#comparison_base_pipeline' do
subject(:pipeline) { merge_request.comparison_base_pipeline(service_class) }
@ -5078,90 +5060,44 @@ RSpec.describe MergeRequest, factory_default: :keep, feature_category: :code_rev
)
end
before do
allow(merge_request).to receive(:use_merge_base_pipeline_for_comparison?)
.with(service_class).and_return(uses_merge_base)
end
context 'when service class uses merge base pipeline' do
let(:uses_merge_base) { true }
context 'when merge request has a merge request pipeline' do
let(:merge_request) do
create(:merge_request, :with_merge_request_pipeline, source_project: project)
end
let!(:merge_base_pipeline) do
create(:ci_pipeline, project: project, ref: merge_request.target_branch, sha: merge_request.target_branch_sha)
end
before do
merge_request.update_head_pipeline
end
it 'returns the merge_base_pipeline' do
expect(pipeline).to eq(merge_base_pipeline)
end
context 'when merge request has a merge request pipeline' do
let(:merge_request) do
create(:merge_request, :with_merge_request_pipeline, source_project: project)
end
it 'returns the base_pipeline when merge does not have a merge request pipeline' do
expect(pipeline).to eq(base_pipeline)
let!(:merge_base_pipeline) do
create(:ci_pipeline, project: project, ref: merge_request.target_branch, sha: merge_request.target_branch_sha)
end
context 'when there is no base pipeline' do
let!(:start_pipeline) do
create(:ci_pipeline,
:success,
project: project,
ref: merge_request.target_branch,
sha: merge_request.diff_start_sha
)
end
before do
merge_request.update_head_pipeline
end
before do
base_pipeline.destroy!
end
it 'returns the start pipeline' do
expect(pipeline).to eq(start_pipeline)
end
it 'returns the merge_base_pipeline' do
expect(pipeline).to eq(merge_base_pipeline)
end
end
context 'when service_class does not use merge base pipeline' do
let(:uses_merge_base) { false }
it 'returns the base_pipeline when merge does not have a merge request pipeline' do
expect(pipeline).to eq(base_pipeline)
end
it 'returns the base_pipeline' do
expect(pipeline).to eq(base_pipeline)
context 'when there is no base pipeline' do
let!(:start_pipeline) do
create(:ci_pipeline,
:success,
project: project,
ref: merge_request.target_branch,
sha: merge_request.diff_start_sha
)
end
context 'when merge request has a merge request pipeline' do
let(:merge_request) do
create(:merge_request, :with_merge_request_pipeline, source_project: project)
end
it 'returns the base pipeline' do
expect(pipeline).to eq(base_pipeline)
end
before do
base_pipeline.destroy!
end
context 'when there is no base pipeline' do
let!(:start_pipeline) do
create(:ci_pipeline,
:success,
project: project,
ref: merge_request.target_branch,
sha: merge_request.diff_start_sha
)
end
before do
base_pipeline.destroy!
end
it 'returns the start pipeline' do
expect(pipeline).to eq(start_pipeline)
end
it 'returns the start pipeline' do
expect(pipeline).to eq(start_pipeline)
end
end
end

View File

@ -3174,71 +3174,48 @@ RSpec.describe API::MergeRequests, :aggregate_failures, feature_category: :sourc
end
shared_examples 'merging with auto merge strategies' do
context 'when only_allow_merge_if_pipeline_succeeds is true' do
before do
project.update_attribute(:only_allow_merge_if_pipeline_succeeds, true)
end
it 'does not merge if auto merge request is passed and the pipeline has failed' do
create(:ci_pipeline,
:failed,
sha: merge_request.diff_head_sha,
merge_requests_as_head_pipeline: [merge_request])
it 'sets auto merge when the pipeline has failed' do
create(:ci_pipeline,
:failed,
sha: merge_request.diff_head_sha,
merge_requests_as_head_pipeline: [merge_request])
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), params: params
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), params: params
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['merge_when_pipeline_succeeds']).to eq(true)
expect(merge_request.reload.state).to eq('opened')
end
it "sets auto merge when the pipeline is active" do
allow_any_instance_of(MergeRequest).to receive_messages(head_pipeline: pipeline, diff_head_pipeline: pipeline)
allow(pipeline).to receive(:active?).and_return(true)
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), params: params
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['title']).to eq('Test')
expect(json_response['merge_when_pipeline_succeeds']).to eq(true)
end
it 'merges when then pipeline is succeed' do
create(:ci_pipeline, :success, sha: merge_request.diff_head_sha, merge_requests_as_head_pipeline: [merge_request])
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), params: params
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['state']).to eq('merged')
end
expect(response).to have_gitlab_http_status(:method_not_allowed)
expect(merge_request.reload.state).to eq('opened')
end
context 'when only_allow_merge_if_pipeline_succeeds is false' do
before do
project.update_attribute(:only_allow_merge_if_pipeline_succeeds, false)
end
it 'merges if the head pipeline already succeeded and auto merge request is passed' do
create(:ci_pipeline, :success, sha: merge_request.diff_head_sha, merge_requests_as_head_pipeline: [merge_request])
it 'merges when the pipeline has failed' do
create(:ci_pipeline,
:failed,
sha: merge_request.diff_head_sha,
merge_requests_as_head_pipeline: [merge_request])
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), params: params
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), params: params
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['state']).to eq('merged')
end
expect(response).to have_gitlab_http_status(:ok)
expect(merge_request.reload.state).to eq('merged')
end
it "enables auto merge if the pipeline is active" do
allow_any_instance_of(MergeRequest).to receive_messages(head_pipeline: pipeline, diff_head_pipeline: pipeline)
allow(pipeline).to receive(:active?).and_return(true)
it "merges when the pipeline is active" do
allow_any_instance_of(MergeRequest).to receive_messages(head_pipeline: pipeline, diff_head_pipeline: pipeline)
allow(pipeline).to receive(:active?).and_return(true)
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), params: params
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), params: params
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['title']).to eq('Test')
expect(json_response['merge_when_pipeline_succeeds']).to eq(true)
end
expect(response).to have_gitlab_http_status(:ok)
expect(merge_request.reload.state).to eq('merged')
end
it "enables auto merge if the pipeline is active and only_allow_merge_if_pipeline_succeeds is true" do
allow_any_instance_of(MergeRequest).to receive_messages(head_pipeline: pipeline, diff_head_pipeline: pipeline)
allow(pipeline).to receive(:active?).and_return(true)
project.update_attribute(:only_allow_merge_if_pipeline_succeeds, true)
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user), params: params
expect(response).to have_gitlab_http_status(:ok)
expect(json_response['title']).to eq('Test')
expect(json_response['merge_when_pipeline_succeeds']).to eq(true)
end
end
@ -3280,15 +3257,15 @@ RSpec.describe API::MergeRequests, :aggregate_failures, feature_category: :sourc
end
end
it "returns 405 if branch can't be merged" do
it "returns 422 if branch can't be merged" do
allow_next_found_instance_of(MergeRequest) do |merge_request|
allow(merge_request).to receive(:mergeable?).and_return(false)
allow(merge_request).to receive(:can_be_merged?).and_return(false)
end
put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/merge", user)
expect(response).to have_gitlab_http_status(:method_not_allowed)
expect(json_response['message']).to eq('405 Method Not Allowed')
expect(response).to have_gitlab_http_status(:unprocessable_entity)
expect(json_response['message']).to eq('Branch cannot be merged')
end
it "returns 405 if merge_request is not open" do