diff options
Diffstat (limited to 'app/models/merge_request.rb')
-rw-r--r-- | app/models/merge_request.rb | 75 |
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 |