Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2025-07-02 03:07:25 +00:00
parent b608034c83
commit 975768d696
21 changed files with 139 additions and 61 deletions

View File

@ -1 +1 @@
e23e51064c5e5a11e328173d7ef2bb724737307c
6c90dbb27ce3609304d71ffcd2b8113a08590f5c

View File

@ -23,7 +23,11 @@ class Import::GitlabProjectsController < Import::BaseController
)
end
@project = ::Projects::GitlabProjectsImportService.new(current_user, project_params).execute
@project = ::Projects::GitlabProjectsImportService.new(
current_user,
project_params,
import_type: 'gitlab_project'
).execute
if @project.saved?
redirect_to(

View File

@ -50,9 +50,15 @@ class Projects::ImportsController < Projects::ApplicationController
redirect_to project_path(@project) if @project.repository_exists?
end
# Project creation by template uses a different permission model to regular imports
# https://gitlab.com/gitlab-org/gitlab/-/issues/414046#note_1945586449.
def require_namespace_project_creation_permission
unless can?(current_user, :admin_project, @project) || can?(current_user, :import_projects, @project.namespace)
render_404
if Gitlab::ImportSources.template?(@project.import_type)
render_404 unless can?(current_user, :create_projects, project.namespace)
else
unless can?(current_user, :admin_project, @project) || can?(current_user, :import_projects, @project.namespace)
render_404
end
end
end

View File

@ -453,7 +453,8 @@ class ApplicationSetting < ApplicationRecord
value&.each do |source|
# Temporary allow "gitlab_custom_project_template" to avoid validation errors
# "gitlab_custom_project_template" can be excluded after incorrect values are removed from the database
allowed_import_sources = Gitlab::ImportSources.values
# Issue: https://gitlab.com/gitlab-org/gitlab/-/issues/550410
allowed_import_sources = Gitlab::ImportSources.values - ['gitlab_built_in_project_template']
unless allowed_import_sources.include?(source)
record.errors.add(attr, format(_("'%{source}' is not a import source"), source: source))

View File

@ -1711,7 +1711,7 @@ class Project < ApplicationRecord
end
def import?
external_import? || forked? || gitlab_project_import? || jira_import? || gitlab_project_migration?
external_import? || forked? || gitlab_project_import? || jira_import? || gitlab_project_migration? || Gitlab::ImportSources.template?(import_type)
end
def external_import?

View File

@ -63,7 +63,8 @@ module Import
@project ||= ::Projects::GitlabProjectsImportService.new(
current_user,
project_params,
params[:override]
params[:override],
import_type: 'gitlab_project'
).execute
end
@ -72,8 +73,7 @@ module Import
name: params[:name],
path: params[:path],
namespace_id: params[:namespace].id,
overwrite: params[:overwrite],
import_type: 'gitlab_project'
overwrite: params[:overwrite]
}.merge(strategy.project_params)
end
end

View File

@ -26,7 +26,7 @@ module Projects
params[:sample_data] = true
end
GitlabProjectsImportService.new(current_user, params, override_params).execute
GitlabProjectsImportService.new(current_user, params, override_params, import_type: 'gitlab_built_in_project_template').execute
ensure
file&.close
end

View File

@ -113,7 +113,6 @@ module Projects
def validate_import_permissions
return unless @project.import?
return if @project.gitlab_project_import?
# Skip for project template importers, as their permission model is different from other importers
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/414046#note_1945586449.
@ -335,9 +334,6 @@ module Projects
# controlled by the `import_sources` application setting.
return if Gitlab::ImportSources.template?(import_type)
# Skip validation when creating project from a built in template
return if @import_export_upload.present? && import_type == 'gitlab_project'
unless ::Gitlab::CurrentSettings.import_sources&.include?(import_type)
raise ImportSourceDisabledError, "#{import_type} import source is disabled"
end

View File

@ -10,10 +10,13 @@ module Projects
attr_reader :current_user, :params
def initialize(user, import_params, override_params = nil)
def initialize(user, import_params, override_params = nil, import_type:)
@current_user = user
@params = import_params.dup
@override_params = override_params
@import_type = import_type.to_s
raise ArgumentError, 'Invalid import_type provided' unless valid_import_type?
end
def execute
@ -26,6 +29,12 @@ module Projects
private
attr_reader :import_type
def valid_import_type?
import_type == 'gitlab_project' || Gitlab::ImportSources.template?(import_type)
end
def overwrite_project?
overwrite? && project_with_same_full_path?
end
@ -67,13 +76,10 @@ module Projects
params[:path] += "-#{tmp_filename}"
end
if template_file
data[:sample_data] = params.delete(:sample_data) if params.key?(:sample_data)
params[:import_type] = 'gitlab_project'
end
data[:sample_data] = params.delete(:sample_data) if template_file && params.key?(:sample_data)
params[:import_type] = import_type
params[:organization_id] = current_namespace.organization_id
params[:import_data] = { data: data } if data.present?
end
end

View File

@ -70,10 +70,6 @@ class RepositoryImportWorker # rubocop:disable Scalability/IdempotentWorker
def fail_import(message)
project.import_state.mark_as_failed(message)
end
def template_import?
project.gitlab_project_import?
end
end
RepositoryImportWorker.prepend_mod_with('RepositoryImportWorker')

View File

@ -56,7 +56,8 @@ module Gitlab
disable_upload_object_storage do
service = Projects::GitlabProjectsImportService.new(
current_user,
import_params
import_params,
import_type: 'gitlab_project'
)
service.execute

View File

@ -16,9 +16,14 @@ module Gitlab
ImportSource.new('git', 'Repository by URL', nil),
ImportSource.new('gitlab_project', 'GitLab export', Gitlab::ImportExport::Importer),
ImportSource.new('gitea', 'Gitea', Gitlab::LegacyGithubImport::Importer),
ImportSource.new('manifest', 'Manifest file', nil)
ImportSource.new('manifest', 'Manifest file', nil),
ImportSource.new(
'gitlab_built_in_project_template', 'GitLab built-in project template', Gitlab::ImportExport::Importer
)
].freeze
PROJECT_TEMPLATE_IMPORTERS = ['gitlab_built_in_project_template'].freeze
class << self
prepend_mod_with('Gitlab::ImportSources') # rubocop: disable Cop/InjectEnterpriseEditionModule
@ -51,7 +56,7 @@ module Gitlab
end
def project_template_importers
[]
PROJECT_TEMPLATE_IMPORTERS
end
end
end

View File

@ -2394,12 +2394,24 @@ msgstr ""
msgid "AICatalog|Agents"
msgstr ""
msgid "AICatalog|Create agent"
msgstr ""
msgid "AICatalog|Description can't be blank."
msgstr ""
msgid "AICatalog|Edit agent"
msgstr ""
msgid "AICatalog|Failed to run agent."
msgstr ""
msgid "AICatalog|Input cannot exceed %{value} characters. Please shorten your input."
msgstr ""
msgid "AICatalog|Modify the agent settings and configuration."
msgstr ""
msgid "AICatalog|Prompt"
msgstr ""
@ -2412,6 +2424,15 @@ msgstr ""
msgid "AICatalog|Run agent"
msgstr ""
msgid "AICatalog|Save changes"
msgstr ""
msgid "AICatalog|System Prompt"
msgstr ""
msgid "AICatalog|User Prompt"
msgstr ""
msgid "AISummary|Generates a summary of this issue"
msgstr ""

View File

@ -3,7 +3,7 @@
require 'spec_helper'
RSpec.describe Projects::ImportsController, feature_category: :importers do
let(:user) { create(:user) }
let_it_be(:user) { create(:user) }
let(:project) { create(:project) }
before do
@ -22,6 +22,33 @@ RSpec.describe Projects::ImportsController, feature_category: :importers do
end
end
context 'when the developer user has project creation rights' do
let_it_be(:group) { create(:group, project_creation_level: Gitlab::Access::DEVELOPER_PROJECT_ACCESS) }
let_it_be(:project) { create(:project_empty_repo, :import_started, group: group) }
before_all do
group.add_developer(user)
end
it 'returns 404 response' do
get :show, params: { namespace_id: project.namespace.to_param, project_id: project }
expect(response).to have_gitlab_http_status(:not_found)
end
context 'when import type is gitlab_built_in_project_template' do
before do
project.update!(import_type: 'gitlab_built_in_project_template')
end
it 'returns 200 response' do
get :show, params: { namespace_id: project.namespace.to_param, project_id: project }
expect(response).to have_gitlab_http_status(:success)
end
end
end
context 'when the user has maintainer rights' do
before do
project.add_maintainer(user)
@ -137,29 +164,6 @@ RSpec.describe Projects::ImportsController, feature_category: :importers do
end
end
end
context 'when project is in group' do
let(:project) { create(:project_empty_repo, import_url: 'https://github.com/vim/vim.git', namespace: group) }
context 'when user has developer access to group and import is in progress' do
let(:import_state) { project.import_state }
before do
group.add_developer(user)
import_state.update!(status: :started)
end
context 'when group prohibits developers to import projects' do
let(:group) { create(:group, project_creation_level: Gitlab::Access::MAINTAINER_PROJECT_ACCESS) }
it 'returns 404 response' do
get :show, params: { namespace_id: project.namespace.to_param, project_id: project }
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
end
end
describe 'POST #create' do

View File

@ -19,6 +19,10 @@ RSpec.describe Gitlab::ImportExport::Project::ImportTask, :request_store, :silen
}
end
before do
stub_application_setting(import_sources: ['gitlab_project'])
end
subject { rake_task.import }
context 'when project import is valid' do

View File

@ -15,6 +15,7 @@ RSpec.describe Gitlab::ImportSources, feature_category: :importers do
gitlab_project
gitea
manifest
gitlab_built_in_project_template
]
expect(described_class.values).to eq(expected)
@ -31,6 +32,7 @@ RSpec.describe Gitlab::ImportSources, feature_category: :importers do
fogbugz
gitlab_project
gitea
gitlab_built_in_project_template
]
without_importer = %w[git manifest doesnotexist]
@ -55,6 +57,7 @@ RSpec.describe Gitlab::ImportSources, feature_category: :importers do
'gitlab_project' => Gitlab::ImportExport::Importer,
'gitea' => Gitlab::LegacyGithubImport::Importer,
'manifest' => nil,
'gitlab_built_in_project_template' => Gitlab::ImportExport::Importer,
'doesnotexist' => nil,
nil => nil
}
@ -76,6 +79,7 @@ RSpec.describe Gitlab::ImportSources, feature_category: :importers do
'gitlab_project' => 'GitLab export',
'gitea' => 'Gitea',
'manifest' => 'Manifest file',
'gitlab_built_in_project_template' => 'GitLab built-in project template',
'doesnotexist' => nil,
nil => nil
}
@ -88,7 +92,7 @@ RSpec.describe Gitlab::ImportSources, feature_category: :importers do
end
describe 'imports_repository? checker' do
let(:allowed_importers) { %w[github gitlab_project bitbucket bitbucket_server] }
let(:allowed_importers) { %w[github gitlab_project bitbucket bitbucket_server gitlab_built_in_project_template] }
it 'fails if any importer other than the allowed ones implements this method' do
current_importers = described_class.values.select { |kind| described_class.importer(kind).try(:imports_repository?) }
@ -125,6 +129,12 @@ RSpec.describe Gitlab::ImportSources, feature_category: :importers do
describe '.template?' do
subject { described_class.template?(template) }
context 'when importer is project template importer' do
let(:template) { 'gitlab_built_in_project_template' }
it { is_expected.to be_truthy }
end
context 'when importer is not project template importer' do
let(:template) { 'github' }
@ -145,8 +155,17 @@ RSpec.describe Gitlab::ImportSources, feature_category: :importers do
end
describe '.project_template_importers' do
it 'does not include non-project template importers' do
it 'returns names of project template importers' do
expect(described_class.project_template_importers).to include('gitlab_built_in_project_template')
expect(described_class.project_template_importers).not_to include('github')
end
end
describe 'gitlab_built_in_project_template' do
subject(:importer) { described_class.import_source('gitlab_built_in_project_template') }
it 'uses Gitlab::ImportExport::Importer' do
expect(importer.importer).to eq(Gitlab::ImportExport::Importer)
end
end
end

View File

@ -925,9 +925,11 @@ RSpec.describe ApplicationSetting, feature_category: :shared, type: :model do
end
describe 'import_sources' do
let(:valid_import_sources) { Gitlab::ImportSources.values }
let(:invalid_import_sources) { ['gitlab_built_in_project_template'] }
let(:valid_import_sources) { Gitlab::ImportSources.values - invalid_import_sources }
it { is_expected.to allow_value(valid_import_sources).for(:import_sources) }
it { is_expected.not_to allow_value(invalid_import_sources).for(:import_sources) }
end
describe 'default_artifacts_expire_in' do

View File

@ -64,7 +64,7 @@ RSpec.describe API::ProjectImport, :aggregate_failures, feature_category: :impor
it 'executes a limited number of queries', :use_clean_rails_redis_caching do
control = ActiveRecord::QueryRecorder.new { perform_archive_upload }
expect(control.count).to be <= 128
expect(control.count).to be <= 134
end
it 'schedules an import using a namespace' do
@ -73,6 +73,14 @@ RSpec.describe API::ProjectImport, :aggregate_failures, feature_category: :impor
perform_archive_upload
expect(json_response).to include({
'id' => kind_of(Integer),
'name' => 'test-import',
'name_with_namespace' => "#{namespace.name} / test-import",
'path' => 'test-import',
'import_type' => 'gitlab_project',
'path_with_namespace' => "#{namespace.path}/test-import"
})
expect(response).to have_gitlab_http_status(:created)
end
@ -337,7 +345,7 @@ RSpec.describe API::ProjectImport, :aggregate_failures, feature_category: :impor
def stub_import(namespace)
expect_any_instance_of(ProjectImportState).to receive(:schedule)
expect(::Projects::CreateService).to receive(:new).with(user, hash_including(namespace_id: namespace.id)).and_call_original
expect(::Projects::CreateService).to receive(:new).with(user, hash_including(namespace_id: namespace.id, import_type: 'gitlab_project')).and_call_original
end
end

View File

@ -1512,7 +1512,7 @@ RSpec.describe API::Projects, :aggregate_failures, feature_category: :groups_and
project = Project.find(json_response['id'])
expect(project).to be_saved
expect(project.import_type).to eq('gitlab_project')
expect(project.import_type).to eq('gitlab_built_in_project_template')
end
it 'returns 400 for an invalid template' do

View File

@ -10,9 +10,13 @@ RSpec.describe Projects::GitlabProjectsImportService, feature_category: :importe
let(:overwrite) { false }
let(:import_params) { { namespace_id: namespace.id, path: path, file: file, overwrite: overwrite } }
subject { described_class.new(namespace.owner, import_params) }
subject { described_class.new(namespace.owner, import_params, import_type: 'gitlab_project') }
before do
stub_application_setting(import_sources: ['gitlab_project'])
end
describe '#execute' do
it_behaves_like 'gitlab projects import validations'
it_behaves_like 'gitlab projects import validations', import_type: 'gitlab_project'
end
end

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
RSpec.shared_examples 'gitlab projects import validations' do
RSpec.shared_examples 'gitlab projects import validations' do |import_type:|
context 'with an invalid path' do
let(:path) { '/invalid-path/' }
@ -18,13 +18,14 @@ RSpec.shared_examples 'gitlab projects import validations' do
expect(project).to be_persisted
expect(project).to be_valid
expect(project.import_type).to eq(import_type.to_s)
end
end
context 'override params' do
it 'stores them as import data when passed' do
project = described_class
.new(namespace.owner, import_params, description: 'Hello')
.new(namespace.owner, import_params, { description: 'Hello' }, import_type: import_type)
.execute
expect(project.import_data.data['override_params']['description']).to eq('Hello')