Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2019-12-27 12:07:59 +00:00
parent 59026a49b3
commit af8c2a780d
5 changed files with 171 additions and 17 deletions

View file

@ -116,7 +116,6 @@ schedule:review-build-cng:
extends: extends:
- .default-tags - .default-tags
- .default-retry - .default-retry
- .default-only
image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-charts-build-base image: registry.gitlab.com/gitlab-org/gitlab-build-images:gitlab-charts-build-base
dependencies: [] dependencies: []
variables: variables:
@ -156,10 +155,11 @@ schedule:review-build-cng:
when: always when: always
review-deploy: review-deploy:
extends: extends: .review-deploy-base
- .review-deploy-base rules:
- .only-review - <<: *if-canonical-gitlab-and-merge-request
- .only:changes-code-qa changes: *code-qa-patterns
when: on_success
schedule:review-deploy: schedule:review-deploy:
extends: extends:
@ -167,10 +167,7 @@ schedule:review-deploy:
- .only-review-schedules - .only-review-schedules
.base-review-stop: .base-review-stop:
extends: extends: .review-workflow-base
- .review-workflow-base
- .only-review
- .only:changes-code-qa
environment: environment:
action: stop action: stop
variables: variables:
@ -187,13 +184,20 @@ schedule:review-deploy:
review-stop-failed-deployment: review-stop-failed-deployment:
extends: .base-review-stop extends: .base-review-stop
stage: prepare stage: prepare
rules:
- <<: *if-canonical-gitlab-and-merge-request
changes: *code-qa-patterns
when: on_success
script: script:
- delete_failed_release - delete_failed_release
review-stop: review-stop:
extends: .base-review-stop extends: .base-review-stop
stage: review stage: review
when: manual rules:
- <<: *if-canonical-gitlab-and-merge-request
changes: *code-qa-patterns
when: manual
allow_failure: true allow_failure: true
script: script:
- delete_release - delete_release
@ -271,10 +275,11 @@ review-qa-all:
performance: performance.json performance: performance.json
review-performance: review-performance:
extends: extends: .review-performance-base
- .review-performance-base rules:
- .only-review - <<: *if-canonical-gitlab-and-merge-request
- .only:changes-code-qa changes: *code-qa-patterns
when: on_success
needs: ["review-deploy"] needs: ["review-deploy"]
dependencies: ["review-deploy"] dependencies: ["review-deploy"]
before_script: before_script:

View file

@ -0,0 +1,5 @@
---
title: Preload project, user and group to reuse objects during project import
merge_request: 21853
author:
type: performance

View file

@ -61,3 +61,29 @@ introduces non database logic to a model, and means we can no longer rely on
foreign keys to remove the data as this would result in the filesystem data foreign keys to remove the data as this would result in the filesystem data
being left behind. In such a case you should use a service class instead that being left behind. In such a case you should use a service class instead that
takes care of removing non database data. takes care of removing non database data.
## Alternative primary keys with has_one associations
Sometimes a `has_one` association is used to create a one-to-one relationship:
```ruby
class User < ActiveRecord::Base
has_one :user_config
end
class UserConfig < ActiveRecord::Base
belongs_to :user
end
```
In these cases, there may be an opportunity to remove the unnecessary `id`
column on the associated table, `user_config.id` in this example. Instead,
the originating table ID can be used as the primary key for the associated
table:
```ruby
create_table :user_configs, id: false do |t|
t.references :users, primary_key: true, default: nil, index: false, foreign_key: { on_delete: :cascade }
...
end
```

View file

@ -34,6 +34,8 @@ module Gitlab
PROJECT_REFERENCES = %w[project_id source_project_id target_project_id].freeze PROJECT_REFERENCES = %w[project_id source_project_id target_project_id].freeze
GROUP_REFERENCES = %w[group_id].freeze
BUILD_MODELS = %i[Ci::Build commit_status].freeze BUILD_MODELS = %i[Ci::Build commit_status].freeze
IMPORTED_OBJECT_MAX_RETRIES = 5.freeze IMPORTED_OBJECT_MAX_RETRIES = 5.freeze
@ -89,7 +91,13 @@ module Gitlab
setup_models setup_models
generate_imported_object object = generate_imported_object
# We preload the project, user, and group to re-use objects
object = preload_keys(object, PROJECT_REFERENCES, @project)
object = preload_keys(object, GROUP_REFERENCES, @project.group)
object = preload_keys(object, USER_REFERENCES, @user)
object
end end
def self.overrides def self.overrides
@ -122,6 +130,21 @@ module Gitlab
remove_encrypted_attributes! remove_encrypted_attributes!
end end
def preload_keys(object, references, value)
return object unless value
references.each do |key|
attribute = "#{key.delete_suffix('_id')}=".to_sym
next unless object.respond_to?(key) && object.respond_to?(attribute)
if object.read_attribute(key) == value&.id
object.public_send(attribute, value) # rubocop:disable GitlabSecurity/PublicSend
end
end
object
end
def update_user_references def update_user_references
USER_REFERENCES.each do |reference| USER_REFERENCES.each do |reference|
if @relation_hash[reference] if @relation_hash[reference]

View file

@ -3,7 +3,8 @@
require 'spec_helper' require 'spec_helper'
describe Gitlab::ImportExport::RelationFactory do describe Gitlab::ImportExport::RelationFactory do
let(:project) { create(:project) } let(:group) { create(:group) }
let(:project) { create(:project, :repository, group: group) }
let(:members_mapper) { double('members_mapper').as_null_object } let(:members_mapper) { double('members_mapper').as_null_object }
let(:merge_requests_mapping) { {} } let(:merge_requests_mapping) { {} }
let(:user) { create(:admin) } let(:user) { create(:admin) }
@ -59,7 +60,7 @@ describe Gitlab::ImportExport::RelationFactory do
end end
it 'has the new project_id' do it 'has the new project_id' do
expect(created_object.project_id).to eq(project.id) expect(created_object.project_id).to eql(project.id)
end end
it 'has a nil token' do it 'has a nil token' do
@ -96,6 +97,100 @@ describe Gitlab::ImportExport::RelationFactory do
end end
end end
context 'merge_requset object' do
let(:relation_sym) { :merge_requests }
let(:exported_member) do
{
"id" => 111,
"access_level" => 30,
"source_id" => 1,
"source_type" => "Project",
"user_id" => 3,
"notification_level" => 3,
"created_at" => "2016-11-18T09:29:42.634Z",
"updated_at" => "2016-11-18T09:29:42.634Z",
"user" => {
"id" => user.id,
"email" => user.email,
"username" => user.username
}
}
end
let(:members_mapper) do
Gitlab::ImportExport::MembersMapper.new(
exported_members: [exported_member],
user: user,
importable: project)
end
let(:relation_hash) do
{
'id' => 27,
'target_branch' => "feature",
'source_branch' => "feature_conflict",
'source_project_id' => project.id,
'target_project_id' => project.id,
'author_id' => user.id,
'assignee_id' => user.id,
'updated_by_id' => user.id,
'title' => "MR1",
'created_at' => "2016-06-14T15:02:36.568Z",
'updated_at' => "2016-06-14T15:02:56.815Z",
'state' => "opened",
'merge_status' => "unchecked",
'description' => "Description",
'position' => 0,
'source_branch_sha' => "ABCD",
'target_branch_sha' => "DCBA",
'merge_when_pipeline_succeeds' => true
}
end
it 'has preloaded author' do
expect(created_object.author).to equal(user)
end
it 'has preloaded updated_by' do
expect(created_object.updated_by).to equal(user)
end
it 'has preloaded source project' do
expect(created_object.source_project).to equal(project)
end
it 'has preloaded target project' do
expect(created_object.source_project).to equal(project)
end
end
context 'label object' do
let(:relation_sym) { :labels }
let(:relation_hash) do
{
"id": 3,
"title": "test3",
"color": "#428bca",
"group_id": project.group.id,
"created_at": "2016-07-22T08:55:44.161Z",
"updated_at": "2016-07-22T08:55:44.161Z",
"template": false,
"description": "",
"project_id": project.id,
"type": "GroupLabel"
}
end
it 'has preloaded project' do
expect(created_object.project).to equal(project)
end
it 'has preloaded group' do
expect(created_object.group).to equal(project.group)
end
end
# `project_id`, `described_class.USER_REFERENCES`, noteable_id, target_id, and some project IDs are already # `project_id`, `described_class.USER_REFERENCES`, noteable_id, target_id, and some project IDs are already
# re-assigned by described_class. # re-assigned by described_class.
context 'Potentially hazardous foreign keys' do context 'Potentially hazardous foreign keys' do