Añade plugin Redmine Git Hosting 4.0.2
This commit is contained in:
parent
472cb1ea76
commit
bdd66d941f
494 changed files with 36768 additions and 0 deletions
|
@ -0,0 +1,103 @@
|
|||
require 'digest/sha1'
|
||||
|
||||
module GitHosting
|
||||
class Config
|
||||
IGNORE_PARAMS = %w[redmineurl projectid debugmode asyncmode repositorykey].freeze
|
||||
REDMINE_PARAMS = %w[redminegitolite.redmineurl
|
||||
redminegitolite.projectid
|
||||
redminegitolite.repositoryid
|
||||
redminegitolite.repositorykey
|
||||
redminegitolite.debugmode
|
||||
redminegitolite.asyncmode].freeze
|
||||
|
||||
attr_reader :config
|
||||
|
||||
def initialize
|
||||
@config = {}
|
||||
load_gitolite_vars
|
||||
end
|
||||
|
||||
def valid?
|
||||
config_errors.nil?
|
||||
end
|
||||
|
||||
def project_url
|
||||
"#{redmine_url}/#{project_name}"
|
||||
end
|
||||
|
||||
def redmine_url
|
||||
config['redmineurl']
|
||||
end
|
||||
|
||||
def project_name
|
||||
config['projectid']
|
||||
end
|
||||
|
||||
def repository_name
|
||||
if config.key?('repositoryid') && !config['repositoryid'].empty?
|
||||
"#{project_name}/#{config['repositoryid']}"
|
||||
else
|
||||
project_name
|
||||
end
|
||||
end
|
||||
|
||||
def repository_key
|
||||
config['repositorykey']
|
||||
end
|
||||
|
||||
def debug_mode?
|
||||
config['debugmode'] == 'true'
|
||||
end
|
||||
|
||||
def loglevel
|
||||
if debug_mode?
|
||||
'debug'
|
||||
else
|
||||
'info'
|
||||
end
|
||||
end
|
||||
|
||||
def post_data
|
||||
post_data = {}
|
||||
post_data['clear_time'] = clear_time
|
||||
post_data['encoded_time'] = auth_token
|
||||
config.each_key do |key|
|
||||
post_data[key] = config[key] unless IGNORE_PARAMS.include?(key)
|
||||
end
|
||||
post_data
|
||||
end
|
||||
|
||||
def clear_time
|
||||
@clear_time ||= Time.new.utc.to_i.to_s
|
||||
end
|
||||
|
||||
def auth_token
|
||||
Digest::SHA1.hexdigest(clear_time.to_s + repository_key)
|
||||
end
|
||||
|
||||
# Detect blank params in config.
|
||||
# Allow blank repositoryid (as default).
|
||||
#
|
||||
def config_errors
|
||||
config.detect { |k, v| k != 'repositoryid' && v == '' }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def load_gitolite_vars
|
||||
REDMINE_PARAMS.each do |var_name|
|
||||
var_value = get_gitolite_config(var_name)
|
||||
var_name = sanitize(var_name)
|
||||
@config[var_name] = var_value
|
||||
end
|
||||
end
|
||||
|
||||
def get_gitolite_config(var_name)
|
||||
(%x[git config #{var_name}]).chomp.strip
|
||||
end
|
||||
|
||||
def sanitize(var_name)
|
||||
var_name.gsub(/^.*\./, '')
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,99 @@
|
|||
module GitHosting
|
||||
class CustomHook
|
||||
|
||||
attr_reader :repo_path
|
||||
attr_reader :refs
|
||||
attr_reader :git_config
|
||||
|
||||
|
||||
def initialize(repo_path, refs)
|
||||
@repo_path = repo_path
|
||||
@refs = refs
|
||||
@git_config = Config.new
|
||||
end
|
||||
|
||||
|
||||
def exec
|
||||
## Execute extra hooks
|
||||
extra_hooks = get_extra_hooks
|
||||
if !extra_hooks.empty?
|
||||
logger.info('Calling additional post-receive hooks...')
|
||||
call_extra_hooks(extra_hooks)
|
||||
logger.info('')
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
|
||||
def get_extra_hooks
|
||||
# Get global extra hooks
|
||||
logger.debug('Looking for additional global post-receive hooks...')
|
||||
global_extra_hooks = get_executables('hooks/post-receive.d')
|
||||
if global_extra_hooks.empty?
|
||||
logger.debug(' - No global hooks found')
|
||||
else
|
||||
logger.debug(" - Global hooks found : #{global_extra_hooks}")
|
||||
end
|
||||
|
||||
logger.debug('')
|
||||
|
||||
# Get local extra hooks
|
||||
logger.debug('Looking for additional local post-receive hooks...')
|
||||
local_extra_hooks = get_executables('hooks/post-receive.local.d')
|
||||
if local_extra_hooks.empty?
|
||||
logger.debug(' - No local hooks found')
|
||||
else
|
||||
logger.debug(" - Local hooks found : #{local_extra_hooks}")
|
||||
end
|
||||
|
||||
logger.debug('')
|
||||
|
||||
global_extra_hooks + local_extra_hooks
|
||||
end
|
||||
|
||||
|
||||
def get_executables(directory)
|
||||
executables = []
|
||||
if File.directory?(directory)
|
||||
Dir.foreach(directory) do |item|
|
||||
next if item == '.' or item == '..'
|
||||
# Use full relative path
|
||||
path = "#{directory}/#{item}"
|
||||
# Test if the file is executable
|
||||
if File.executable?(path)
|
||||
# Remember it, if so
|
||||
executables.push(path)
|
||||
end
|
||||
end
|
||||
end
|
||||
executables
|
||||
end
|
||||
|
||||
|
||||
def call_extra_hooks(extra_hooks)
|
||||
# Call each exectuble found with the parameters we got
|
||||
extra_hooks.each do |extra_hook|
|
||||
logger.info(" - Executing extra hook '#{extra_hook}'")
|
||||
|
||||
IO.popen("#{extra_hook}", "w+") do |pipe|
|
||||
begin
|
||||
pipe.puts refs
|
||||
pipe.close_write
|
||||
logger.info("#{pipe.read}")
|
||||
rescue => e
|
||||
logger.error("Error while executing hook #{extra_hook}")
|
||||
logger.error("#{e.message}")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def logger
|
||||
@logger ||= GitHosting::HookLogger.new(loglevel: git_config.loglevel)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,37 @@
|
|||
module GitHosting
|
||||
class HookLogger
|
||||
|
||||
attr_reader :loglevel
|
||||
|
||||
|
||||
def initialize(opts = {})
|
||||
@loglevel = opts.delete(:loglevel) { 'info' }
|
||||
end
|
||||
|
||||
|
||||
def debug(message)
|
||||
write(message) if loglevel == 'debug'
|
||||
end
|
||||
|
||||
|
||||
def info(message)
|
||||
write(message)
|
||||
end
|
||||
|
||||
|
||||
def error(message)
|
||||
write(message)
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
|
||||
def write(message)
|
||||
$stdout.sync = true
|
||||
$stdout.puts "\e[1G#{message}"
|
||||
$stdout.flush
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,126 @@
|
|||
require 'json'
|
||||
require 'net/http'
|
||||
require 'net/https'
|
||||
require 'uri'
|
||||
|
||||
module GitHosting
|
||||
module HttpHelper
|
||||
|
||||
def http_post(url, opts = {}, &block)
|
||||
http, request = build_post_request(url, opts)
|
||||
send_http_request(http, request, &block)
|
||||
end
|
||||
|
||||
|
||||
def http_get(url, opts = {}, &block)
|
||||
http, request = build_get_request(url, opts)
|
||||
send_http_request(http, request, &block)
|
||||
end
|
||||
|
||||
|
||||
def valid_url?(url)
|
||||
uri = URI.parse(url)
|
||||
uri.kind_of?(URI::HTTP)
|
||||
rescue URI::InvalidURIError
|
||||
false
|
||||
end
|
||||
|
||||
|
||||
def serialize_params(params)
|
||||
params.map do |key, value|
|
||||
if value.instance_of?(Array)
|
||||
value.map { |e| "#{urlencode(key.to_s)}=#{urlencode(e.to_s)}" }.join('&')
|
||||
else
|
||||
"#{urlencode(key.to_s)}=#{urlencode(value.to_s)}"
|
||||
end
|
||||
end.join('&')
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
|
||||
def urlencode(string)
|
||||
URI.encode(string, /[^a-zA-Z0-9_\.\-]/)
|
||||
end
|
||||
|
||||
|
||||
def build_post_request(url, opts = {})
|
||||
# Get params
|
||||
params = opts.delete(:params) { {} }
|
||||
|
||||
# Build request
|
||||
uri, http = build_http_request(url, opts)
|
||||
request = Net::HTTP::Post.new(uri.request_uri)
|
||||
|
||||
# Set request
|
||||
request.body = serialize_params(params)
|
||||
request.content_type = 'application/x-www-form-urlencoded'
|
||||
|
||||
return http, request
|
||||
end
|
||||
|
||||
|
||||
def build_get_request(url, opts = {})
|
||||
# Get params
|
||||
params = opts.delete(:params) { {} }
|
||||
params = serialize_params(params)
|
||||
|
||||
# Build request
|
||||
uri, http = build_http_request(url, opts)
|
||||
request = Net::HTTP::Get.new(uri.request_uri)
|
||||
|
||||
return http, request
|
||||
end
|
||||
|
||||
|
||||
def build_http_request(url, opts = {})
|
||||
# Get HTTP options
|
||||
open_timeout = opts.delete(:open_timeout) { 5 }
|
||||
read_timeout = opts.delete(:read_timeout) { 10 }
|
||||
|
||||
uri = URI(url)
|
||||
http = Net::HTTP.new(uri.host, uri.port)
|
||||
if uri.scheme == 'https'
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||
end
|
||||
|
||||
# Set HTTP options
|
||||
http.open_timeout = open_timeout
|
||||
http.read_timeout = read_timeout
|
||||
|
||||
return uri, http
|
||||
end
|
||||
|
||||
|
||||
def send_http_request(http, request, &block)
|
||||
if block_given?
|
||||
yield(http, request)
|
||||
else
|
||||
one_shot_request(http, request)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def one_shot_request(http, request)
|
||||
message = ''
|
||||
begin
|
||||
res = http.start { |openhttp| openhttp.request request }
|
||||
if !res.is_a?(Net::HTTPSuccess)
|
||||
message = "Return code : #{res.code} (#{res.message})."
|
||||
failed = true
|
||||
else
|
||||
message = res.body
|
||||
failed = false
|
||||
end
|
||||
rescue => e
|
||||
message = "Exception : #{e.message}"
|
||||
failed = true
|
||||
end
|
||||
|
||||
return failed, message
|
||||
end
|
||||
|
||||
end
|
||||
end
|
|
@ -0,0 +1,73 @@
|
|||
module GitHosting
|
||||
class PostReceive
|
||||
|
||||
include HttpHelper
|
||||
|
||||
attr_reader :repo_path
|
||||
attr_reader :refs
|
||||
attr_reader :git_config
|
||||
|
||||
|
||||
def initialize(repo_path, refs)
|
||||
@repo_path = repo_path
|
||||
@refs = refs
|
||||
@git_config = Config.new
|
||||
end
|
||||
|
||||
|
||||
def exec
|
||||
notify_redmine if git_config.valid?
|
||||
end
|
||||
|
||||
|
||||
private
|
||||
|
||||
|
||||
def notify_redmine
|
||||
logger.info('')
|
||||
logger.info("Notifying Redmine about changes to this repository : '#{git_config.repository_name}' ...")
|
||||
|
||||
http_post(git_config.project_url, { params: http_post_data }) do |http, request|
|
||||
begin
|
||||
http.request(request) { |response| check_response(response) }
|
||||
rescue => e
|
||||
logger.error("HTTP_ERROR : #{e.message}")
|
||||
end
|
||||
end
|
||||
|
||||
logger.info('')
|
||||
end
|
||||
|
||||
|
||||
def http_post_data
|
||||
git_config.post_data.merge('refs[]' => parsed_refs)
|
||||
end
|
||||
|
||||
|
||||
def parsed_refs
|
||||
parsed = []
|
||||
refs.split("\n").each do |line|
|
||||
r = line.chomp.strip.split
|
||||
parsed << [r[0].to_s, r[1].to_s, r[2].to_s].join(',')
|
||||
end
|
||||
parsed
|
||||
end
|
||||
|
||||
|
||||
def check_response(response)
|
||||
if response.code.to_i == 200
|
||||
response.read_body do |body_frag|
|
||||
body_frag.split("\n").each { |line| logger.info(line) }
|
||||
end
|
||||
else
|
||||
logger.error(" - Error while notifying Redmine ! (status code: #{response.code})")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def logger
|
||||
@logger ||= GitHosting::HookLogger.new(loglevel: git_config.loglevel)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,35 @@
|
|||
#! /usr/bin/env python
|
||||
|
||||
import sys
|
||||
import os
|
||||
|
||||
import git_multimail
|
||||
|
||||
|
||||
# It is possible to modify the output templates here; e.g.:
|
||||
|
||||
git_multimail.FOOTER_TEMPLATE = """\
|
||||
|
||||
-- \n\
|
||||
This email was generated by the wonderful git-multimail tool from JBox Web.
|
||||
"""
|
||||
|
||||
|
||||
# Specify which "git config" section contains the configuration for
|
||||
# git-multimail:
|
||||
config = git_multimail.Config('multimailhook')
|
||||
|
||||
# check if hook is enabled
|
||||
enabled = config.get_bool('enabled')
|
||||
|
||||
if enabled:
|
||||
# Select the type of environment:
|
||||
environment = git_multimail.GitoliteEnvironment(config=config)
|
||||
|
||||
# Choose the method of sending emails based on the git config:
|
||||
mailer = git_multimail.choose_mailer(config, environment)
|
||||
|
||||
# Read changes from stdin and send notification emails:
|
||||
git_multimail.run_as_post_receive_hook(environment, mailer)
|
||||
else:
|
||||
print(" multimailhook is disabled")
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env ruby
|
||||
|
||||
# This file was placed here by Redmine Git Hosting. It makes sure that your pushed commits
|
||||
# will be processed properly.
|
||||
|
||||
refs = ARGF.read
|
||||
repo_path = Dir.pwd
|
||||
|
||||
require_relative 'lib/git_hosting/http_helper'
|
||||
require_relative 'lib/git_hosting/hook_logger'
|
||||
require_relative 'lib/git_hosting/config'
|
||||
require_relative 'lib/git_hosting/post_receive'
|
||||
require_relative 'lib/git_hosting/custom_hook'
|
||||
|
||||
if GitHosting::PostReceive.new(repo_path, refs).exec && GitHosting::CustomHook.new(repo_path, refs).exec
|
||||
exit 0
|
||||
else
|
||||
exit 1
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue