debian-mirror-gitlab/app/models/service.rb

215 lines
5.4 KiB
Ruby
Raw Normal View History

2014-09-02 18:07:02 +05:30
# == Schema Information
#
# Table name: services
#
2015-04-26 12:48:37 +05:30
# 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-09-11 14:41:01 +05:30
# note_events :boolean default(TRUE), not null
# build_events :boolean default(FALSE), not null
2014-09-02 18:07:02 +05:30
#
# To add new service you should build a class inherited from Service
# and implement a set of methods
class Service < ActiveRecord::Base
2015-04-26 12:48:37 +05:30
include Sortable
serialize :properties, JSON
2014-09-02 18:07:02 +05:30
default_value_for :active, false
2015-04-26 12:48:37 +05:30
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
2015-12-23 02:04:40 +05:30
default_value_for :build_events, true
2015-04-26 12:48:37 +05:30
after_initialize :initialize_properties
2014-09-02 18:07:02 +05:30
2015-10-24 18:46:33 +05:30
after_commit :reset_updated_properties
2014-09-02 18:07:02 +05:30
belongs_to :project
has_one :service_hook
2015-04-26 12:48:37 +05:30
validates :project_id, presence: true, unless: Proc.new { |service| service.template? }
2015-12-23 02:04:40 +05:30
scope :visible, -> { where.not(type: ['GitlabIssueTrackerService', 'GitlabCiService']) }
2016-01-29 22:53:50 +05:30
scope :issue_trackers, -> { where(category: 'issue_tracker') }
scope :active, -> { where(active: true) }
scope :without_defaults, -> { where(default: false) }
2015-04-26 12:48:37 +05:30
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) }
2015-12-23 02:04:40 +05:30
scope :build_hooks, -> { where(build_events: true, active: true) }
2014-09-02 18:07:02 +05:30
2016-01-29 22:53:50 +05:30
default_value_for :category, 'common'
2014-09-02 18:07:02 +05:30
def activated?
active
end
2015-04-26 12:48:37 +05:30
def template?
template
end
2014-09-02 18:07:02 +05:30
def category
2016-01-29 22:53:50 +05:30
read_attribute(:category).to_sym
2014-09-02 18:07:02 +05:30
end
2015-04-26 12:48:37 +05:30
def initialize_properties
self.properties = {} if properties.nil?
end
2014-09-02 18:07:02 +05:30
def title
# implement inside child
end
def description
# implement inside child
end
def help
# implement inside child
end
def to_param
# implement inside child
end
def fields
# implement inside child
[]
end
2015-04-26 12:48:37 +05:30
def supported_events
%w(push tag_push issue merge_request)
end
2015-09-11 14:41:01 +05:30
def execute(data)
2014-09-02 18:07:02 +05:30
# implement inside child
end
2015-09-11 14:41:01 +05:30
def test(data)
# default implementation
result = execute(data)
{ success: result.present?, result: result }
end
2014-09-02 18:07:02 +05:30
def can_test?
!project.empty_repo?
end
2015-04-26 12:48:37 +05:30
# Provide convenient accessor methods
# for each serialized property.
2015-10-24 18:46:33 +05:30
# Also keep track of updated properties in a similar way as ActiveModel::Dirty
2015-04-26 12:48:37 +05:30
def self.prop_accessor(*args)
args.each do |arg|
class_eval %{
def #{arg}
properties['#{arg}']
end
def #{arg}=(value)
2015-10-24 18:46:33 +05:30
updated_properties['#{arg}'] = #{arg} unless #{arg}_changed?
2015-04-26 12:48:37 +05:30
self.properties['#{arg}'] = value
end
2015-10-24 18:46:33 +05:30
def #{arg}_changed?
#{arg}_touched? && #{arg} != #{arg}_was
end
def #{arg}_touched?
updated_properties.include?('#{arg}')
end
def #{arg}_was
updated_properties['#{arg}']
end
2015-04-26 12:48:37 +05:30
}
end
end
2015-12-23 02:04:40 +05:30
# Provide convenient boolean accessor methods
# for each serialized property.
# Also keep track of updated properties in a similar way as ActiveModel::Dirty
def self.boolean_accessor(*args)
self.prop_accessor(*args)
args.each do |arg|
class_eval %{
def #{arg}?
ActiveRecord::ConnectionAdapters::Column::TRUE_VALUES.include?(#{arg})
end
}
end
end
2015-10-24 18:46:33 +05:30
# Returns a hash of the properties that have been assigned a new value since last save,
# indicating their original values (attr => original value).
2016-01-29 22:53:50 +05:30
# ActiveRecord does not provide a mechanism to track changes in serialized keys,
2015-10-24 18:46:33 +05:30
# 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 reset_updated_properties
@updated_properties = nil
end
2016-01-29 22:53:50 +05:30
2015-04-26 12:48:37 +05:30
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
def self.available_services_names
%w(
asana
assembla
bamboo
buildkite
2015-12-23 02:04:40 +05:30
builds_email
2015-04-26 12:48:37 +05:30
campfire
custom_issue_tracker
2015-09-25 12:07:36 +05:30
drone_ci
2015-04-26 12:48:37 +05:30
emails_on_push
external_wiki
flowdock
gemnasium
hipchat
irker
jira
pivotaltracker
pushover
redmine
slack
teamcity
)
end
def self.create_from_template(project_id, template)
service = template.dup
service.template = false
service.project_id = project_id
service if service.save
end
2014-09-02 18:07:02 +05:30
end