Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/merge_request.rb')
-rw-r--r--app/models/merge_request.rb87
1 files changed, 77 insertions, 10 deletions
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 64b8223a1f0..1374e8a814a 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -50,12 +50,15 @@ class MergeRequest < ApplicationRecord
end
end
- has_many :merge_request_diffs
+ has_many :merge_request_diffs,
+ -> { regular }, inverse_of: :merge_request
has_many :merge_request_context_commits, inverse_of: :merge_request
has_many :merge_request_context_commit_diff_files, through: :merge_request_context_commits, source: :diff_files
has_one :merge_request_diff,
- -> { order('merge_request_diffs.id DESC') }, inverse_of: :merge_request
+ -> { regular.order('merge_request_diffs.id DESC') }, inverse_of: :merge_request
+ has_one :merge_head_diff,
+ -> { merge_head }, inverse_of: :merge_request, class_name: 'MergeRequestDiff'
has_one :cleanup_schedule, inverse_of: :merge_request
belongs_to :latest_merge_request_diff, class_name: 'MergeRequestDiff'
@@ -270,8 +273,7 @@ class MergeRequest < ApplicationRecord
by_commit_sha(sha),
by_squash_commit_sha(sha),
by_merge_commit_sha(sha)
- ],
- remove_duplicates: false
+ ]
)
end
scope :by_cherry_pick_sha, -> (sha) do
@@ -477,13 +479,17 @@ class MergeRequest < ApplicationRecord
# This is used after project import, to reset the IDs to the correct
# values. It is not intended to be called without having already scoped the
# relation.
+ #
+ # Only set `regular` merge request diffs as latest so `merge_head` diff
+ # won't be considered as `MergeRequest#merge_request_diff`.
def self.set_latest_merge_request_diff_ids!
- update = '
+ update = "
latest_merge_request_diff_id = (
SELECT MAX(id)
FROM merge_request_diffs
WHERE merge_requests.id = merge_request_diffs.merge_request_id
- )'.squish
+ AND merge_request_diffs.diff_type = #{MergeRequestDiff.diff_types[:regular]}
+ )".squish
self.each_batch do |batch|
batch.update_all(update)
@@ -915,6 +921,10 @@ class MergeRequest < ApplicationRecord
closed? && !source_project_missing? && source_branch_exists?
end
+ def can_be_closed?
+ opened?
+ end
+
def ensure_merge_request_diff
merge_request_diff.persisted? || create_merge_request_diff
end
@@ -922,7 +932,7 @@ class MergeRequest < ApplicationRecord
def create_merge_request_diff
fetch_ref!
- # n+1: https://gitlab.com/gitlab-org/gitlab-foss/issues/37435
+ # n+1: https://gitlab.com/gitlab-org/gitlab/-/issues/19377
Gitlab::GitalyClient.allow_n_plus_1_calls do
merge_request_diffs.create!
reload_merge_request_diff
@@ -996,7 +1006,7 @@ class MergeRequest < ApplicationRecord
# rubocop: enable CodeReuse/ServiceClass
def diffable_merge_ref?
- open? && merge_ref_head.present? && (Feature.enabled?(:display_merge_conflicts_in_diff, project) || can_be_merged?)
+ open? && merge_head_diff.present? && (Feature.enabled?(:display_merge_conflicts_in_diff, project) || can_be_merged?)
end
# Returns boolean indicating the merge_status should be rechecked in order to
@@ -1478,8 +1488,26 @@ class MergeRequest < ApplicationRecord
compare_reports(Ci::GenerateCoverageReportsService)
end
+ def has_codequality_mr_diff_report?
+ return false unless ::Gitlab::Ci::Features.display_quality_on_mr_diff?(project)
+
+ actual_head_pipeline&.has_codequality_mr_diff_report?
+ end
+
+ # TODO: this method and compare_test_reports use the same
+ # result type, which is handled by the controller's #reports_response.
+ # we should minimize mistakes by isolating the common parts.
+ # issue: https://gitlab.com/gitlab-org/gitlab/issues/34224
+ def find_codequality_mr_diff_reports
+ unless has_codequality_mr_diff_report?
+ return { status: :error, status_reason: 'This merge request does not have codequality mr diff reports' }
+ end
+
+ compare_reports(Ci::GenerateCodequalityMrDiffReportService)
+ end
+
def has_codequality_reports?
- return false unless Feature.enabled?(:codequality_mr_diff, project)
+ return false unless ::Gitlab::Ci::Features.display_codequality_backend_comparison?(project)
actual_head_pipeline&.has_reports?(Ci::JobArtifact.codequality_reports)
end
@@ -1530,6 +1558,26 @@ class MergeRequest < ApplicationRecord
end || { status: :parsing }
end
+ def has_sast_reports?
+ !!actual_head_pipeline&.has_reports?(::Ci::JobArtifact.sast_reports)
+ end
+
+ def has_secret_detection_reports?
+ !!actual_head_pipeline&.has_reports?(::Ci::JobArtifact.secret_detection_reports)
+ end
+
+ def compare_sast_reports(current_user)
+ return missing_report_error("SAST") unless has_sast_reports?
+
+ compare_reports(::Ci::CompareSecurityReportsService, current_user, 'sast')
+ end
+
+ def compare_secret_detection_reports(current_user)
+ return missing_report_error("secret detection") unless has_secret_detection_reports?
+
+ compare_reports(::Ci::CompareSecurityReportsService, current_user, 'secret_detection')
+ end
+
def calculate_reactive_cache(identifier, current_user_id = nil, report_type = nil, *args)
service_class = identifier.constantize
@@ -1760,7 +1808,7 @@ class MergeRequest < ApplicationRecord
end
def allows_reviewers?
- Feature.enabled?(:merge_request_reviewers, project, default_enabled: true)
+ true
end
def allows_multiple_reviewers?
@@ -1771,8 +1819,23 @@ class MergeRequest < ApplicationRecord
true
end
+ def find_reviewer(user)
+ merge_request_reviewers.find_by(user_id: user.id)
+ end
+
+ def enabled_reports
+ {
+ sast: report_type_enabled?(:sast),
+ secret_detection: report_type_enabled?(:secret_detection)
+ }
+ end
+
private
+ def missing_report_error(report_type)
+ { status: :error, status_reason: "This merge request does not have #{report_type} reports" }
+ end
+
def with_rebase_lock
if Feature.enabled?(:merge_request_rebase_nowait_lock, default_enabled: true)
with_retried_nowait_lock { yield }
@@ -1814,6 +1877,10 @@ class MergeRequest < ApplicationRecord
key = Gitlab::Routing.url_helpers.cached_widget_project_json_merge_request_path(project, self, format: :json)
Gitlab::EtagCaching::Store.new.touch(key)
end
+
+ def report_type_enabled?(report_type)
+ !!actual_head_pipeline&.batch_lookup_report_artifact_for_file_type(report_type)
+ end
end
MergeRequest.prepend_if_ee('::EE::MergeRequest')