Añade el plugin Redmine Git Hosting 5.0.0

This commit is contained in:
Manuel Cillero 2021-03-20 13:29:16 +01:00
parent cfa0d58b18
commit a3bddad233
458 changed files with 30396 additions and 1 deletions

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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