diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-09-30 12:09:43 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-09-30 12:09:43 +0300 |
commit | 14846d722eb52ea70bc3092eb5da80ce1c2e9750 (patch) | |
tree | 34700bc9c8c7cddbf955bc079a174ca75e099903 /app | |
parent | bfb305ef516d8d6c07e91024a16772070d09afe0 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app')
-rw-r--r-- | app/graphql/graphql_triggers.rb | 8 | ||||
-rw-r--r-- | app/models/concerns/timebox.rb | 92 | ||||
-rw-r--r-- | app/models/iteration.rb | 6 | ||||
-rw-r--r-- | app/models/milestone.rb | 91 | ||||
-rw-r--r-- | app/models/project.rb | 1 | ||||
-rw-r--r-- | app/models/user_detail.rb | 3 | ||||
-rw-r--r-- | app/services/merge_requests/base_service.rb | 1 |
7 files changed, 106 insertions, 96 deletions
diff --git a/app/graphql/graphql_triggers.rb b/app/graphql/graphql_triggers.rb index 2d25a675a46..02b05a24578 100644 --- a/app/graphql/graphql_triggers.rb +++ b/app/graphql/graphql_triggers.rb @@ -24,6 +24,14 @@ module GraphqlTriggers def self.issuable_dates_updated(issuable) GitlabSchema.subscriptions.trigger('issuableDatesUpdated', { issuable_id: issuable.to_gid }, issuable) end + + def self.merge_request_reviewers_updated(merge_request) + GitlabSchema.subscriptions.trigger( + 'mergeRequestReviewersUpdated', + { issuable_id: merge_request.to_gid }, + merge_request + ) + end end GraphqlTriggers.prepend_mod diff --git a/app/models/concerns/timebox.rb b/app/models/concerns/timebox.rb index d53594eb5af..5b74e88429c 100644 --- a/app/models/concerns/timebox.rb +++ b/app/models/concerns/timebox.rb @@ -3,13 +3,10 @@ module Timebox extend ActiveSupport::Concern - include AtomicInternalId include CacheMarkdownField include Gitlab::SQL::Pattern - include IidRoutes include Referable include StripAttribute - include FromUnion TimeboxStruct = Struct.new(:title, :name, :id, :class_name) do # Ensure these models match the interface required for exporting @@ -42,39 +39,19 @@ module Timebox alias_method :timebox_id, :id - validates :group, presence: true, unless: :project - validates :project, presence: true, unless: :group - - validate :timebox_type_check validate :start_date_should_be_less_than_due_date, if: proc { |m| m.start_date.present? && m.due_date.present? } validate :dates_within_4_digits cache_markdown_field :title, pipeline: :single_line cache_markdown_field :description, issuable_reference_expansion_enabled: true - belongs_to :project - belongs_to :group - has_many :issues has_many :labels, -> { distinct.reorder('labels.title') }, through: :issues has_many :merge_requests - scope :of_projects, ->(ids) { where(project_id: ids) } - scope :of_groups, ->(ids) { where(group_id: ids) } scope :closed, -> { with_state(:closed) } - scope :for_projects, -> { where(group: nil).includes(:project) } scope :with_title, -> (title) { where(title: title) } - scope :for_projects_and_groups, -> (projects, groups) do - projects = projects.compact if projects.is_a? Array - projects = [] if projects.nil? - - groups = groups.compact if groups.is_a? Array - groups = [] if groups.nil? - - from_union([where(project_id: projects), where(group_id: groups)], remove_duplicates: false) - end - # A timebox is within the timeframe (start_date, end_date) if it overlaps # with that timeframe: # @@ -132,10 +109,6 @@ module Timebox end end - def count_by_state - reorder(nil).group(:state).count - end - def predefined_id?(id) [Any.id, None.id, Upcoming.id, Started.id].include?(id) end @@ -145,29 +118,8 @@ module Timebox end end - ## - # Returns the String necessary to reference a Timebox in Markdown. Group - # timeboxes only support name references, and do not support cross-project - # references. - # - # format - Symbol format to use (default: :iid, optional: :name) - # - # Examples: - # - # Milestone.first.to_reference # => "%1" - # Iteration.first.to_reference(format: :name) # => "*iteration:\"goal\"" - # Milestone.first.to_reference(cross_namespace_project) # => "gitlab-org/gitlab-foss%1" - # Iteration.first.to_reference(same_namespace_project) # => "gitlab-foss*iteration:1" - # - def to_reference(from = nil, format: :name, full: false) - format_reference = timebox_format_reference(format) - reference = "#{self.class.reference_prefix}#{format_reference}" - - if project - "#{project.to_reference_base(from, full: full)}#{reference}" - else - reference - end + def to_reference + raise NotImplementedError end def reference_link_text(from = nil) @@ -182,20 +134,12 @@ module Timebox model_name.singular end - def group_timebox? - group_id.present? - end - - def project_timebox? - project_id.present? - end - def safe_title title.to_slug.normalize.to_s end def resource_parent - group || project + raise NotImplementedError end def to_ability_name @@ -203,13 +147,7 @@ module Timebox end def merge_requests_enabled? - if group_timebox? - # Assume that groups have at least one project with merge requests enabled. - # Otherwise, we would need to load all of the projects from the database. - true - elsif project_timebox? - project&.merge_requests_enabled? - end + raise NotImplementedError end def weight_available? @@ -218,28 +156,6 @@ module Timebox private - def timebox_format_reference(format = :iid) - raise ArgumentError, _('Unknown format') unless [:iid, :name].include?(format) - - if group_timebox? && format == :iid - raise ArgumentError, _('Cannot refer to a group %{timebox_type} by an internal id!') % { timebox_type: timebox_name } - end - - if format == :name && !name.include?('"') - %("#{name}") - else - iid - end - end - - # Timebox should be either a project timebox or a group timebox - def timebox_type_check - if group_id && project_id - field = project_id_changed? ? :project_id : :group_id - errors.add(field, _("%{timebox_name} should belong either to a project or a group.") % { timebox_name: timebox_name }) - end - end - def start_date_should_be_less_than_due_date if due_date <= start_date errors.add(:due_date, _("must be greater than start date")) diff --git a/app/models/iteration.rb b/app/models/iteration.rb index 71ecbcf1c1a..ed73793c78f 100644 --- a/app/models/iteration.rb +++ b/app/models/iteration.rb @@ -2,6 +2,12 @@ # Placeholder class for model that is implemented in EE class Iteration < ApplicationRecord + include IgnorableColumns + + # TODO https://gitlab.com/gitlab-org/gitlab/-/issues/372125 + # TODO https://gitlab.com/gitlab-org/gitlab/-/issues/372126 + ignore_column :project_id, remove_with: '15.6', remove_after: '2022-09-17' + self.table_name = 'sprints' def self.reference_prefix diff --git a/app/models/milestone.rb b/app/models/milestone.rb index ff4fadb0f13..da07d8dd9fc 100644 --- a/app/models/milestone.rb +++ b/app/models/milestone.rb @@ -1,11 +1,13 @@ # frozen_string_literal: true class Milestone < ApplicationRecord + include AtomicInternalId include Sortable include Timebox include Milestoneish include FromUnion include Importable + include IidRoutes prepend_mod_with('Milestone') # rubocop: disable Cop/InjectEnterpriseEditionModule @@ -13,6 +15,9 @@ class Milestone < ApplicationRecord ALL = [::Timebox::None, ::Timebox::Any, ::Timebox::Started, ::Timebox::Upcoming].freeze end + belongs_to :project + belongs_to :group + has_many :milestone_releases has_many :releases, through: :milestone_releases @@ -30,13 +35,28 @@ class Milestone < ApplicationRecord .order(:project_id, :group_id, :due_date) end + scope :of_projects, ->(ids) { where(project_id: ids) } + scope :for_projects, -> { where(group: nil).includes(:project) } + scope :for_projects_and_groups, -> (projects, groups) do + projects = projects.compact if projects.is_a? Array + projects = [] if projects.nil? + + groups = groups.compact if groups.is_a? Array + groups = [] if groups.nil? + + from_union([where(project_id: projects), where(group_id: groups)], remove_duplicates: false) + end + scope :order_by_name_asc, -> { order(Arel::Nodes::Ascending.new(arel_table[:title].lower)) } scope :reorder_by_due_date_asc, -> { reorder(arel_table[:due_date].asc.nulls_last) } scope :with_api_entity_associations, -> { preload(project: [:project_feature, :route, namespace: :route]) } scope :order_by_dates_and_title, -> { order(due_date: :asc, start_date: :asc, title: :asc) } + validates :group, presence: true, unless: :project + validates :project, presence: true, unless: :group validates :title, presence: true validates_associated :milestone_releases, message: -> (_, obj) { obj[:value].map(&:errors).map(&:full_messages).join(",") } + validate :parent_type_check validate :uniqueness_of_title, if: :title_changed? state_machine :state, initial: :active do @@ -176,10 +196,18 @@ class Milestone < ApplicationRecord # TODO: remove after all code paths use `timebox_id` # https://gitlab.com/gitlab-org/gitlab/-/issues/215688 alias_method :milestoneish_id, :timebox_id - # TODO: remove after all code paths use (group|project)_timebox? - # https://gitlab.com/gitlab-org/gitlab/-/issues/215690 - alias_method :group_milestone?, :group_timebox? - alias_method :project_milestone?, :project_timebox? + + def group_milestone? + group_id.present? + end + + def project_milestone? + project_id.present? + end + + def resource_parent + group || project + end def parent if group_milestone? @@ -193,8 +221,63 @@ class Milestone < ApplicationRecord group_milestone? && parent.subgroup? end + def merge_requests_enabled? + if group_milestone? + # Assume that groups have at least one project with merge requests enabled. + # Otherwise, we would need to load all of the projects from the database. + true + elsif project_milestone? + project&.merge_requests_enabled? + end + end + + ## + # Returns the String necessary to reference a milestone in Markdown. Group + # milestones only support name references, and do not support cross-project + # references. + # + # format - Symbol format to use (default: :iid, optional: :name) + # + # Examples: + # + # Milestone.first.to_reference # => "%1" + # Milestone.first.to_reference(cross_namespace_project) # => "gitlab-org/gitlab-foss%1" + # + def to_reference(from = nil, format: :name, full: false) + format_reference = timebox_format_reference(format) + reference = "#{self.class.reference_prefix}#{format_reference}" + + if project + "#{project.to_reference_base(from, full: full)}#{reference}" + else + reference + end + end + private + def timebox_format_reference(format = :iid) + raise ArgumentError, _('Unknown format') unless [:iid, :name].include?(format) + + if group_milestone? && format == :iid + raise ArgumentError, _('Cannot refer to a group milestone by an internal id!') + end + + if format == :name && !name.include?('"') + %("#{name}") + else + iid + end + end + + # Milestone should be either a project milestone or a group milestone + def parent_type_check + return unless group_id && project_id + + field = project_id_changed? ? :project_id : :group_id + errors.add(field, _("milestone should belong either to a project or a group.") % { timebox_name: timebox_name }) + end + def issues_finder_params { project_id: project_id, group_id: group_id, include_subgroups: group_id.present? }.compact end diff --git a/app/models/project.rb b/app/models/project.rb index fcf7f71aa75..88cecc4770d 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -263,7 +263,6 @@ class Project < ApplicationRecord has_many :integrations has_many :events has_many :milestones - has_many :iterations # Projects with a very large number of notes may time out destroying them # through the foreign key. Additionally, the deprecated attachment uploader diff --git a/app/models/user_detail.rb b/app/models/user_detail.rb index b9b69d12729..3787ad1c380 100644 --- a/app/models/user_detail.rb +++ b/app/models/user_detail.rb @@ -2,9 +2,6 @@ class UserDetail < ApplicationRecord extend ::Gitlab::Utils::Override - include IgnorableColumns - - ignore_columns :other_role, remove_after: '2022-07-22', remove_with: '15.3' REGISTRATION_OBJECTIVE_PAIRS = { basics: 0, move_repository: 1, code_storage: 2, exploring: 3, ci: 4, other: 5, joining_team: 6 }.freeze diff --git a/app/services/merge_requests/base_service.rb b/app/services/merge_requests/base_service.rb index 6cefd9169f5..a848053ecaf 100644 --- a/app/services/merge_requests/base_service.rb +++ b/app/services/merge_requests/base_service.rb @@ -58,6 +58,7 @@ module MergeRequests new_reviewers = merge_request.reviewers - old_reviewers merge_request_activity_counter.track_users_review_requested(users: new_reviewers) merge_request_activity_counter.track_reviewers_changed_action(user: current_user) + GraphqlTriggers.merge_request_reviewers_updated(merge_request) end def cleanup_environments(merge_request) |