Commit af8c2a78 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent 59026a49
...@@ -116,7 +116,6 @@ schedule:review-build-cng: ...@@ -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: ...@@ -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: ...@@ -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,12 +184,19 @@ schedule:review-deploy: ...@@ -187,12 +184,19 @@ 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
rules:
- <<: *if-canonical-gitlab-and-merge-request
changes: *code-qa-patterns
when: manual when: manual
allow_failure: true allow_failure: true
script: script:
...@@ -271,10 +275,11 @@ review-qa-all: ...@@ -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:
......
---
title: Preload project, user and group to reuse objects during project import
merge_request: 21853
author:
type: performance
...@@ -61,3 +61,29 @@ introduces non database logic to a model, and means we can no longer rely on ...@@ -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
```
...@@ -34,6 +34,8 @@ module Gitlab ...@@ -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 ...@@ -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 ...@@ -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]
......
...@@ -3,7 +3,8 @@ ...@@ -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 ...@@ -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 ...@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment