Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-06-25 03:24:27 +00:00
parent 5df018c2b1
commit 8f94de6da8
32 changed files with 451 additions and 158 deletions

View File

@ -5,6 +5,9 @@ module UploadsActions
include Gitlab::Utils::StrongMemoize
include SendFileUpload
# Starting with version 2, Markdown upload URLs use project / group IDs instead of paths
ID_BASED_UPLOAD_PATH_VERSION = 2
UPLOAD_MOUNTS = %w[avatar attachment file logo pwa_icon header_logo favicon screenshot].freeze
included do
@ -145,6 +148,12 @@ module UploadsActions
action_name == 'show' && embeddable?
end
def upload_version_at_least?(version)
return unless uploader && uploader.upload
uploader.upload.version >= version
end
def target_project
nil
end

View File

@ -8,12 +8,18 @@ class Groups::UploadsController < Groups::ApplicationController
before_action :authorize_upload_file!, only: [:create, :authorize]
before_action :verify_workhorse_api!, only: [:authorize]
before_action :disallow_new_uploads!, only: :show
feature_category :portfolio_management
urgency :low, [:show]
private
# Starting with this version, #show is handled by Banzai::UploadsController#show
def disallow_new_uploads!
render_404 if upload_version_at_least?(ID_BASED_UPLOAD_PATH_VERSION)
end
def upload_model_class
Group
end

View File

@ -10,11 +10,17 @@ class Projects::UploadsController < Projects::ApplicationController
before_action :authorize_upload_file!, only: [:create, :authorize]
before_action :verify_workhorse_api!, only: [:authorize]
before_action :disallow_new_uploads!, only: :show
feature_category :team_planning
private
# Starting with this version, #show is handled by Banzai::UploadsController#show
def disallow_new_uploads!
render_404 if upload_version_at_least?(ID_BASED_UPLOAD_PATH_VERSION)
end
def upload_model_class
Project
end

View File

@ -4,6 +4,10 @@ module RecordsUploads
module Concern
extend ActiveSupport::Concern
# This value is stored in `uploads.version`. Increment this value to have
# functionality that only applies to certain versions of uploads.
VERSION = 2
attr_accessor :upload
included do
@ -60,7 +64,8 @@ module RecordsUploads
size: file.size,
path: upload_path,
model: model,
mount_point: mounted_as
mount_point: mounted_as,
version: VERSION
)
end

View File

@ -15,5 +15,6 @@
- content_for :usage_quotas_tabs do
#js-storage-usage-app{ data: { project_path: @project.full_path } }
= render_if_exists 'projects/usage_quotas/transfer_tab_content'
= render_if_exists 'shared/usage_quotas/tabs_content/observability'
= render 'shared/usage_quotas/index'

View File

@ -0,0 +1,9 @@
---
migration_job_name: BackfillPackagesConanMetadataProjectId
description: Backfills sharding key `packages_conan_metadata.project_id` from `packages_packages`.
feature_category: package_registry
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/156254
milestone: '17.2'
queued_migration_version: 20240613071715
finalize_after: '2024-07-22'
finalized_by: # version of the migration that finalized this BBM

View File

@ -19,3 +19,4 @@ desired_sharding_key:
table: packages_packages
sharding_key: project_id
belongs_to: package
desired_sharding_key_migration_job_name: BackfillPackagesConanMetadataProjectId

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class AddProjectIdToPackagesConanMetadata < Gitlab::Database::Migration[2.2]
milestone '17.2'
def change
add_column :packages_conan_metadata, :project_id, :bigint
end
end

View File

@ -0,0 +1,9 @@
# frozen_string_literal: true
class AddVersionToUploads < Gitlab::Database::Migration[2.2]
milestone '17.2'
def change
add_column :uploads, :version, :integer, null: false, default: 1
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class IndexPackagesConanMetadataOnProjectId < Gitlab::Database::Migration[2.2]
milestone '17.2'
disable_ddl_transaction!
INDEX_NAME = 'index_packages_conan_metadata_on_project_id'
def up
add_concurrent_index :packages_conan_metadata, :project_id, name: INDEX_NAME
end
def down
remove_concurrent_index_by_name :packages_conan_metadata, INDEX_NAME
end
end

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class AddPackagesConanMetadataProjectIdFk < Gitlab::Database::Migration[2.2]
milestone '17.2'
disable_ddl_transaction!
def up
add_concurrent_foreign_key :packages_conan_metadata, :projects, column: :project_id, on_delete: :cascade
end
def down
with_lock_retries do
remove_foreign_key :packages_conan_metadata, column: :project_id
end
end
end

View File

@ -0,0 +1,25 @@
# frozen_string_literal: true
class AddPackagesConanMetadataProjectIdTrigger < Gitlab::Database::Migration[2.2]
milestone '17.2'
def up
install_sharding_key_assignment_trigger(
table: :packages_conan_metadata,
sharding_key: :project_id,
parent_table: :packages_packages,
parent_sharding_key: :project_id,
foreign_key: :package_id
)
end
def down
remove_sharding_key_assignment_trigger(
table: :packages_conan_metadata,
sharding_key: :project_id,
parent_table: :packages_packages,
parent_sharding_key: :project_id,
foreign_key: :package_id
)
end
end

View File

@ -0,0 +1,40 @@
# frozen_string_literal: true
class QueueBackfillPackagesConanMetadataProjectId < Gitlab::Database::Migration[2.2]
milestone '17.2'
restrict_gitlab_migration gitlab_schema: :gitlab_main_cell
MIGRATION = "BackfillPackagesConanMetadataProjectId"
DELAY_INTERVAL = 2.minutes
BATCH_SIZE = 1000
SUB_BATCH_SIZE = 100
def up
queue_batched_background_migration(
MIGRATION,
:packages_conan_metadata,
:id,
:project_id,
:packages_packages,
:project_id,
:package_id,
job_interval: DELAY_INTERVAL,
batch_size: BATCH_SIZE,
sub_batch_size: SUB_BATCH_SIZE
)
end
def down
delete_batched_background_migration(
MIGRATION,
:packages_conan_metadata,
:id,
[
:project_id,
:packages_packages,
:project_id,
:package_id
]
)
end
end

View File

@ -0,0 +1 @@
fa0b49f89efeed78982d1c8f96b068fa54024eed6a7ab2d847b7c37b9be147e2

View File

@ -0,0 +1 @@
41d1a6bef277adaf4bfffe31757bcacdb3f12eec6795d80901db329b3bb41e71

View File

@ -0,0 +1 @@
42d0b244f1163155ffd2839796a9f5077cd37fc96d10778d5bbdd17ff8394b42

View File

@ -0,0 +1 @@
51abebcfd2ac74b9ad980f2f6374ee49504c88289b6d79a28928bcc914082ef2

View File

@ -0,0 +1 @@
ad61d6d55b22a37b7052d6de321ebdd3f0a1543cacebd5fb128e052c2b38ba1c

View File

@ -0,0 +1 @@
85443e198681c111d6293606fa543e798777e9155cf5bfbd357ae2a7183bb008

View File

@ -829,6 +829,22 @@ RETURN NEW;
END
$$;
CREATE FUNCTION trigger_18bc439a6741() RETURNS trigger
LANGUAGE plpgsql
AS $$
BEGIN
IF NEW."project_id" IS NULL THEN
SELECT "project_id"
INTO NEW."project_id"
FROM "packages_packages"
WHERE "packages_packages"."id" = NEW."package_id";
END IF;
RETURN NEW;
END
$$;
CREATE FUNCTION trigger_1ed40f4d5f4e() RETURNS trigger
LANGUAGE plpgsql
AS $$
@ -13739,7 +13755,8 @@ CREATE TABLE packages_conan_metadata (
created_at timestamp with time zone NOT NULL,
updated_at timestamp with time zone NOT NULL,
package_username character varying(255) NOT NULL,
package_channel character varying(255) NOT NULL
package_channel character varying(255) NOT NULL,
project_id bigint
);
CREATE SEQUENCE packages_conan_metadata_id_seq
@ -18096,6 +18113,7 @@ CREATE TABLE uploads (
store integer DEFAULT 1,
mount_point character varying,
secret character varying,
version integer DEFAULT 1 NOT NULL,
CONSTRAINT check_5e9547379c CHECK ((store IS NOT NULL))
);
@ -27947,6 +27965,8 @@ CREATE UNIQUE INDEX index_packages_conan_file_metadata_on_package_file_id ON pac
CREATE UNIQUE INDEX index_packages_conan_metadata_on_package_id_username_channel ON packages_conan_metadata USING btree (package_id, package_username, package_channel);
CREATE INDEX index_packages_conan_metadata_on_project_id ON packages_conan_metadata USING btree (project_id);
CREATE INDEX index_packages_debian_group_component_files_on_component_id ON packages_debian_group_component_files USING btree (component_id);
CREATE INDEX index_packages_debian_group_distribution_keys_on_group_id ON packages_debian_group_distribution_keys USING btree (group_id);
@ -31291,6 +31311,8 @@ CREATE TRIGGER trigger_13d4aa8fe3dd BEFORE INSERT OR UPDATE ON draft_notes FOR E
CREATE TRIGGER trigger_174b23fa3dfb BEFORE INSERT OR UPDATE ON approval_project_rules_users FOR EACH ROW EXECUTE FUNCTION trigger_174b23fa3dfb();
CREATE TRIGGER trigger_18bc439a6741 BEFORE INSERT OR UPDATE ON packages_conan_metadata FOR EACH ROW EXECUTE FUNCTION trigger_18bc439a6741();
CREATE TRIGGER trigger_1ed40f4d5f4e BEFORE INSERT OR UPDATE ON packages_maven_metadata FOR EACH ROW EXECUTE FUNCTION trigger_1ed40f4d5f4e();
CREATE TRIGGER trigger_207005e8e995 BEFORE INSERT OR UPDATE ON operations_strategies FOR EACH ROW EXECUTE FUNCTION trigger_207005e8e995();
@ -32061,6 +32083,9 @@ ALTER TABLE ONLY subscription_user_add_on_assignments
ALTER TABLE ONLY vulnerabilities
ADD CONSTRAINT fk_725465b774 FOREIGN KEY (dismissed_by_id) REFERENCES users(id) ON DELETE SET NULL;
ALTER TABLE ONLY packages_conan_metadata
ADD CONSTRAINT fk_7302a29cd9 FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
ALTER TABLE ONLY approval_merge_request_rules
ADD CONSTRAINT fk_73fec3d7e5 FOREIGN KEY (approval_policy_rule_id) REFERENCES approval_policy_rules(id) ON DELETE CASCADE;

View File

@ -82,7 +82,8 @@ module Bitbucket
target_branch_name: target_branch_name,
target_branch_sha: target_branch_sha,
source_and_target_project_different: source_and_target_project_different,
reviewers: reviewers
reviewers: reviewers,
closed_by: closed_by
}
end
@ -107,6 +108,10 @@ module Bitbucket
def source_and_target_project_different
source_repo_uuid != target_repo_uuid
end
def closed_by
raw['closed_by']&.dig('uuid')
end
end
end
end

View File

@ -0,0 +1,10 @@
# frozen_string_literal: true
module Gitlab
module BackgroundMigration
class BackfillPackagesConanMetadataProjectId < BackfillDesiredShardingKeyJob
operation_name :backfill_packages_conan_metadata_project_id
feature_category :package_registry
end
end
end

View File

@ -45,6 +45,8 @@ module Gitlab
merge_request.reviewer_ids = reviewers
merge_request.save!
create_merge_request_metrics(merge_request)
metrics.merge_requests_counter.increment
end
@ -85,7 +87,26 @@ module Gitlab
end
def author_id
user_finder.gitlab_user_id(project, object[:author])
@author_id ||= user_finder.gitlab_user_id(project, object[:author])
end
def create_merge_request_metrics(merge_request)
return if object[:closed_by].nil?
case object[:state]
when 'merged'
merge_request.metrics.merged_by_id = closed_by_id
when 'closed'
merge_request.metrics.latest_closed_by_id = closed_by_id
else
return
end
merge_request.metrics.save!
end
def closed_by_id
user_finder.gitlab_user_id(project, object[:closed_by])
end
def reviewers

View File

@ -48017,9 +48017,6 @@ msgstr ""
msgid "SecurityOrchestration|Select frameworks"
msgstr ""
msgid "SecurityOrchestration|Select groups"
msgstr ""
msgid "SecurityOrchestration|Select policy"
msgstr ""
@ -56883,6 +56880,9 @@ msgstr ""
msgid "UsageQuota|No projects to display."
msgstr ""
msgid "UsageQuota|Observability"
msgstr ""
msgid "UsageQuota|Pending Members"
msgstr ""

View File

@ -15,6 +15,8 @@ RSpec.describe Groups::UploadsController, feature_category: :portfolio_managemen
{ group_id: other_model }
end
let(:legacy_version) { UploadsActions::ID_BASED_UPLOAD_PATH_VERSION - 1 }
it_behaves_like 'handle uploads' do
let(:uploader_class) { NamespaceFileUploader }
end
@ -36,102 +38,99 @@ RSpec.describe Groups::UploadsController, feature_category: :portfolio_managemen
end
describe "GET #show" do
let(:filename) { "rails_sample.jpg" }
let(:user) { create(:user) }
let(:jpg) { fixture_file_upload('spec/fixtures/rails_sample.jpg', 'image/jpg') }
let(:txt) { fixture_file_upload('spec/fixtures/doc_sample.txt', 'text/plain') }
let(:uploader_class) { NamespaceFileUploader }
let(:secret) { uploader_class.generate_secret }
let(:upload_service) do
UploadService.new(model, jpg, uploader_class).execute
end
let(:filename) { "rails_sample.jpg" }
let!(:upload) { create(:upload, :namespace_upload, :with_file, model: model, filename: filename) }
let(:show_upload) do
get :show, params: params.merge(secret: secret, filename: filename)
get :show, params: params.merge(secret: upload.secret, filename: filename)
end
before do
allow(uploader_class).to receive(:generate_secret).and_return(secret)
it 'responds with status 404' do
show_upload
allow_next_instance_of(uploader_class) do |instance|
allow(instance).to receive(:image?).and_return(true)
end
upload_service
expect(response).to have_gitlab_http_status(:not_found)
end
context 'when the group is public' do
before do
model.update_attribute(:visibility_level, Gitlab::VisibilityLevel::PUBLIC)
context 'with legacy upload' do
let!(:upload) do
create(:upload, :namespace_upload, :with_file, model: model, filename: filename, version: legacy_version)
end
context "when not signed in" do
it "responds with appropriate status" do
show_upload
expect(response).to have_gitlab_http_status(:ok)
context 'when the group is public' do
before do
model.update_attribute(:visibility_level, Gitlab::VisibilityLevel::PUBLIC)
end
context 'when uploader class does not match the upload' do
let(:uploader_class) { FileUploader }
it 'responds with status 404' do
context "when not signed in" do
it "responds with appropriate status" do
show_upload
expect(response).to have_gitlab_http_status(:not_found)
expect(response).to have_gitlab_http_status(:ok)
end
context 'when uploader class does not match the upload' do
let!(:upload) do
create(:upload, :issuable_upload, :with_file, model: model, filename: filename, version: legacy_version)
end
it 'responds with status 404' do
show_upload
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'when filename does not match' do
let(:invalid_filename) { 'invalid_filename.jpg' }
it 'responds with status 404' do
get :show, params: params.merge(secret: upload.secret, filename: invalid_filename)
expect(response).to have_gitlab_http_status(:not_found)
end
end
end
context 'when filename does not match' do
let(:invalid_filename) { 'invalid_filename.jpg' }
context "when signed in" do
before do
sign_in(user)
end
it 'responds with status 404' do
get :show, params: params.merge(secret: secret, filename: invalid_filename)
context "when the user doesn't have access to the model" do
it "responds with status 200" do
show_upload
expect(response).to have_gitlab_http_status(:not_found)
expect(response).to have_gitlab_http_status(:ok)
end
end
end
end
context "when signed in" do
context 'when the group is private' do
before do
sign_in(user)
model.update_attribute(:visibility_level, Gitlab::VisibilityLevel::PRIVATE)
end
context "when the user doesn't have access to the model" do
it "responds with status 200" do
context "when not signed in" do
it "responds with appropriate status" do
show_upload
expect(response).to have_gitlab_http_status(:ok)
end
end
end
end
context 'when the group is private' do
before do
model.update_attribute(:visibility_level, Gitlab::VisibilityLevel::PRIVATE)
end
context "when signed in" do
before do
sign_in(user)
end
context "when not signed in" do
it "responds with appropriate status" do
show_upload
context "when the user doesn't have access to the model" do
it "responds with status 200" do
show_upload
expect(response).to have_gitlab_http_status(:ok)
end
end
context "when signed in" do
before do
sign_in(user)
end
context "when the user doesn't have access to the model" do
it "responds with status 200" do
show_upload
expect(response).to have_gitlab_http_status(:ok)
expect(response).to have_gitlab_http_status(:ok)
end
end
end
end

View File

@ -15,6 +15,8 @@ RSpec.describe Projects::UploadsController, feature_category: :team_planning do
{ namespace_id: other_model.namespace.to_param, project_id: other_model }
end
let(:legacy_version) { UploadsActions::ID_BASED_UPLOAD_PATH_VERSION - 1 }
it_behaves_like 'handle uploads'
context 'when the URL the old style, without /-/system' do
@ -55,77 +57,40 @@ RSpec.describe Projects::UploadsController, feature_category: :team_planning do
end
describe "GET #show" do
let(:filename) { "rails_sample.jpg" }
let(:user) { create(:user) }
let(:jpg) { fixture_file_upload('spec/fixtures/rails_sample.jpg', 'image/jpg') }
let(:txt) { fixture_file_upload('spec/fixtures/doc_sample.txt', 'text/plain') }
let(:secret) { FileUploader.generate_secret }
let(:uploader_class) { FileUploader }
let(:upload_service) do
UploadService.new(model, jpg, uploader_class).execute
end
let(:filename) { "rails_sample.jpg" }
let!(:upload) { create(:upload, :issuable_upload, :with_file, model: model, filename: filename) }
let(:show_upload) do
get :show, params: params.merge(secret: secret, filename: filename)
get :show, params: params.merge(secret: upload.secret, filename: filename)
end
before do
allow(FileUploader).to receive(:generate_secret).and_return(secret)
it 'responds with status 404' do
show_upload
allow_next_instance_of(FileUploader) do |instance|
allow(instance).to receive(:image?).and_return(true)
end
upload_service
expect(response).to have_gitlab_http_status(:not_found)
end
context 'when project is private do' do
before do
model.update_attribute(:visibility_level, Gitlab::VisibilityLevel::PRIVATE)
context 'with legacy upload' do
let!(:upload) do
create(:upload, :issuable_upload, :with_file, model: model, filename: filename, version: legacy_version)
end
context "when not signed in" do
context 'when the project has setting enforce_auth_checks_on_uploads true' do
before do
model.update!(enforce_auth_checks_on_uploads: true)
end
it "responds with status 302" do
show_upload
expect(response).to have_gitlab_http_status(:redirect)
end
end
context 'when the project has setting enforce_auth_checks_on_uploads false' do
before do
model.update!(enforce_auth_checks_on_uploads: false)
end
it "responds with status 200" do
show_upload
expect(response).to have_gitlab_http_status(:ok)
end
end
end
context "when signed in" do
context 'when project is private do' do
before do
sign_in(user)
model.update_attribute(:visibility_level, Gitlab::VisibilityLevel::PRIVATE)
end
context "when the user doesn't have access to the model" do
context "when not signed in" do
context 'when the project has setting enforce_auth_checks_on_uploads true' do
before do
model.update!(enforce_auth_checks_on_uploads: true)
end
it "responds with status 404" do
it "responds with status 302" do
show_upload
expect(response).to have_gitlab_http_status(:not_found)
expect(response).to have_gitlab_http_status(:redirect)
end
end
@ -141,46 +106,46 @@ RSpec.describe Projects::UploadsController, feature_category: :team_planning do
end
end
end
end
end
context 'when project is public' do
before do
model.update_attribute(:visibility_level, Gitlab::VisibilityLevel::PUBLIC)
end
context "when not signed in" do
context 'when the project has setting enforce_auth_checks_on_uploads true' do
context "when signed in" do
before do
model.update!(enforce_auth_checks_on_uploads: true)
sign_in(user)
end
it "responds with status 200" do
show_upload
context "when the user doesn't have access to the model" do
context 'when the project has setting enforce_auth_checks_on_uploads true' do
before do
model.update!(enforce_auth_checks_on_uploads: true)
end
expect(response).to have_gitlab_http_status(:ok)
end
end
it "responds with status 404" do
show_upload
context 'when the project has setting enforce_auth_checks_on_uploads false' do
before do
model.update!(enforce_auth_checks_on_uploads: false)
end
expect(response).to have_gitlab_http_status(:not_found)
end
end
it "responds with status 200" do
show_upload
context 'when the project has setting enforce_auth_checks_on_uploads false' do
before do
model.update!(enforce_auth_checks_on_uploads: false)
end
expect(response).to have_gitlab_http_status(:ok)
it "responds with status 200" do
show_upload
expect(response).to have_gitlab_http_status(:ok)
end
end
end
end
end
context "when signed in" do
context 'when project is public' do
before do
sign_in(user)
model.update_attribute(:visibility_level, Gitlab::VisibilityLevel::PUBLIC)
end
context "when the user doesn't have access to the model" do
context "when not signed in" do
context 'when the project has setting enforce_auth_checks_on_uploads true' do
before do
model.update!(enforce_auth_checks_on_uploads: true)
@ -205,6 +170,38 @@ RSpec.describe Projects::UploadsController, feature_category: :team_planning do
end
end
end
context "when signed in" do
before do
sign_in(user)
end
context "when the user doesn't have access to the model" do
context 'when the project has setting enforce_auth_checks_on_uploads true' do
before do
model.update!(enforce_auth_checks_on_uploads: true)
end
it "responds with status 200" do
show_upload
expect(response).to have_gitlab_http_status(:ok)
end
end
context 'when the project has setting enforce_auth_checks_on_uploads false' do
before do
model.update!(enforce_auth_checks_on_uploads: false)
end
it "responds with status 200" do
show_upload
expect(response).to have_gitlab_http_status(:ok)
end
end
end
end
end
end
end

View File

@ -8,6 +8,7 @@ FactoryBot.define do
mount_point { :avatar }
secret { nil }
store { ObjectStorage::Store::LOCAL }
version { RecordsUploads::Concern::VERSION }
# we should build a mount agnostic upload by default
transient do

View File

@ -108,6 +108,7 @@ RSpec.describe Bitbucket::Representation::PullRequest, feature_category: :import
source_branch_sha: 'source-commit-hash',
merge_commit_sha: 'merge-commit-hash',
state: 'merged',
closed_by: nil,
target_branch_name: 'destination-branch-name',
target_branch_sha: 'destination-commit-hash',
title: 'title',

View File

@ -0,0 +1,15 @@
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe Gitlab::BackgroundMigration::BackfillPackagesConanMetadataProjectId,
feature_category: :package_registry,
schema: 20240613071711 do
include_examples 'desired sharding key backfill job' do
let(:batch_table) { :packages_conan_metadata }
let(:backfill_column) { :project_id }
let(:backfill_via_table) { :packages_packages }
let(:backfill_via_column) { :project_id }
let(:backfill_via_foreign_key) { :package_id }
end
end

View File

@ -9,8 +9,10 @@ RSpec.describe Gitlab::BitbucketImport::Importers::PullRequestImporter, :clean_g
let_it_be(:bitbucket_user) { create(:user) }
let_it_be(:user_2) { create(:user) }
let_it_be(:user_3) { create(:user) }
let_it_be(:closed_by_user) { create(:user) }
let_it_be(:identity) { create(:identity, user: bitbucket_user, extern_uid: '{123}', provider: :bitbucket) }
let_it_be(:identity_2) { create(:identity, user: user_2, extern_uid: 'user_2', provider: :bitbucket) }
let_it_be(:closed_by_identity) { create(:identity, user: closed_by_user, extern_uid: '{345}', provider: :bitbucket) }
let(:mentions_converter) { Gitlab::Import::MentionsConverter.new('bitbucket', project) }
let(:source_branch_sha) { project.repository.commit.sha }
let(:target_branch_sha) { project.repository.commit('refs/heads/master').sha }
@ -29,7 +31,8 @@ RSpec.describe Gitlab::BitbucketImport::Importers::PullRequestImporter, :clean_g
target_branch_sha: target_branch_sha,
title: 'title',
updated_at: Date.today,
reviewers: %w[user_2 user_3]
reviewers: %w[user_2 user_3],
closed_by: '{345}'
}
end
@ -65,6 +68,8 @@ RSpec.describe Gitlab::BitbucketImport::Importers::PullRequestImporter, :clean_g
expect(merge_request.reviewer_ids).to eq([user_2.id])
expect(merge_request.merge_request_diffs.first.base_commit_sha).to eq(source_branch_sha)
expect(merge_request.merge_request_diffs.first.head_commit_sha).to eq(target_branch_sha)
expect(merge_request.metrics.merged_by_id).to eq(closed_by_user.id)
expect(merge_request.metrics.latest_closed_by_id).to be_nil
end
it 'converts mentions in the description' do
@ -78,6 +83,8 @@ RSpec.describe Gitlab::BitbucketImport::Importers::PullRequestImporter, :clean_g
described_class.new(project, hash.merge(state: 'closed')).execute
expect(project.merge_requests.first.closed?).to be_truthy
expect(project.merge_requests.first.metrics.latest_closed_by_id).to eq(closed_by_user.id)
expect(project.merge_requests.first.metrics.merged_by_id).to be_nil
end
end
@ -86,6 +93,8 @@ RSpec.describe Gitlab::BitbucketImport::Importers::PullRequestImporter, :clean_g
described_class.new(project, hash.merge(state: 'opened')).execute
expect(project.merge_requests.first.opened?).to be_truthy
expect(project.merge_requests.first.metrics.latest_closed_by_id).to be_nil
expect(project.merge_requests.first.metrics.merged_by_id).to be_nil
end
end
@ -131,6 +140,30 @@ RSpec.describe Gitlab::BitbucketImport::Importers::PullRequestImporter, :clean_g
end
end
context 'when closed by user cannot be found' do
before do
User.find(closed_by_user.id).destroy!
end
it 'sets the merged by user to the project creator' do
importer.execute
expect(project.merge_requests.first.metrics.merged_by_id).to eq(project.creator_id)
expect(project.merge_requests.first.metrics.latest_closed_by_id).to be_nil
end
context 'when merge state is closed' do
let(:hash) { super().merge(state: 'closed') }
it 'sets the closed by user to the project creator' do
importer.execute
expect(project.merge_requests.first.metrics.latest_closed_by_id).to eq(project.creator_id)
expect(project.merge_requests.first.metrics.merged_by_id).to be_nil
end
end
end
describe 'head_commit_sha for merge request diff' do
let(:diff) { project.merge_requests.first.merge_request_diffs.first }
let(:min_length) { Commit::MIN_SHA_LENGTH }

View File

@ -0,0 +1,33 @@
# frozen_string_literal: true
require 'spec_helper'
require_migration!
RSpec.describe QueueBackfillPackagesConanMetadataProjectId, feature_category: :package_registry do
let!(:batched_migration) { described_class::MIGRATION }
it 'schedules a new batched migration' do
reversible_migration do |migration|
migration.before -> {
expect(batched_migration).not_to have_scheduled_batched_migration
}
migration.after -> {
expect(batched_migration).to have_scheduled_batched_migration(
table_name: :packages_conan_metadata,
column_name: :id,
interval: described_class::DELAY_INTERVAL,
batch_size: described_class::BATCH_SIZE,
sub_batch_size: described_class::SUB_BATCH_SIZE,
gitlab_schema: :gitlab_main_cell,
job_arguments: [
:project_id,
:packages_packages,
:project_id,
:package_id
]
)
}
end
end
end

View File

@ -70,24 +70,21 @@ RSpec.shared_examples 'handle uploads' do
describe "GET #show" do
let(:filename) { "rails_sample.jpg" }
let(:upload_service) do
UploadService.new(model, jpg, uploader_class).execute
let(:secret) { upload.secret }
let!(:upload) do
create(
:upload, :issuable_upload, :with_file,
uploader: uploader_class.to_s, model: model, filename: filename, version: legacy_version
)
end
let(:show_upload) do
get :show, params: params.merge(secret: secret, filename: filename)
end
before do
allow(FileUploader).to receive(:generate_secret).and_return(secret)
upload_service
end
context 'when the secret is invalid' do
let(:secret) { "../../../../../../../../" }
let(:filename) { "Gemfile.lock" }
let(:upload_service) { nil }
it 'responds with status 404' do
show_upload
@ -107,11 +104,9 @@ RSpec.shared_examples 'handle uploads' do
end
context 'when the upload does not have a MIME type that Rails knows' do
let(:po) { fixture_file_upload('spec/fixtures/missing_metadata.po', 'text/plain') }
let(:filename) { 'missing_metadata.po' }
it 'falls back to the null type' do
UploadService.new(model, po, uploader_class).execute
get :show, params: params.merge(secret: secret, filename: 'missing_metadata.po')
expect(response.headers['Content-Type']).to eq('application/octet-stream')