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')
-rw-r--r--app/models/broadcast_message.rb10
-rw-r--r--app/models/merge_request/pipelines.rb60
2 files changed, 48 insertions, 22 deletions
diff --git a/app/models/broadcast_message.rb b/app/models/broadcast_message.rb
index dfcf28763ee..9c2ae92071d 100644
--- a/app/models/broadcast_message.rb
+++ b/app/models/broadcast_message.rb
@@ -20,7 +20,7 @@ class BroadcastMessage < ApplicationRecord
after_commit :flush_redis_cache
- def self.current
+ def self.current(current_path = nil)
messages = cache.fetch(CACHE_KEY, as: BroadcastMessage, expires_in: cache_expires_in) do
current_and_future_messages
end
@@ -33,7 +33,7 @@ class BroadcastMessage < ApplicationRecord
# cache so we don't keep running this code all the time.
cache.expire(CACHE_KEY) if now_or_future.empty?
- now_or_future.select(&:now?)
+ now_or_future.select(&:now?).select { |message| message.matches_current_path(current_path) }
end
def self.current_and_future_messages
@@ -72,6 +72,12 @@ class BroadcastMessage < ApplicationRecord
now? || future?
end
+ def matches_current_path(current_path)
+ return true if current_path.blank? || target_path.blank?
+
+ current_path.match(Regexp.escape(target_path).gsub('\\*', '.*'))
+ end
+
def flush_redis_cache
self.class.cache.expire(CACHE_KEY)
end
diff --git a/app/models/merge_request/pipelines.rb b/app/models/merge_request/pipelines.rb
index cba38f781a6..c32f29a9304 100644
--- a/app/models/merge_request/pipelines.rb
+++ b/app/models/merge_request/pipelines.rb
@@ -12,15 +12,18 @@ class MergeRequest::Pipelines
attr_reader :merge_request
- delegate :all_commit_shas, :source_project, :source_branch, to: :merge_request
+ delegate :commit_shas, :source_project, :source_branch, to: :merge_request
def all
- return Ci::Pipeline.none unless source_project
-
strong_memoize(:all_pipelines) do
- pipelines = Ci::Pipeline.from_union(
- [source_pipelines, detached_pipelines, triggered_for_branch],
- remove_duplicates: false)
+ next Ci::Pipeline.none unless source_project
+
+ pipelines =
+ if merge_request.persisted?
+ pipelines_using_cte
+ else
+ triggered_for_branch.for_sha(commit_shas)
+ end
sort(pipelines)
end
@@ -28,38 +31,55 @@ class MergeRequest::Pipelines
private
- def triggered_by_merge_request
- source_project.ci_pipelines
- .where(source: :merge_request_event, merge_request: merge_request)
+ def pipelines_using_cte
+ cte = Gitlab::SQL::CTE.new(:shas, merge_request.all_commits.select(:sha))
+
+ source_pipelines_join = cte.table[:sha].eq(Ci::Pipeline.arel_table[:source_sha])
+ source_pipelines = filter_by(triggered_by_merge_request, cte, source_pipelines_join)
+ detached_pipelines = filter_by_sha(triggered_by_merge_request, cte)
+ pipelines_for_branch = filter_by_sha(triggered_for_branch, cte)
+
+ Ci::Pipeline.with(cte.to_arel)
+ .from_union([source_pipelines, detached_pipelines, pipelines_for_branch])
+ end
+
+ def filter_by_sha(pipelines, cte)
+ hex = Arel::Nodes::SqlLiteral.new("'hex'")
+ string_sha = Arel::Nodes::NamedFunction.new('encode', [cte.table[:sha], hex])
+ join_condition = string_sha.eq(Ci::Pipeline.arel_table[:sha])
+
+ filter_by(pipelines, cte, join_condition)
end
- def detached_pipelines
- triggered_by_merge_request.for_sha(all_commit_shas)
+ def filter_by(pipelines, cte, join_condition)
+ shas_table =
+ Ci::Pipeline.arel_table
+ .join(cte.table, Arel::Nodes::InnerJoin)
+ .on(join_condition)
+ .join_sources
+
+ pipelines.joins(shas_table)
end
- def source_pipelines
- triggered_by_merge_request.for_source_sha(all_commit_shas)
+ def triggered_by_merge_request
+ source_project.ci_pipelines
+ .where(source: :merge_request_event, merge_request: merge_request)
end
def triggered_for_branch
source_project.ci_pipelines
.where(source: branch_pipeline_sources, ref: source_branch, tag: false)
- .for_sha(all_commit_shas)
- end
-
- def sources
- ::Ci::Pipeline.sources
end
def branch_pipeline_sources
strong_memoize(:branch_pipeline_sources) do
- sources.reject { |source| source == EVENT }.values
+ Ci::Pipeline.sources.reject { |source| source == EVENT }.values
end
end
def sort(pipelines)
sql = 'CASE ci_pipelines.source WHEN (?) THEN 0 ELSE 1 END, ci_pipelines.id DESC'
- query = ApplicationRecord.send(:sanitize_sql_array, [sql, sources[:merge_request_event]]) # rubocop:disable GitlabSecurity/PublicSend
+ query = ApplicationRecord.send(:sanitize_sql_array, [sql, Ci::Pipeline.sources[:merge_request_event]]) # rubocop:disable GitlabSecurity/PublicSend
pipelines.order(Arel.sql(query))
end