Avoid dynamic use of database schema during PushRule creation
Background
This is a corrective action for this production incident https://gitlab.com/gitlab-com/gl-infra/production/-/issues/7792.
This database migration triggered a forwards incompatible code path in PushRule creation: !97938 (merged).
Problem
The pathology is described by @krasio and @tkuah in:
This snippet (source) is responsible:
def create_push_rule_from_group
push_rule_attributes = project.group.predefined_push_rule.attributes.except("id")
project.create_push_rule(push_rule_attributes.merge(is_sample: false))
project.project_setting.update(push_rule: project.push_rule)
end
Because we use .attributes
, we get all of the columns. Even ones that the cached schema in rails does not know about yet.
That results in:
Unable to save project. Error: unknown attribute 'reject_non_dco_commits' for PushRule.
Proposal
When creating the PushRule, we need to ensure we only use columns that the cached schema actually contains.
@krasio suggested this:
project.group.predefined_push_rule.attributes.slice(*PushRule.column_names)