summaryrefslogtreecommitdiff
path: root/app/models/merge_request.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/merge_request.rb')
-rw-r--r--app/models/merge_request.rb75
1 files changed, 64 insertions, 11 deletions
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index df5678ec2f1..77e48ce11e8 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -63,6 +63,7 @@ class MergeRequest < ActiveRecord::Base
dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
has_many :cached_closes_issues, through: :merge_requests_closing_issues, source: :issue
+ has_many :merge_request_pipelines, foreign_key: 'merge_request_id', class_name: 'Ci::Pipeline'
belongs_to :assignee, class_name: "User"
@@ -538,15 +539,26 @@ class MergeRequest < ActiveRecord::Base
def validate_branches
if target_project == source_project && target_branch == source_branch
- errors.add :branch_conflict, "You can not use same project/branch for source and target"
+ errors.add :branch_conflict, "You can't use same project/branch for source and target"
+ return
end
if opened?
- similar_mrs = self.target_project.merge_requests.where(source_branch: source_branch, target_branch: target_branch, source_project_id: source_project.try(:id)).opened
- similar_mrs = similar_mrs.where('id not in (?)', self.id) if self.id
- if similar_mrs.any?
- errors.add :validate_branches,
- "Cannot Create: This merge request already exists: #{similar_mrs.pluck(:title)}"
+ similar_mrs = target_project
+ .merge_requests
+ .where(source_branch: source_branch, target_branch: target_branch)
+ .where(source_project_id: source_project&.id)
+ .opened
+
+ similar_mrs = similar_mrs.where.not(id: id) if persisted?
+
+ conflict = similar_mrs.first
+
+ if conflict.present?
+ errors.add(
+ :validate_branches,
+ "Another open merge request already exists for this source branch: #{conflict.to_reference}"
+ )
end
end
end
@@ -1053,18 +1065,59 @@ class MergeRequest < ActiveRecord::Base
diverged_commits_count > 0
end
- def all_pipelines
+ def all_pipelines(shas: all_commit_shas)
return Ci::Pipeline.none unless source_project
- @all_pipelines ||= source_project.pipelines
- .where(sha: all_commit_shas, ref: source_branch)
- .order(id: :desc)
+ @all_pipelines ||= source_project.ci_pipelines
+ .where(sha: shas, ref: source_branch)
+ .where(merge_request: [nil, self])
+ .sort_by_merge_request_pipelines
+ end
+
+ def merge_request_pipeline_exists?
+ merge_request_pipelines.exists?(sha: diff_head_sha)
end
def has_test_reports?
actual_head_pipeline&.has_test_reports?
end
+ def predefined_variables
+ Gitlab::Ci::Variables::Collection.new.tap do |variables|
+ variables.append(key: 'CI_MERGE_REQUEST_ID', value: id.to_s)
+ variables.append(key: 'CI_MERGE_REQUEST_IID', value: iid.to_s)
+
+ variables.append(key: 'CI_MERGE_REQUEST_REF_PATH',
+ value: ref_path.to_s)
+
+ variables.append(key: 'CI_MERGE_REQUEST_PROJECT_ID',
+ value: project.id.to_s)
+
+ variables.append(key: 'CI_MERGE_REQUEST_PROJECT_PATH',
+ value: project.full_path)
+
+ variables.append(key: 'CI_MERGE_REQUEST_PROJECT_URL',
+ value: project.web_url)
+
+ variables.append(key: 'CI_MERGE_REQUEST_TARGET_BRANCH_NAME',
+ value: target_branch.to_s)
+
+ if source_project
+ variables.append(key: 'CI_MERGE_REQUEST_SOURCE_PROJECT_ID',
+ value: source_project.id.to_s)
+
+ variables.append(key: 'CI_MERGE_REQUEST_SOURCE_PROJECT_PATH',
+ value: source_project.full_path)
+
+ variables.append(key: 'CI_MERGE_REQUEST_SOURCE_PROJECT_URL',
+ value: source_project.web_url)
+
+ variables.append(key: 'CI_MERGE_REQUEST_SOURCE_BRANCH_NAME',
+ value: source_branch.to_s)
+ end
+ end
+ end
+
# rubocop: disable CodeReuse/ServiceClass
def compare_test_reports
unless has_test_reports?
@@ -1215,7 +1268,7 @@ class MergeRequest < ActiveRecord::Base
end
def base_pipeline
- @base_pipeline ||= project.pipelines
+ @base_pipeline ||= project.ci_pipelines
.order(id: :desc)
.find_by(sha: diff_base_sha)
end