summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG1
-rw-r--r--app/controllers/projects_controller.rb2
-rw-r--r--app/models/merge_request.rb1
-rw-r--r--app/models/project.rb10
-rw-r--r--app/services/projects/unlink_fork_service.rb19
-rw-r--r--spec/services/projects/unlink_fork_service_spec.rb32
6 files changed, 54 insertions, 11 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 34cf78f8f8c..f72bb670ece 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -128,6 +128,7 @@ v 8.6.0
- Add main language of a project in the list of projects (Tiago Botelho)
- Add #upcoming filter to Milestone filter (Tiago Botelho)
- Add ability to show archived projects on dashboard, explore and group pages
+ - Remove fork link closes all merge requests opened on source project (Florent Baldino)
- Move group activity to separate page
- Create external users which are excluded of internal and private projects unless access was explicitly granted
- Continue parameters are checked to ensure redirection goes to the same instance
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index 62f53664db3..8c3a74c8236 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -71,7 +71,7 @@ class ProjectsController < Projects::ApplicationController
def remove_fork
return access_denied! unless can?(current_user, :remove_fork_project, @project)
- if @project.unlink_fork
+ if ::Projects::UnlinkForkService.new(@project, current_user).execute
flash[:notice] = 'The fork relationship has been removed.'
end
end
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 45c3b0a3a66..bf185cb5dd8 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -135,6 +135,7 @@ class MergeRequest < ActiveRecord::Base
scope :cared, ->(user) { where('assignee_id = :user OR author_id = :user', user: user.id) }
scope :by_milestone, ->(milestone) { where(milestone_id: milestone) }
scope :of_projects, ->(ids) { where(target_project_id: ids) }
+ scope :from_project, ->(project) { where(source_project_id: project.id) }
scope :merged, -> { with_state(:merged) }
scope :closed_and_merged, -> { with_states(:closed, :merged) }
diff --git a/app/models/project.rb b/app/models/project.rb
index c5022fd4ffc..3e1f04b4158 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -931,16 +931,6 @@ class Project < ActiveRecord::Base
self.builds_enabled = true
end
- def unlink_fork
- if forked?
- forked_from_project.lfs_objects.find_each do |lfs_object|
- lfs_object.projects << self
- end
-
- forked_project_link.destroy
- end
- end
-
def any_runners?(&block)
if runners.active.any?(&block)
return true
diff --git a/app/services/projects/unlink_fork_service.rb b/app/services/projects/unlink_fork_service.rb
new file mode 100644
index 00000000000..315c3e16292
--- /dev/null
+++ b/app/services/projects/unlink_fork_service.rb
@@ -0,0 +1,19 @@
+module Projects
+ class UnlinkForkService < BaseService
+ def execute
+ return unless @project.forked?
+
+ @project.forked_from_project.lfs_objects.find_each do |lfs_object|
+ lfs_object.projects << @project
+ end
+
+ merge_requests = @project.forked_from_project.merge_requests.opened.from_project(@project)
+
+ merge_requests.each do |mr|
+ MergeRequests::CloseService.new(@project, @current_user).execute(mr)
+ end
+
+ @project.forked_project_link.destroy
+ end
+ end
+end
diff --git a/spec/services/projects/unlink_fork_service_spec.rb b/spec/services/projects/unlink_fork_service_spec.rb
new file mode 100644
index 00000000000..23f5555d3e0
--- /dev/null
+++ b/spec/services/projects/unlink_fork_service_spec.rb
@@ -0,0 +1,32 @@
+require 'spec_helper'
+
+describe Projects::UnlinkForkService, services: true do
+ subject { Projects::UnlinkForkService.new(fork_project, user) }
+
+ let(:fork_link) { create(:forked_project_link) }
+ let(:fork_project) { fork_link.forked_to_project }
+ let(:user) { create(:user) }
+
+ context 'with opened merge request on the source project' do
+ let(:merge_request) { create(:merge_request, source_project: fork_project, target_project: fork_link.forked_from_project) }
+ let(:mr_close_service) { MergeRequests::CloseService.new(fork_project, user) }
+
+ before do
+ allow(MergeRequests::CloseService).to receive(:new).
+ with(fork_project, user).
+ and_return(mr_close_service)
+ end
+
+ it 'close all pending merge requests' do
+ expect(mr_close_service).to receive(:execute).with(merge_request)
+
+ subject.execute
+ end
+ end
+
+ it 'remove fork relation' do
+ expect(fork_project.forked_project_link).to receive(:destroy)
+
+ subject.execute
+ end
+end