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:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-09-09 00:13:09 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-09-09 00:13:09 +0300
commitf26a600a69b3a13d3102d801f5d92d3235ea56d4 (patch)
tree87393fc4a3de2ff1324ea014563de27512316227 /app/models
parent03a8aa2ca6a7d7aced2fde7815c8ef85d681db60 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/models')
-rw-r--r--app/models/ci/pipeline.rb32
-rw-r--r--app/models/ci/runner.rb8
-rw-r--r--app/models/concerns/integrations/has_web_hook.rb1
-rw-r--r--app/models/concerns/sortable.rb27
-rw-r--r--app/models/environment.rb2
-rw-r--r--app/models/environment_status.rb2
-rw-r--r--app/models/integrations/buildkite.rb8
-rw-r--r--app/models/issue.rb26
-rw-r--r--app/models/member.rb87
-rw-r--r--app/models/merge_request.rb2
-rw-r--r--app/models/namespace.rb2
-rw-r--r--app/models/onboarding/progress.rb118
-rw-r--r--app/models/onboarding_progress.rb114
-rw-r--r--app/models/project.rb4
14 files changed, 247 insertions, 186 deletions
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index f2d4c9a43c3..4c0fbcfe330 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -611,7 +611,7 @@ module Ci
if cascade_to_children
# cancel any bridges that could spin up new child pipelines
- cancel_jobs(bridges_in_self_and_descendants.cancelable, retries: retries, auto_canceled_by_pipeline_id: auto_canceled_by_pipeline_id)
+ cancel_jobs(bridges_in_self_and_project_descendants.cancelable, retries: retries, auto_canceled_by_pipeline_id: auto_canceled_by_pipeline_id)
cancel_children(auto_canceled_by_pipeline_id: auto_canceled_by_pipeline_id, execute_async: execute_async)
end
end
@@ -943,26 +943,26 @@ module Ci
).base_and_descendants.select(:id)
end
- def build_with_artifacts_in_self_and_descendants(name)
- builds_in_self_and_descendants
+ def build_with_artifacts_in_self_and_project_descendants(name)
+ builds_in_self_and_project_descendants
.ordered_by_pipeline # find job in hierarchical order
.with_downloadable_artifacts
.find_by_name(name)
end
- def builds_in_self_and_descendants
- Ci::Build.latest.where(pipeline: self_and_descendants)
+ def builds_in_self_and_project_descendants
+ Ci::Build.latest.where(pipeline: self_and_project_descendants)
end
- def bridges_in_self_and_descendants
- Ci::Bridge.latest.where(pipeline: self_and_descendants)
+ def bridges_in_self_and_project_descendants
+ Ci::Bridge.latest.where(pipeline: self_and_project_descendants)
end
- def environments_in_self_and_descendants(deployment_status: nil)
+ def environments_in_self_and_project_descendants(deployment_status: nil)
# We limit to 100 unique environments for application safety.
# See: https://gitlab.com/gitlab-org/gitlab/-/issues/340781#note_699114700
expanded_environment_names =
- builds_in_self_and_descendants.joins(:metadata)
+ builds_in_self_and_project_descendants.joins(:metadata)
.where.not('ci_builds_metadata.expanded_environment_name' => nil)
.distinct('ci_builds_metadata.expanded_environment_name')
.limit(100)
@@ -977,17 +977,17 @@ module Ci
end
# With multi-project and parent-child pipelines
- def all_pipelines_in_hierarchy
+ def upstream_and_all_downstreams
object_hierarchy.all_objects
end
# With only parent-child pipelines
- def self_and_ancestors
+ def self_and_project_ancestors
object_hierarchy(project_condition: :same).base_and_ancestors
end
# With only parent-child pipelines
- def self_and_descendants
+ def self_and_project_descendants
object_hierarchy(project_condition: :same).base_and_descendants
end
@@ -996,8 +996,8 @@ module Ci
object_hierarchy(project_condition: :same).descendants
end
- def self_and_descendants_complete?
- self_and_descendants.all?(&:complete?)
+ def self_and_project_descendants_complete?
+ self_and_project_descendants.all?(&:complete?)
end
# Follow the parent-child relationships and return the top-level parent
@@ -1061,8 +1061,8 @@ module Ci
latest_report_builds(Ci::JobArtifact.of_report_type(:test)).preload(:project, :metadata)
end
- def latest_report_builds_in_self_and_descendants(reports_scope = ::Ci::JobArtifact.all_reports)
- builds_in_self_and_descendants.with_artifacts(reports_scope)
+ def latest_report_builds_in_self_and_project_descendants(reports_scope = ::Ci::JobArtifact.all_reports)
+ builds_in_self_and_project_descendants.with_artifacts(reports_scope)
end
def builds_with_coverage
diff --git a/app/models/ci/runner.rb b/app/models/ci/runner.rb
index 6c3754d84d0..3cbc4c50444 100644
--- a/app/models/ci/runner.rb
+++ b/app/models/ci/runner.rb
@@ -359,14 +359,6 @@ module Ci
runner_projects.limit(2).count(:all) > 1
end
- def assigned_to_group?
- runner_namespaces.any?
- end
-
- def assigned_to_project?
- runner_projects.any?
- end
-
def match_build_if_online?(build)
active? && online? && matches_build?(build)
end
diff --git a/app/models/concerns/integrations/has_web_hook.rb b/app/models/concerns/integrations/has_web_hook.rb
index e9fcb0d151d..e6ca6cc7938 100644
--- a/app/models/concerns/integrations/has_web_hook.rb
+++ b/app/models/concerns/integrations/has_web_hook.rb
@@ -5,6 +5,7 @@ module Integrations
extend ActiveSupport::Concern
included do
+ after_save :update_web_hook!, if: :activated?
has_one :service_hook, inverse_of: :integration, foreign_key: :service_id
end
diff --git a/app/models/concerns/sortable.rb b/app/models/concerns/sortable.rb
index 65fb62a814f..eccb004b503 100644
--- a/app/models/concerns/sortable.rb
+++ b/app/models/concerns/sortable.rb
@@ -43,6 +43,33 @@ module Sortable
}
end
+ def build_keyset_order_on_joined_column(scope:, attribute_name:, column:, direction:, nullable:)
+ reversed_direction = direction == :asc ? :desc : :asc
+
+ # rubocop: disable GitlabSecurity/PublicSend
+ order = ::Gitlab::Pagination::Keyset::Order.build(
+ [
+ ::Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: attribute_name,
+ column_expression: column,
+ order_expression: column.send(direction).send(nullable),
+ reversed_order_expression: column.send(reversed_direction).send(nullable),
+ order_direction: direction,
+ distinct: false,
+ add_to_projections: true,
+ nullable: nullable
+ ),
+ ::Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
+ attribute_name: 'id',
+ order_expression: arel_table['id'].desc
+ )
+ ]
+ )
+ # rubocop: enable GitlabSecurity/PublicSend
+
+ order.apply_cursor_conditions(scope).reorder(order)
+ end
+
private
def highest_label_priority(target_type_column: nil, target_type: nil, target_column:, project_column:, excluded_labels: [])
diff --git a/app/models/environment.rb b/app/models/environment.rb
index bc1b2daf3db..4aab4ab8170 100644
--- a/app/models/environment.rb
+++ b/app/models/environment.rb
@@ -84,7 +84,7 @@ class Environment < ApplicationRecord
# Search environments which have names like the given query.
# Do not set a large limit unless you've confirmed that it works on gitlab.com scale.
scope :for_name_like, -> (query, limit: 5) do
- where(arel_table[:name].matches("#{sanitize_sql_like query}%")).limit(limit)
+ where('LOWER(environments.name) LIKE LOWER(?) || \'%\'', sanitize_sql_like(query)).limit(limit)
end
scope :for_project, -> (project) { where(project_id: project) }
diff --git a/app/models/environment_status.rb b/app/models/environment_status.rb
index 43b2c7899a1..d06d0a99948 100644
--- a/app/models/environment_status.rb
+++ b/app/models/environment_status.rb
@@ -100,7 +100,7 @@ class EnvironmentStatus
def self.build_environments_status(mr, user, pipeline)
return [] unless pipeline
- pipeline.environments_in_self_and_descendants.includes(:project).available.map do |environment|
+ pipeline.environments_in_self_and_project_descendants.includes(:project).available.map do |environment|
next unless Ability.allowed?(user, :read_environment, environment)
EnvironmentStatus.new(pipeline.project, environment, mr, pipeline.sha)
diff --git a/app/models/integrations/buildkite.rb b/app/models/integrations/buildkite.rb
index c19e06f055e..7a48e71b934 100644
--- a/app/models/integrations/buildkite.rb
+++ b/app/models/integrations/buildkite.rb
@@ -8,8 +8,6 @@ module Integrations
include ReactivelyCached
extend Gitlab::Utils::Override
- after_save :ensure_ssl_verification
-
ENDPOINT = "https://buildkite.com"
field :project_url,
@@ -50,12 +48,6 @@ module Integrations
self.properties = properties.except('enable_ssl_verification') # Remove unused key
end
- def ensure_ssl_verification
- return unless service_hook
-
- update_web_hook!
- end
-
override :hook_url
def hook_url
"#{buildkite_endpoint('webhook')}/deliver/#{webhook_token}"
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 1de2075b456..153747c75df 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -254,32 +254,6 @@ class Issue < ApplicationRecord
alias_method :with_state, :with_state_id
alias_method :with_states, :with_state_ids
- def build_keyset_order_on_joined_column(scope:, attribute_name:, column:, direction:, nullable:)
- reversed_direction = direction == :asc ? :desc : :asc
-
- # rubocop: disable GitlabSecurity/PublicSend
- order = ::Gitlab::Pagination::Keyset::Order.build(
- [
- ::Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
- attribute_name: attribute_name,
- column_expression: column,
- order_expression: column.send(direction).send(nullable),
- reversed_order_expression: column.send(reversed_direction).send(nullable),
- order_direction: direction,
- distinct: false,
- add_to_projections: true,
- nullable: nullable
- ),
- ::Gitlab::Pagination::Keyset::ColumnOrderDefinition.new(
- attribute_name: 'id',
- order_expression: arel_table['id'].desc
- )
- ])
- # rubocop: enable GitlabSecurity/PublicSend
-
- order.apply_cursor_conditions(scope).order(order)
- end
-
override :order_upvotes_desc
def order_upvotes_desc
reorder(upvotes_count: :desc)
diff --git a/app/models/member.rb b/app/models/member.rb
index 186fcd8759f..c5351d5447b 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -184,14 +184,85 @@ class Member < ApplicationRecord
unscoped.from(distinct_members, :members)
end
- scope :order_name_asc, -> { left_join_users.reorder(User.arel_table[:name].asc.nulls_last) }
- scope :order_name_desc, -> { left_join_users.reorder(User.arel_table[:name].desc.nulls_last) }
- scope :order_recent_sign_in, -> { left_join_users.reorder(User.arel_table[:last_sign_in_at].desc.nulls_last) }
- scope :order_oldest_sign_in, -> { left_join_users.reorder(User.arel_table[:last_sign_in_at].asc.nulls_last) }
- scope :order_recent_last_activity, -> { left_join_users.reorder(User.arel_table[:last_activity_on].desc.nulls_last) }
- scope :order_oldest_last_activity, -> { left_join_users.reorder(User.arel_table[:last_activity_on].asc.nulls_first) }
- scope :order_recent_created_user, -> { left_join_users.reorder(User.arel_table[:created_at].desc.nulls_last) }
- scope :order_oldest_created_user, -> { left_join_users.reorder(User.arel_table[:created_at].asc.nulls_first) }
+ scope :order_name_asc, -> do
+ build_keyset_order_on_joined_column(
+ scope: left_join_users,
+ attribute_name: 'member_user_full_name',
+ column: User.arel_table[:name],
+ direction: :asc,
+ nullable: :nulls_last
+ )
+ end
+
+ scope :order_name_desc, -> do
+ build_keyset_order_on_joined_column(
+ scope: left_join_users,
+ attribute_name: 'member_user_full_name',
+ column: User.arel_table[:name],
+ direction: :desc,
+ nullable: :nulls_last
+ )
+ end
+
+ scope :order_oldest_sign_in, -> do
+ build_keyset_order_on_joined_column(
+ scope: left_join_users,
+ attribute_name: 'member_user_last_sign_in_at',
+ column: User.arel_table[:last_sign_in_at],
+ direction: :asc,
+ nullable: :nulls_last
+ )
+ end
+
+ scope :order_recent_sign_in, -> do
+ build_keyset_order_on_joined_column(
+ scope: left_join_users,
+ attribute_name: 'member_user_last_sign_in_at',
+ column: User.arel_table[:last_sign_in_at],
+ direction: :desc,
+ nullable: :nulls_last
+ )
+ end
+
+ scope :order_oldest_last_activity, -> do
+ build_keyset_order_on_joined_column(
+ scope: left_join_users,
+ attribute_name: 'member_user_last_activity_on',
+ column: User.arel_table[:last_activity_on],
+ direction: :asc,
+ nullable: :nulls_first
+ )
+ end
+
+ scope :order_recent_last_activity, -> do
+ build_keyset_order_on_joined_column(
+ scope: left_join_users,
+ attribute_name: 'member_user_last_activity_on',
+ column: User.arel_table[:last_activity_on],
+ direction: :desc,
+ nullable: :nulls_last
+ )
+ end
+
+ scope :order_oldest_created_user, -> do
+ build_keyset_order_on_joined_column(
+ scope: left_join_users,
+ attribute_name: 'member_user_created_at',
+ column: User.arel_table[:created_at],
+ direction: :asc,
+ nullable: :nulls_first
+ )
+ end
+
+ scope :order_recent_created_user, -> do
+ build_keyset_order_on_joined_column(
+ scope: left_join_users,
+ attribute_name: 'member_user_created_at',
+ column: User.arel_table[:created_at],
+ direction: :desc,
+ nullable: :nulls_last
+ )
+ end
scope :on_project_and_ancestors, ->(project) { where(source: [project] + project.ancestors) }
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 18459805883..d155a295481 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -1466,7 +1466,7 @@ class MergeRequest < ApplicationRecord
end
def environments_in_head_pipeline(deployment_status: nil)
- actual_head_pipeline&.environments_in_self_and_descendants(deployment_status: deployment_status) || Environment.none
+ actual_head_pipeline&.environments_in_self_and_project_descendants(deployment_status: deployment_status) || Environment.none
end
def fetch_ref!
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 4f0639a08a0..17d4c6d27e6 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -61,7 +61,7 @@ class Namespace < ApplicationRecord
has_many :runner_namespaces, inverse_of: :namespace, class_name: 'Ci::RunnerNamespace'
has_many :runners, through: :runner_namespaces, source: :runner, class_name: 'Ci::Runner'
has_many :pending_builds, class_name: 'Ci::PendingBuild'
- has_one :onboarding_progress
+ has_one :onboarding_progress, class_name: 'Onboarding::Progress'
# This should _not_ be `inverse_of: :namespace`, because that would also set
# `user.namespace` when this user creates a group with themselves as `owner`.
diff --git a/app/models/onboarding/progress.rb b/app/models/onboarding/progress.rb
new file mode 100644
index 00000000000..ecc78418256
--- /dev/null
+++ b/app/models/onboarding/progress.rb
@@ -0,0 +1,118 @@
+# frozen_string_literal: true
+
+module Onboarding
+ class Progress < ApplicationRecord
+ self.table_name = 'onboarding_progresses'
+
+ belongs_to :namespace, optional: false
+
+ validate :namespace_is_root_namespace
+
+ ACTIONS = [
+ :git_pull,
+ :git_write,
+ :merge_request_created,
+ :pipeline_created,
+ :user_added,
+ :trial_started,
+ :subscription_created,
+ :required_mr_approvals_enabled,
+ :code_owners_enabled,
+ :scoped_label_created,
+ :security_scan_enabled,
+ :issue_created,
+ :issue_auto_closed,
+ :repository_imported,
+ :repository_mirrored,
+ :secure_dependency_scanning_run,
+ :secure_container_scanning_run,
+ :secure_dast_run,
+ :secure_secret_detection_run,
+ :secure_coverage_fuzzing_run,
+ :secure_api_fuzzing_run,
+ :secure_cluster_image_scanning_run,
+ :license_scanning_run
+ ].freeze
+
+ scope :incomplete_actions, ->(actions) do
+ Array.wrap(actions).inject(self) { |scope, action| scope.where(column_name(action) => nil) }
+ end
+
+ scope :completed_actions, ->(actions) do
+ Array.wrap(actions).inject(self) { |scope, action| scope.where.not(column_name(action) => nil) }
+ end
+
+ scope :completed_actions_with_latest_in_range, ->(actions, range) do
+ actions = Array(actions)
+ if actions.size == 1
+ where(column_name(actions[0]) => range)
+ else
+ action_columns = actions.map { |action| arel_table[column_name(action)] }
+ completed_actions(actions).where(Arel::Nodes::NamedFunction.new('GREATEST', action_columns).between(range))
+ end
+ end
+
+ class << self
+ def onboard(namespace)
+ return unless root_namespace?(namespace)
+
+ create(namespace: namespace)
+ end
+
+ def onboarding?(namespace)
+ where(namespace: namespace).any?
+ end
+
+ def register(namespace, actions)
+ actions = Array(actions)
+ return unless root_namespace?(namespace) && actions.difference(ACTIONS).empty?
+
+ onboarding_progress = find_by(namespace: namespace)
+ return unless onboarding_progress
+
+ now = Time.current
+ nil_actions = actions.select { |action| onboarding_progress[column_name(action)].nil? }
+ return if nil_actions.empty?
+
+ updates = nil_actions.inject({}) { |sum, action| sum.merge!({ column_name(action) => now }) }
+ onboarding_progress.update!(updates)
+ end
+
+ def completed?(namespace, action)
+ return unless root_namespace?(namespace) && ACTIONS.include?(action)
+
+ action_column = column_name(action)
+ where(namespace: namespace).where.not(action_column => nil).exists?
+ end
+
+ def not_completed?(namespace_id, action)
+ return unless ACTIONS.include?(action)
+
+ action_column = column_name(action)
+ exists?(namespace_id: namespace_id, action_column => nil)
+ end
+
+ def column_name(action)
+ :"#{action}_at"
+ end
+
+ private
+
+ def root_namespace?(namespace)
+ namespace&.root?
+ end
+ end
+
+ def number_of_completed_actions
+ attributes.extract!(*ACTIONS.map { |action| self.class.column_name(action).to_s }).compact!.size
+ end
+
+ private
+
+ def namespace_is_root_namespace
+ return unless namespace
+
+ errors.add(:namespace, _('must be a root namespace')) if namespace.has_parent?
+ end
+ end
+end
diff --git a/app/models/onboarding_progress.rb b/app/models/onboarding_progress.rb
deleted file mode 100644
index e5851c5cfc5..00000000000
--- a/app/models/onboarding_progress.rb
+++ /dev/null
@@ -1,114 +0,0 @@
-# frozen_string_literal: true
-
-class OnboardingProgress < ApplicationRecord
- belongs_to :namespace, optional: false
-
- validate :namespace_is_root_namespace
-
- ACTIONS = [
- :git_pull,
- :git_write,
- :merge_request_created,
- :pipeline_created,
- :user_added,
- :trial_started,
- :subscription_created,
- :required_mr_approvals_enabled,
- :code_owners_enabled,
- :scoped_label_created,
- :security_scan_enabled,
- :issue_created,
- :issue_auto_closed,
- :repository_imported,
- :repository_mirrored,
- :secure_dependency_scanning_run,
- :secure_container_scanning_run,
- :secure_dast_run,
- :secure_secret_detection_run,
- :secure_coverage_fuzzing_run,
- :secure_api_fuzzing_run,
- :secure_cluster_image_scanning_run,
- :license_scanning_run
- ].freeze
-
- scope :incomplete_actions, -> (actions) do
- Array.wrap(actions).inject(self) { |scope, action| scope.where(column_name(action) => nil) }
- end
-
- scope :completed_actions, -> (actions) do
- Array.wrap(actions).inject(self) { |scope, action| scope.where.not(column_name(action) => nil) }
- end
-
- scope :completed_actions_with_latest_in_range, -> (actions, range) do
- actions = Array(actions)
- if actions.size == 1
- where(column_name(actions[0]) => range)
- else
- action_columns = actions.map { |action| arel_table[column_name(action)] }
- completed_actions(actions).where(Arel::Nodes::NamedFunction.new('GREATEST', action_columns).between(range))
- end
- end
-
- class << self
- def onboard(namespace)
- return unless root_namespace?(namespace)
-
- create(namespace: namespace)
- end
-
- def onboarding?(namespace)
- where(namespace: namespace).any?
- end
-
- def register(namespace, actions)
- actions = Array(actions)
- return unless root_namespace?(namespace) && actions.difference(ACTIONS).empty?
-
- onboarding_progress = find_by(namespace: namespace)
- return unless onboarding_progress
-
- now = Time.current
- nil_actions = actions.select { |action| onboarding_progress[column_name(action)].nil? }
- return if nil_actions.empty?
-
- updates = nil_actions.inject({}) { |sum, action| sum.merge!({ column_name(action) => now }) }
- onboarding_progress.update!(updates)
- end
-
- def completed?(namespace, action)
- return unless root_namespace?(namespace) && ACTIONS.include?(action)
-
- action_column = column_name(action)
- where(namespace: namespace).where.not(action_column => nil).exists?
- end
-
- def not_completed?(namespace_id, action)
- return unless ACTIONS.include?(action)
-
- action_column = column_name(action)
- where(namespace_id: namespace_id).where(action_column => nil).exists?
- end
-
- def column_name(action)
- :"#{action}_at"
- end
-
- private
-
- def root_namespace?(namespace)
- namespace && namespace.root?
- end
- end
-
- def number_of_completed_actions
- attributes.extract!(*ACTIONS.map { |action| self.class.column_name(action).to_s }).compact!.size
- end
-
- private
-
- def namespace_is_root_namespace
- return unless namespace
-
- errors.add(:namespace, _('must be a root namespace')) if namespace.has_parent?
- end
-end
diff --git a/app/models/project.rb b/app/models/project.rb
index 78ec17acc01..0be24252fa8 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -1170,7 +1170,7 @@ class Project < ApplicationRecord
latest_pipeline = ci_pipelines.latest_successful_for_ref(ref)
return unless latest_pipeline
- latest_pipeline.build_with_artifacts_in_self_and_descendants(job_name)
+ latest_pipeline.build_with_artifacts_in_self_and_project_descendants(job_name)
end
def latest_successful_build_for_sha(job_name, sha)
@@ -1179,7 +1179,7 @@ class Project < ApplicationRecord
latest_pipeline = ci_pipelines.latest_successful_for_sha(sha)
return unless latest_pipeline
- latest_pipeline.build_with_artifacts_in_self_and_descendants(job_name)
+ latest_pipeline.build_with_artifacts_in_self_and_project_descendants(job_name)
end
def latest_successful_build_for_ref!(job_name, ref = default_branch)