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/push_event.rb')
-rw-r--r--app/models/push_event.rb114
1 files changed, 114 insertions, 0 deletions
diff --git a/app/models/push_event.rb b/app/models/push_event.rb
new file mode 100644
index 00000000000..90c085c888e
--- /dev/null
+++ b/app/models/push_event.rb
@@ -0,0 +1,114 @@
+class PushEvent < Event
+ # This validation exists so we can't accidentally use PushEvent with a
+ # different "action" value.
+ validate :validate_push_action
+
+ # The project is required to build links to commits, commit ranges, etc.
+ #
+ # We're just validating the presence of the ID here as foreign key constraints
+ # should ensure the ID points to a valid project.
+ validates :project_id, presence: true
+
+ # These fields are also not used for push events, thus storing them would be a
+ # waste.
+ validates :target_id, absence: true
+ validates :target_type, absence: true
+
+ delegate :branch?, to: :push_event_payload
+ delegate :tag?, to: :push_event_payload
+ delegate :commit_from, to: :push_event_payload
+ delegate :commit_to, to: :push_event_payload
+ delegate :ref_type, to: :push_event_payload
+ delegate :commit_title, to: :push_event_payload
+
+ delegate :commit_count, to: :push_event_payload
+ alias_method :commits_count, :commit_count
+
+ # Returns events of pushes that either pushed to an existing ref or created a
+ # new one.
+ def self.created_or_pushed
+ actions = [
+ PushEventPayload.actions[:pushed],
+ PushEventPayload.actions[:created]
+ ]
+
+ joins(:push_event_payload)
+ .where(push_event_payloads: { action: actions })
+ end
+
+ # Returns events of pushes to a branch.
+ def self.branch_events
+ ref_type = PushEventPayload.ref_types[:branch]
+
+ joins(:push_event_payload)
+ .where(push_event_payloads: { ref_type: ref_type })
+ end
+
+ # Returns PushEvent instances for which no merge requests have been created.
+ def self.without_existing_merge_requests
+ existing_mrs = MergeRequest.except(:order, :where)
+ .select(1)
+ .where('merge_requests.source_project_id = events.project_id')
+ .where('merge_requests.source_branch = push_event_payloads.ref')
+ .where(state: :opened)
+
+ # For reasons unknown the use of #eager_load will result in the
+ # "push_event_payload" association not being set. Because of this we're
+ # using "joins" here, which does mean an additional query needs to be
+ # executed in order to retrieve the "push_event_association" when the
+ # returned PushEvent is used.
+ joins(:push_event_payload)
+ .where('NOT EXISTS (?)', existing_mrs)
+ .created_or_pushed
+ .branch_events
+ end
+
+ def self.sti_name
+ PUSHED
+ end
+
+ def push?
+ true
+ end
+
+ def push_with_commits?
+ !!(commit_from && commit_to)
+ end
+
+ def valid_push?
+ push_event_payload.ref.present?
+ end
+
+ def new_ref?
+ push_event_payload.created?
+ end
+
+ def rm_ref?
+ push_event_payload.removed?
+ end
+
+ def md_ref?
+ !(rm_ref? || new_ref?)
+ end
+
+ def ref_name
+ push_event_payload.ref
+ end
+
+ alias_method :branch_name, :ref_name
+ alias_method :tag_name, :ref_name
+
+ def commit_id
+ commit_to || commit_from
+ end
+
+ def last_push_to_non_root?
+ branch? && project.default_branch != branch_name
+ end
+
+ def validate_push_action
+ return if action == PUSHED
+
+ errors.add(:action, "the action #{action.inspect} is not valid")
+ end
+end