rosa-build/app/models/hook.rb

145 lines
4.3 KiB
Ruby
Raw Normal View History

class Hook < ActiveRecord::Base
include Modules::Models::WebHooks
belongs_to :project
before_validation :cleanup_data
validates :project_id, :data, :presence => true
validates :name, :presence => true, :inclusion => {:in => NAMES}
attr_accessible :data, :name
serialize :data, Hash
scope :for_name, lambda {|name| where(:name => name) if name.present? }
2013-04-17 11:58:09 +01:00
def receive_issues(issue, action)
2013-04-15 21:10:54 +01:00
pull = issue.pull_request
return if action.to_sym == :create && pull
payload = meta(issue.project, issue.user)
base_params = {
:number => issue.serial_id,
:state => issue.status,
:title => issue.title,
:body => issue.body,
:user => {:login => issue.user.uname},
}
2013-04-15 21:10:54 +01:00
if pull
total_commits = pull.repo.commits_between(pull.to_commit, pull.from_commit).count
repo_owner = pull.to_project.owner.uname
post 'pull_request', {
:payload => payload.merge(
:action => (pull.ready? ? 'opened' : pull.status),
:pull_request => base_params.merge(
:commits => total_commits,
:head => {:label => "#{pull.from_project.owner.uname}:#{pull.from_ref}"},
:base => {:label => "#{repo_owner}:#{pull.to_ref}"},
2013-04-17 11:58:09 +01:00
:html_url => "#{issue.project.html_url}/pull_requests/#{pull.serial_id}"
2013-04-15 21:10:54 +01:00
)
).to_json
}
else
post 'issues', {
:payload => payload.merge(
:action => (issue.closed? ? 'closed' : 'opened'),
:issue => base_params.merge(
2013-04-17 11:58:09 +01:00
:html_url => "#{issue.project.html_url}/issues/#{issue.serial_id}"
2013-04-15 21:10:54 +01:00
)
).to_json
}
end
end
2013-04-17 11:58:09 +01:00
later :receive_issues, :queue => :clone_build
def receive_push(git_hook)
2013-04-25 16:27:48 +01:00
project = Project.find(git_hook['project']['project']['id'])
user = User.find(git_hook['user']['user']['id'])
payload = meta(project, user)
oldrev = git_hook['oldrev']
newrev = git_hook['newrev']
change_type = git_hook['change_type']
2013-04-17 11:58:09 +01:00
commits = []
2013-04-25 16:27:48 +01:00
payload.merge!(:before => oldrev, :after => newrev)
if %w(delete create).exclude? change_type
2013-04-17 11:58:09 +01:00
payload.merge!(
2013-04-25 16:27:48 +01:00
:compare => "#{project.html_url}/diff/#{oldrev[0..6]}...#{newrev[0..6]}"
2013-04-17 11:58:09 +01:00
)
2013-04-25 16:27:48 +01:00
if oldrev == newrev
2013-05-14 12:27:15 +01:00
commits = [project.repo.commit(newrev)]
modified = commits.first.stats.files.map{|f| f[0]}
2013-04-17 11:58:09 +01:00
else
2013-04-25 16:27:48 +01:00
commits = project.repo.commits_between(oldrev, newrev)
2013-04-17 11:58:09 +01:00
end
end
post 'push', {
:payload => payload.merge(
2013-04-25 16:27:48 +01:00
:ref => git_hook['refname'],
2013-04-17 11:58:09 +01:00
:commits => commits.map{ |c|
cf = changed_files c
2013-04-17 11:58:09 +01:00
{
:id => c.id,
:message => c.message,
:distinct => true,
:url => "#{project.html_url}/commit/#{c.id}",
:removed => cf[:removed],
:added => cf[:added],
:modified => cf[:modified],
2013-05-14 12:27:15 +01:00
:timestamp => c.committed_date,
2013-04-17 11:58:09 +01:00
:author => {:name => c.committer.name, :email => c.committer.email}
}
}
).to_json
}
end
later :receive_push, :queue => :clone_build
protected
2013-04-15 21:10:54 +01:00
def post(action, params)
2013-04-17 12:55:22 +01:00
github_services = APP_CONFIG['github_services']
uri = URI "http://#{github_services['ip']}:#{github_services['port']}/#{name}/#{action}"
2013-04-15 21:10:54 +01:00
Net::HTTP.post_form uri, params.merge(:data => data.to_json)
rescue # Dont care about it
end
def meta(project, user)
{
:repository => {
:name => project.name,
:url => project.html_url,
:owner => { :login => project.owner.uname }
},
2013-04-17 11:58:09 +01:00
:sender => {:login => user.uname},
:pusher => {:name => user.uname}
}
end
def cleanup_data
if self.name.present? && fields = SCHEMA[self.name.to_sym]
new_data = {}
fields.each{ |type, field| new_data[field] = self.data[field] }
self.data = new_data
end
end
def changed_files(commit)
removed, added, modified = [], [], []
commit.show.each do |diff|
if diff.renamed_file
added << diff.b_path
removed << diff.a_path
elsif diff.new_file
added << diff.b_path
elsif diff.deleted_file
removed << diff.a_path
else
modified << diff.a_path
end
end
{:removed => removed, :added => added, :modified => modified}
end
end