Merge branch '36860-migrate-issues-author' into 'master'
Migrate old issues without author to the ghost user Closes #36860 See merge request !13860
This commit is contained in:
commit
745bc35666
|
@ -37,8 +37,7 @@
|
|||
%ul
|
||||
- if can_update_issue
|
||||
%li= link_to 'Edit', edit_project_issue_path(@project, @issue)
|
||||
/ TODO: simplify condition back #36860
|
||||
- if @issue.author && current_user != @issue.author
|
||||
- unless current_user == @issue.author
|
||||
%li= link_to 'Report abuse', new_abuse_report_path(user_id: @issue.author.id, ref_url: issue_url(@issue))
|
||||
- if can_update_issue
|
||||
%li= link_to 'Close issue', issue_path(@issue, issue: { state_event: :close }, format: 'json'), class: "btn-close js-btn-issue-action #{issue_button_visibility(@issue, true)}", title: 'Close issue'
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
class: "hidden-xs hidden-sm btn btn-grouped btn-reopen js-btn-issue-action #{issuable_button_visibility(issuable, false)}", title: "Reopen #{display_issuable_type}"
|
||||
- elsif can_update && !is_current_user
|
||||
= render 'shared/issuable/close_reopen_report_toggle', issuable: issuable
|
||||
- elsif issuable.author
|
||||
/ TODO: change back to else #36860
|
||||
- else
|
||||
= link_to 'Report abuse', new_abuse_report_path(user_id: issuable.author.id, ref_url: issuable_url(issuable)),
|
||||
class: 'hidden-xs hidden-sm btn btn-grouped btn-close-color', title: 'Report abuse'
|
||||
|
|
|
@ -37,15 +37,13 @@
|
|||
|
||||
%li.divider.droplab-item-ignore
|
||||
|
||||
/ TODO: remove condition #36860
|
||||
- if issuable.author
|
||||
%li.report-item{ data: { text: 'Report abuse', url: new_abuse_report_path(user_id: issuable.author.id, ref_url: issuable_url(issuable)),
|
||||
button_class: "#{button_class} btn-close-color", toggle_class: "#{toggle_class} btn-close-color", method: '' } }
|
||||
%button.btn.btn-transparent
|
||||
= icon('check', class: 'icon')
|
||||
.description
|
||||
%strong.title Report abuse
|
||||
%p.text
|
||||
Report
|
||||
= display_issuable_type.pluralize
|
||||
that are abusive, inappropriate or spam.
|
||||
%li.report-item{ data: { text: 'Report abuse', url: new_abuse_report_path(user_id: issuable.author.id, ref_url: issuable_url(issuable)),
|
||||
button_class: "#{button_class} btn-close-color", toggle_class: "#{toggle_class} btn-close-color", method: '' } }
|
||||
%button.btn.btn-transparent
|
||||
= icon('check', class: 'icon')
|
||||
.description
|
||||
%strong.title Report abuse
|
||||
%p.text
|
||||
Report
|
||||
= display_issuable_type.pluralize
|
||||
that are abusive, inappropriate or spam.
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Migrate issues authored by deleted user to the Ghost user
|
||||
merge_request:
|
||||
author:
|
||||
type: fixed
|
|
@ -0,0 +1,36 @@
|
|||
class MigrateIssuesToGhostUser < ActiveRecord::Migration
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
DOWNTIME = false
|
||||
|
||||
disable_ddl_transaction!
|
||||
|
||||
class User < ActiveRecord::Base
|
||||
self.table_name = 'users'
|
||||
end
|
||||
|
||||
class Issue < ActiveRecord::Base
|
||||
self.table_name = 'issues'
|
||||
|
||||
include ::EachBatch
|
||||
end
|
||||
|
||||
def reset_column_in_migration_models
|
||||
ActiveRecord::Base.clear_cache!
|
||||
|
||||
::User.reset_column_information
|
||||
end
|
||||
|
||||
def up
|
||||
reset_column_in_migration_models
|
||||
|
||||
# we use the model method because rewriting it is too complicated and would require copying multiple methods
|
||||
ghost_id = ::User.ghost.id
|
||||
|
||||
Issue.where('NOT EXISTS (?)', User.unscoped.select(1).where('issues.author_id = users.id')).each_batch do |relation|
|
||||
relation.update_all(author_id: ghost_id)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
end
|
||||
end
|
|
@ -0,0 +1,14 @@
|
|||
class AddForeignKeyToIssueAuthor < ActiveRecord::Migration
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
disable_ddl_transaction!
|
||||
|
||||
def up
|
||||
add_concurrent_foreign_key(:issues, :users, column: :author_id, on_delete: :nullify)
|
||||
end
|
||||
|
||||
def down
|
||||
remove_foreign_key(:issues, column: :author_id)
|
||||
end
|
||||
end
|
|
@ -11,7 +11,7 @@
|
|||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20170831195038) do
|
||||
ActiveRecord::Schema.define(version: 20170901071411) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
@ -1708,6 +1708,7 @@ ActiveRecord::Schema.define(version: 20170831195038) do
|
|||
add_foreign_key "issue_assignees", "users", name: "fk_5e0c8d9154", on_delete: :cascade
|
||||
add_foreign_key "issue_metrics", "issues", on_delete: :cascade
|
||||
add_foreign_key "issues", "projects", name: "fk_899c8f3231", on_delete: :cascade
|
||||
add_foreign_key "issues", "users", column: "author_id", name: "fk_05f1e72feb", on_delete: :cascade
|
||||
add_foreign_key "label_priorities", "labels", on_delete: :cascade
|
||||
add_foreign_key "label_priorities", "projects", on_delete: :cascade
|
||||
add_foreign_key "labels", "namespaces", column: "group_id", on_delete: :cascade
|
||||
|
|
|
@ -40,18 +40,4 @@ feature 'Issue Detail', :js do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when authored by a user who is later deleted' do
|
||||
before do
|
||||
issue.update_attribute(:author_id, nil)
|
||||
sign_in(user)
|
||||
visit project_issue_path(project, issue)
|
||||
end
|
||||
|
||||
it 'shows the issue' do
|
||||
page.within('.issuable-details') do
|
||||
expect(find('h2')).to have_content(issue.title)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
require 'spec_helper'
|
||||
require Rails.root.join('db', 'migrate', '20170825104051_migrate_issues_to_ghost_user.rb')
|
||||
|
||||
describe MigrateIssuesToGhostUser, :migration do
|
||||
describe '#up' do
|
||||
let(:projects) { table(:projects) }
|
||||
let(:issues) { table(:issues) }
|
||||
let(:users) { table(:users) }
|
||||
|
||||
before do
|
||||
projects.create!(name: 'gitlab')
|
||||
user = users.create(email: 'test@example.com')
|
||||
issues.create(title: 'Issue 1', author_id: nil, project_id: 1)
|
||||
issues.create(title: 'Issue 2', author_id: user.id, project_id: 1)
|
||||
end
|
||||
|
||||
context 'when ghost user exists' do
|
||||
let!(:ghost) { users.create(ghost: true, email: 'ghost@example.com') }
|
||||
|
||||
it 'does not create a new user' do
|
||||
expect { schema_migrate_up! }.not_to change { User.count }
|
||||
end
|
||||
|
||||
it 'migrates issues where author = nil to the ghost user' do
|
||||
schema_migrate_up!
|
||||
|
||||
expect(issues.first.reload.author_id).to eq(ghost.id)
|
||||
end
|
||||
|
||||
it 'does not change issues authored by an existing user' do
|
||||
expect { schema_migrate_up! }.not_to change { issues.second.reload.author_id}
|
||||
end
|
||||
end
|
||||
|
||||
context 'when ghost user does not exist' do
|
||||
it 'creates a new user' do
|
||||
expect { schema_migrate_up! }.to change { User.count }.by(1)
|
||||
end
|
||||
|
||||
it 'migrates issues where author = nil to the ghost user' do
|
||||
schema_migrate_up!
|
||||
|
||||
expect(issues.first.reload.author_id).to eq(User.ghost.id)
|
||||
end
|
||||
|
||||
it 'does not change issues authored by an existing user' do
|
||||
expect { schema_migrate_up! }.not_to change { issues.second.reload.author_id}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue