Commit 8aebc174 authored by Stan Hu's avatar Stan Hu

Fix project imports not working with serialized data

The change in e404c311 broke models that
relied on single-type inheritance:

```
CommitStatus.new(type: 'Ci::Build').class
=> Ci::Build

CommitStatus.new.tap{|c| c.assign_attributes(type: 'Ci::Build')}.class
=> CommitStatus
```

As a result, any serialized options would not be properly saved to the
database, leading to errors expecting a `Hash` vs. a `String`, for
example.

This affected all pipelines that used shared runners because the build
would error out due to this serialization error.

Closes https://gitlab.com/gitlab-org/gitlab/issues/34860
parent 3548d193
---
title: Fix project imports not working with serialized data
merge_request: 19124
author:
type: fixed
...@@ -292,9 +292,11 @@ module Gitlab ...@@ -292,9 +292,11 @@ module Gitlab
existing_object existing_object
else else
object = relation_class.new # Because of single-type inheritance, we need to be careful to use the `type` field
# See https://gitlab.com/gitlab-org/gitlab/issues/34860#note_235321497
# Use #assign_attributes here to call object custom setters inheritance_column = relation_class.try(:inheritance_column)
inheritance_attributes = parsed_relation_hash.slice(inheritance_column)
object = relation_class.new(inheritance_attributes)
object.assign_attributes(parsed_relation_hash) object.assign_attributes(parsed_relation_hash)
object object
end end
......
...@@ -6226,7 +6226,9 @@ ...@@ -6226,7 +6226,9 @@
"job_id": null, "job_id": null,
"name": "test build 1", "name": "test build 1",
"deploy": false, "deploy": false,
"options": null, "options": {
"image": "busybox:latest"
},
"allow_failure": false, "allow_failure": false,
"stage": "test", "stage": "test",
"trigger_request_id": null, "trigger_request_id": null,
......
...@@ -283,6 +283,10 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do ...@@ -283,6 +283,10 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
it 'correctly restores association between a pipeline and a job' do it 'correctly restores association between a pipeline and a job' do
expect(CommitStatus.all).to all(have_attributes(pipeline_id: a_value > 0)) expect(CommitStatus.all).to all(have_attributes(pipeline_id: a_value > 0))
end end
it 'restores a Hash for CommitStatus options' do
expect(CommitStatus.all.map(&:options).compact).to all(be_a(Hash))
end
end end
end end
end end
......
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