gitlab-org--gitlab-foss/app/models/service.rb

191 lines
4.7 KiB
Ruby
Raw Normal View History

2012-11-19 13:14:05 -05:00
# == Schema Information
#
# Table name: services
#
2015-03-04 17:14:00 -05:00
# id :integer not null, primary key
# type :string(255)
# title :string(255)
# project_id :integer
# created_at :datetime
# updated_at :datetime
# active :boolean default(FALSE), not null
# properties :text
# template :boolean default(FALSE)
# push_events :boolean default(TRUE)
# issues_events :boolean default(TRUE)
# merge_requests_events :boolean default(TRUE)
# tag_push_events :boolean default(TRUE)
2015-05-03 12:05:38 -04:00
# note_events :boolean default(TRUE), not null
#
2012-11-19 13:14:05 -05:00
2013-05-22 09:58:44 -04:00
# To add new service you should build a class inherited from Service
# and implement a set of methods
2012-11-19 13:14:05 -05:00
class Service < ActiveRecord::Base
include Sortable
2014-09-07 20:54:18 -04:00
serialize :properties, JSON
default_value_for :active, false
default_value_for :push_events, true
default_value_for :issues_events, true
default_value_for :merge_requests_events, true
default_value_for :tag_push_events, true
default_value_for :note_events, true
2014-09-11 11:48:29 -04:00
after_initialize :initialize_properties
after_commit :reset_updated_properties
2012-11-19 13:14:05 -05:00
belongs_to :project
has_one :service_hook
2015-02-11 20:34:41 -05:00
validates :project_id, presence: true, unless: Proc.new { |service| service.template? }
2013-01-03 02:52:14 -05:00
scope :visible, -> { where.not(type: 'GitlabIssueTrackerService') }
scope :push_hooks, -> { where(push_events: true, active: true) }
scope :tag_push_hooks, -> { where(tag_push_events: true, active: true) }
scope :issue_hooks, -> { where(issues_events: true, active: true) }
scope :merge_request_hooks, -> { where(merge_requests_events: true, active: true) }
scope :note_hooks, -> { where(note_events: true, active: true) }
2013-01-03 02:52:14 -05:00
def activated?
active
end
2013-05-22 09:58:44 -04:00
2015-02-11 20:34:41 -05:00
def template?
template
end
def category
:common
end
2014-09-11 11:48:29 -04:00
def initialize_properties
self.properties = {} if properties.nil?
end
2013-05-22 09:58:44 -04:00
def title
# implement inside child
2013-05-22 09:58:44 -04:00
end
def description
# implement inside child
2013-05-22 09:58:44 -04:00
end
def help
# implement inside child
end
2013-05-22 09:58:44 -04:00
def to_param
# implement inside child
2013-05-22 09:58:44 -04:00
end
def fields
# implement inside child
2013-05-22 09:58:44 -04:00
[]
end
def supported_events
%w(push tag_push issue merge_request)
end
def execute(data)
# implement inside child
end
def test(data)
# default implementation
result = execute(data)
{ success: result.present?, result: result }
end
def can_test?
!project.empty_repo?
end
2014-09-07 20:54:18 -04:00
# Provide convenient accessor methods
# for each serialized property.
# Also keep track of updated properties.
2014-09-07 20:54:18 -04:00
def self.prop_accessor(*args)
args.each do |arg|
class_eval %{
def #{arg}
properties['#{arg}']
end
def #{arg}=(value)
updated_properties['#{arg}'] = #{arg} unless updated_properties.include?('#{arg}')
2014-09-07 20:54:18 -04:00
self.properties['#{arg}'] = value
end
}
end
end
# Returns a hash of the properties that have been assigned a new value since last save,
# indicating their original values (attr => original value).
# ActiveRecord does not provide a mechanism to track changes in serialized keys,
# so we need a specific implementation for service properties.
# This allows to track changes to properties set with the accessor methods,
# but not direct manipulation of properties hash.
def updated_properties
@updated_properties ||= ActiveSupport::HashWithIndifferentAccess.new
end
def prop_updated?(prop_name)
# Check if a new value was set.
# The new value may or may not be the same as the old value
updated_properties.include?(prop_name)
end
def prop_modified?(prop_name)
# Check if new value was set and it is different from the old value
prop_updated?(prop_name) && updated_properties[prop_name] != send(prop_name)
end
def reset_updated_properties
@updated_properties = nil
end
def async_execute(data)
return unless supported_events.include?(data[:object_kind])
Sidekiq::Client.enqueue(ProjectServiceWorker, id, data)
end
def issue_tracker?
self.category == :issue_tracker
end
2015-02-12 12:19:55 -05:00
def self.available_services_names
%w(
asana
assembla
bamboo
buildkite
campfire
custom_issue_tracker
2015-08-26 19:58:49 -04:00
drone_ci
emails_on_push
external_wiki
flowdock
gemnasium
gitlab_ci
hipchat
irker
jira
pivotaltracker
pushover
redmine
slack
teamcity
)
2015-02-12 12:19:55 -05:00
end
2015-02-11 20:34:41 -05:00
def self.create_from_template(project_id, template)
service = template.dup
service.template = false
service.project_id = project_id
service if service.save
end
2012-11-19 13:14:05 -05:00
end