Añade el plugin Redmine Git Hosting 5.0.0
This commit is contained in:
parent
cfa0d58b18
commit
a3bddad233
458 changed files with 30396 additions and 1 deletions
|
@ -0,0 +1,54 @@
|
|||
module RedmineHooks
|
||||
class Base
|
||||
attr_reader :object, :payloads
|
||||
|
||||
def initialize(object, payloads = {})
|
||||
@object = object
|
||||
@payloads = payloads
|
||||
end
|
||||
|
||||
class << self
|
||||
def call(object, payloads = {})
|
||||
new(object, payloads).call
|
||||
end
|
||||
end
|
||||
|
||||
def call
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
def start_message
|
||||
raise NotImplementedError
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def logger
|
||||
RedmineGitHosting.logger
|
||||
end
|
||||
|
||||
def success_message
|
||||
" [success]\n"
|
||||
end
|
||||
|
||||
def failure_message
|
||||
" [failure]\n"
|
||||
end
|
||||
|
||||
def log_hook_succeeded
|
||||
logger.info 'Succeeded!'
|
||||
end
|
||||
|
||||
def log_hook_failed
|
||||
logger.error 'Failed!'
|
||||
end
|
||||
|
||||
def execute_hook(&block)
|
||||
y = ''
|
||||
logger.info start_message
|
||||
y << " - #{start_message} ... "
|
||||
yield y
|
||||
y
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,111 @@
|
|||
module RedmineHooks
|
||||
class CallWebservices < Base
|
||||
include HttpHelper
|
||||
|
||||
attr_reader :payloads_to_send
|
||||
|
||||
def initialize(*args)
|
||||
super
|
||||
|
||||
@payloads_to_send = []
|
||||
set_payloads_to_send
|
||||
end
|
||||
|
||||
def call
|
||||
execute_hook do |out|
|
||||
if needs_push?
|
||||
out << call_webservice
|
||||
else
|
||||
out << "#{skip_message}\n"
|
||||
logger.info skip_message
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def post_receive_url
|
||||
object
|
||||
end
|
||||
|
||||
def needs_push?
|
||||
return true if post_receive_url.mode == :post
|
||||
return false if payloads.empty?
|
||||
return true unless use_triggers?
|
||||
return false if post_receive_url.triggers.empty?
|
||||
|
||||
!payloads_to_send.empty?
|
||||
end
|
||||
|
||||
def start_message
|
||||
uri = URI post_receive_url.url
|
||||
if uri.password.present?
|
||||
uri.user = nil
|
||||
uri.password = nil
|
||||
"Notifying #{uri} (with base auth)"
|
||||
else
|
||||
"Notifying #{post_receive_url.url}"
|
||||
end
|
||||
end
|
||||
|
||||
def skip_message
|
||||
"This url doesn't need to be notified"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def set_payloads_to_send
|
||||
@payloads_to_send = if post_receive_url.mode == :post
|
||||
{}
|
||||
elsif use_triggers?
|
||||
extract_payloads
|
||||
else
|
||||
payloads
|
||||
end
|
||||
end
|
||||
|
||||
def extract_payloads
|
||||
new_payloads = []
|
||||
payloads.each do |payload|
|
||||
data = RedmineGitHosting::Utils::Git.parse_refspec(payload[:ref])
|
||||
new_payloads << payload if data[:type] == 'heads' && post_receive_url.triggers.include?(data[:name])
|
||||
end
|
||||
new_payloads
|
||||
end
|
||||
|
||||
def use_method
|
||||
post_receive_url.mode == :get ? :http_get : :http_post
|
||||
end
|
||||
|
||||
def use_triggers?
|
||||
post_receive_url.use_triggers?
|
||||
end
|
||||
|
||||
def split_payloads?
|
||||
post_receive_url.split_payloads?
|
||||
end
|
||||
|
||||
def call_webservice
|
||||
if use_method == :http_post && split_payloads?
|
||||
y = ''
|
||||
payloads_to_send.each do |payload|
|
||||
y << do_call_webservice(payload)
|
||||
end
|
||||
y
|
||||
else
|
||||
do_call_webservice payloads_to_send
|
||||
end
|
||||
end
|
||||
|
||||
def do_call_webservice(payload)
|
||||
post_failed, post_message = send(use_method, post_receive_url.url, { data: { payload: payload } })
|
||||
|
||||
if post_failed
|
||||
logger.error 'Failed!'
|
||||
logger.error post_message
|
||||
(split_payloads? ? failure_message.delete("\n") : failure_message)
|
||||
else
|
||||
log_hook_succeeded
|
||||
(split_payloads? ? success_message.delete("\n") : success_message)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,30 @@
|
|||
module RedmineHooks
|
||||
class FetchChangesets < Base
|
||||
def call
|
||||
repository.empty_cache!
|
||||
execute_hook do |out|
|
||||
out << fetch_changesets
|
||||
end
|
||||
end
|
||||
|
||||
def repository
|
||||
object
|
||||
end
|
||||
|
||||
def start_message
|
||||
"Fetching changesets for '#{repository.redmine_name}' repository"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def fetch_changesets
|
||||
repository.fetch_changesets
|
||||
log_hook_succeeded
|
||||
success_message
|
||||
rescue ::Redmine::Scm::Adapters::CommandFailed => e
|
||||
log_hook_failed
|
||||
logger.error "Error during fetching changesets : #{e.message}"
|
||||
failure_message
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,138 @@
|
|||
require 'json'
|
||||
|
||||
module RedmineHooks
|
||||
class GithubIssuesSync < Base
|
||||
include HttpHelper
|
||||
|
||||
def call
|
||||
sync_with_github
|
||||
end
|
||||
|
||||
def project
|
||||
object
|
||||
end
|
||||
|
||||
def params
|
||||
payloads
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def github_issue
|
||||
GithubIssue.find_by_github_id params[:issue][:id]
|
||||
end
|
||||
|
||||
def redmine_issue
|
||||
Issue.find_by_subject params[:issue][:title]
|
||||
end
|
||||
|
||||
def sync_with_github
|
||||
create_relation = false
|
||||
|
||||
## We don't have stored relation
|
||||
if github_issue.nil?
|
||||
create_relation = true
|
||||
|
||||
## And we don't have issue in Redmine
|
||||
redmine_issue = if redmine_issue.nil?
|
||||
create_redmine_issue
|
||||
else
|
||||
## Create relation and update issue
|
||||
update_redmine_issue(redmine_issue)
|
||||
end
|
||||
else
|
||||
## We have one relation, update issue
|
||||
redmine_issue = update_redmine_issue(github_issue.issue)
|
||||
end
|
||||
|
||||
if create_relation
|
||||
github_issue = GithubIssue.new
|
||||
github_issue.github_id = params[:issue][:id]
|
||||
github_issue.issue_id = redmine_issue.id
|
||||
github_issue.save!
|
||||
end
|
||||
|
||||
if params.key?(:comment)
|
||||
issue_journal = GithubComment.find_by_github_id(params[:comment][:id])
|
||||
|
||||
if issue_journal.nil?
|
||||
issue_journal = create_issue_journal(github_issue.issue)
|
||||
|
||||
github_comment = GithubComment.new
|
||||
github_comment.github_id = params[:comment][:id]
|
||||
github_comment.journal_id = issue_journal.id
|
||||
github_comment.save!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def create_redmine_issue
|
||||
logger.info('Github Issues Sync : create new issue')
|
||||
|
||||
issue = project.issues.new
|
||||
issue.tracker_id = project.trackers.first.try(:id)
|
||||
issue.subject = params[:issue][:title].chomp[0, 255]
|
||||
issue.description = params[:issue][:body]
|
||||
issue.updated_on = params[:issue][:updated_at]
|
||||
issue.created_on = params[:issue][:created_at]
|
||||
|
||||
## Get user mail
|
||||
user = find_user(params[:issue][:user][:url])
|
||||
issue.author = user
|
||||
|
||||
issue.save!
|
||||
issue
|
||||
end
|
||||
|
||||
def create_issue_journal(issue)
|
||||
logger.info("Github Issues Sync : create new journal for issue '##{issue.id}'")
|
||||
|
||||
journal = Journal.new
|
||||
journal.journalized_id = issue.id
|
||||
journal.journalized_type = 'Issue'
|
||||
journal.notes = params[:comment][:body]
|
||||
journal.created_on = params[:comment][:created_at]
|
||||
|
||||
## Get user mail
|
||||
user = find_user(params[:comment][:user][:url])
|
||||
journal.user_id = user.id
|
||||
|
||||
journal.save!
|
||||
journal
|
||||
end
|
||||
|
||||
def update_redmine_issue(issue)
|
||||
logger.info("Github Issues Sync : update issue '##{issue.id}'")
|
||||
|
||||
issue.status_id = if params[:issue][:state] == 'closed'
|
||||
5
|
||||
else
|
||||
1
|
||||
end
|
||||
|
||||
issue.subject = params[:issue][:title].chomp[0, 255]
|
||||
issue.description = params[:issue][:body]
|
||||
issue.updated_on = params[:issue][:updated_at]
|
||||
|
||||
issue.save!
|
||||
issue
|
||||
end
|
||||
|
||||
def find_user(url)
|
||||
post_failed, user_data = http_get(url)
|
||||
user_data = JSON.parse(user_data)
|
||||
|
||||
user = User.find_by_mail(user_data['email'])
|
||||
|
||||
if user.nil?
|
||||
logger.info("Github Issues Sync : cannot find user '#{user_data['email']}' in Redmine, use anonymous")
|
||||
user = User.anonymous
|
||||
user.mail = user_data['email']
|
||||
user.firstname = user_data['name']
|
||||
user.lastname = user_data['login']
|
||||
end
|
||||
|
||||
user
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
module RedmineHooks
|
||||
module HttpHelper
|
||||
def http_post(url, opts = {})
|
||||
RedmineGitHosting::Utils::Http.http_post url, opts
|
||||
end
|
||||
|
||||
def http_get(url, opts = {})
|
||||
RedmineGitHosting::Utils::Http.http_get url, opts
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,63 @@
|
|||
module RedmineHooks
|
||||
class UpdateMirrors < Base
|
||||
def call
|
||||
execute_hook do |out|
|
||||
if needs_push?
|
||||
out << call_mirror
|
||||
else
|
||||
out << "#{skip_message}\n"
|
||||
logger.info(skip_message)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def mirror
|
||||
object
|
||||
end
|
||||
|
||||
# If we have an explicit refspec, check it against incoming payloads
|
||||
# Special case: if we do not pass in any payloads, return true
|
||||
def needs_push?
|
||||
return true if payloads.empty?
|
||||
return true if mirror.mirror_mode?
|
||||
|
||||
check_ref_spec
|
||||
end
|
||||
|
||||
def start_message
|
||||
"Pushing changes to #{mirror.url}"
|
||||
end
|
||||
|
||||
def skip_message
|
||||
"This mirror doesn't need to be updated"
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def check_ref_spec
|
||||
refspec_parse = RedmineGitHosting::Validators.valid_git_refspec?(mirror.explicit_refspec)
|
||||
payloads.each do |payload|
|
||||
next unless splitpath = RedmineGitHosting::Utils::Git.parse_refspec(payload[:ref])
|
||||
|
||||
return true if payload[:ref] == refspec_parse[1] # Explicit Reference Spec complete path
|
||||
return true if splitpath[:name] == refspec_parse[1] # Explicit Reference Spec no type
|
||||
return true if mirror.include_all_branches? && splitpath[:type] == 'heads'
|
||||
return true if mirror.include_all_tags? && splitpath[:type] == 'tags'
|
||||
end
|
||||
false
|
||||
end
|
||||
|
||||
def call_mirror
|
||||
push_failed, push_message = RepositoryMirrors::Push.call(mirror)
|
||||
|
||||
if push_failed
|
||||
log_hook_failed
|
||||
logger.error(push_message)
|
||||
failure_message
|
||||
else
|
||||
log_hook_succeeded
|
||||
success_message
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue