Initial commit of gem for trello/github integration
This commit is contained in:
Коммит
4ced5b2ae0
|
@ -0,0 +1,4 @@
|
|||
source "http://rubygems.org"
|
||||
gemspec
|
||||
|
||||
gem "rake"
|
|
@ -0,0 +1,29 @@
|
|||
PATH
|
||||
remote: .
|
||||
specs:
|
||||
github-trello (0.0.1)
|
||||
sinatra (~> 1.3.2)
|
||||
vegas (~> 0.1.8)
|
||||
|
||||
GEM
|
||||
remote: http://rubygems.org/
|
||||
specs:
|
||||
rack (1.4.1)
|
||||
rack-protection (1.2.0)
|
||||
rack
|
||||
rake (0.9.2.2)
|
||||
sinatra (1.3.2)
|
||||
rack (~> 1.3, >= 1.3.6)
|
||||
rack-protection (~> 1.2)
|
||||
tilt (~> 1.3, >= 1.3.3)
|
||||
tilt (1.3.3)
|
||||
vegas (0.1.11)
|
||||
rack (>= 1.0.0)
|
||||
|
||||
PLATFORMS
|
||||
java
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
github-trello!
|
||||
rake
|
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2011 Zachary Anker
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,4 @@
|
|||
Overview
|
||||
===
|
||||
Allows you to manage or reference your Trello board through commits to Github. Tag a commit with "Closes 1234" to have a card automatically archived, or "Card 1234" to have the commit sent to the card.
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
require "bundler"
|
||||
Bundler.setup
|
||||
|
||||
require "rake"
|
||||
require "rspec"
|
||||
require "rspec/core/rake_task"
|
||||
|
||||
RSpec::Core::RakeTask.new("spec") do |spec|
|
||||
spec.pattern = "spec/**/*_spec.rb"
|
||||
end
|
||||
|
||||
task :default => :spec
|
|
@ -0,0 +1,25 @@
|
|||
#!/usr/bin/env ruby
|
||||
$LOAD_PATH.unshift File.expand_path(File.dirname(__FILE__) + "/../lib")
|
||||
|
||||
require "vegas"
|
||||
require "github-trello/server"
|
||||
|
||||
Vegas::Runner.new(GithubTrello::Server, "trello-web", {
|
||||
:launch_path => lambda {|vegas|
|
||||
path = File.join(vegas.app_dir, "trello.yml")
|
||||
if File.exists?(path)
|
||||
GithubTrello::Server.config = YAML::load(File.read(path))
|
||||
else
|
||||
puts "[WARNING] No configuration found at #{path}."
|
||||
puts "We've generated an example one for you, but you need to configure it still."
|
||||
|
||||
File.open(path, "w+") do |f|
|
||||
f.write("#board_ids:\n# [repo name]: [board id]\n#oauth_token: [token]\n#api_key: [key]#on_start:\n# move_to: [list id]\n#on_close:\n# move_to: [list id]\n# archive: false\n# on_deploy:\n# move_to: [list id]\n# archive: true")
|
||||
end
|
||||
|
||||
exit
|
||||
end
|
||||
|
||||
nil
|
||||
}
|
||||
})
|
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env ruby
|
||||
$LOAD_PATH.unshift ::File.expand_path(::File.dirname(__FILE__) + "/lib")
|
||||
require "trello/server"
|
||||
|
||||
use Rack::ShowExceptions
|
||||
run TrelloService::Server.new
|
|
@ -0,0 +1,21 @@
|
|||
$LOAD_PATH.unshift(File.expand_path("../lib", __FILE__))
|
||||
require "github-trello/version"
|
||||
|
||||
Gem::Specification.new do |s|
|
||||
s.name = "github-trello"
|
||||
s.version = GithubTrello::VERSION
|
||||
s.platform = Gem::Platform::RUBY
|
||||
s.authors = ["Zachary Anker"]
|
||||
s.email = ["zach.anker@gmail.com"]
|
||||
s.homepage = "http://github.com/zanker/github-trello"
|
||||
s.summary = "Github -> Trello integration"
|
||||
|
||||
s.required_rubygems_version = ">= 1.3.6"
|
||||
s.rubyforge_project = "github-trello"
|
||||
|
||||
s.add_runtime_dependency "vegas", "~>0.1.8"
|
||||
s.add_runtime_dependency "sinatra", "~>1.3.2"
|
||||
|
||||
s.files = Dir.glob("lib/**/*") + %w[MIT-LICENSE README.md Rakefile]
|
||||
s.executables = ["trello-web"]
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
require "github-trello/version"
|
|
@ -0,0 +1,54 @@
|
|||
require "cgi"
|
||||
require "net/https"
|
||||
|
||||
module GithubTrello
|
||||
class HTTP
|
||||
def initialize(token, api_key)
|
||||
@token, @api_key = token, api_key
|
||||
@uri = URI("https://api.trello.com")
|
||||
end
|
||||
|
||||
def get_card(board_id, card_id)
|
||||
http_request(:get, "/1/boards/#{board_id}/cards/#{card_id}", :params => {:fields => "idList,closed"})
|
||||
end
|
||||
|
||||
def update_card(card_id, params)
|
||||
http_request(:put, "/1/cards/#{card_id}", :params => params)
|
||||
end
|
||||
|
||||
def add_comment(card_id, comment)
|
||||
http_request(:post, "/1/cards/#{card_id}/actions/comments", :body => "text=#{CGI::escape(comment)}")
|
||||
end
|
||||
|
||||
private
|
||||
def http_request(method, request_path, args={})
|
||||
|
||||
request_path << "?"
|
||||
args[:params] ||= {}
|
||||
args[:params][:key] = @api_key
|
||||
args[:params][:token] = @token
|
||||
args[:params].each {|k, v| request_path << "#{k}=#{CGI::escape(v)}&"}
|
||||
|
||||
http = Net::HTTP.new(@uri.host, @uri.port)
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
||||
http.set_debug_output($stdout)
|
||||
|
||||
http.start
|
||||
|
||||
if method == :get
|
||||
response = http.request_get(request_path)
|
||||
elsif method == :post
|
||||
response = http.request_post(request_path, args.delete(:body))
|
||||
elsif method == :put
|
||||
response = http.request_put(request_path, args.delete(:body))
|
||||
end
|
||||
|
||||
unless response.code == "200" or response.code == "201"
|
||||
raise Net::HTTPError.new("#{response.body == "" ? response.message : response.body.strip} (#{response.code})", response)
|
||||
end
|
||||
|
||||
response.body
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,87 @@
|
|||
require "json"
|
||||
require "sinatra/base"
|
||||
require "github-trello/version"
|
||||
require "github-trello/http"
|
||||
|
||||
module GithubTrello
|
||||
class Server < Sinatra::Base
|
||||
get "/posthook" do
|
||||
config, http = self.class.config, self.class.http
|
||||
|
||||
payload = JSON.parse(params[:payload])
|
||||
|
||||
board_id = config["board_ids"][payload["repository"]["name"]]
|
||||
unless board_id
|
||||
puts "[ERROR] Commit from #{payload["repository"]["name"]} but no board_id entry found in config"
|
||||
return
|
||||
end
|
||||
|
||||
branch = payload["ref"].gsub("refs/heads/", "")
|
||||
if config["blacklist_branches"] and config["blacklist_branches"].include?(branch)
|
||||
return
|
||||
elsif config["whitelist_branches"] and !config["whitelist_branches"].include?(branch)
|
||||
return
|
||||
end
|
||||
|
||||
payload["commits"].each do |commit|
|
||||
# Figure out the card short id
|
||||
match = commit["message"].match(/((case|card|close|archive|fix)e?s? \D?([0-9]+))/i)
|
||||
next unless match and match[3].to_i > 0
|
||||
|
||||
# Determine the action to take
|
||||
update_config = case match[2].downcase
|
||||
when "case", "card" then config["on_start"]
|
||||
when "close", "fix" then config["on_close"]
|
||||
when "archive" then {:archive => true}
|
||||
end
|
||||
|
||||
unless update_config.is_a?(Hash)
|
||||
raise "Updating card with #{match[2].downcase} type, but no config found to indicate what to do"
|
||||
end
|
||||
|
||||
results = http.get_card(board_id, match[3].to_i)
|
||||
unless results
|
||||
puts "[ERROR] Cannot find card matching ID #{match[3]}"
|
||||
next
|
||||
end
|
||||
|
||||
results = JSON.parse(results)
|
||||
|
||||
# Add the commit comment
|
||||
message = "#{commit["author"]["name"]}: #{commit["message"]}\n\n[#{branch}] #{commit["url"]}"
|
||||
message.gsub!(match[1], "")
|
||||
message.gsub!(/\(\)$/, "")
|
||||
|
||||
http.add_comment(results["id"], message)
|
||||
|
||||
# Modify it if needed
|
||||
to_update = {}
|
||||
unless results["idList"] == update_config["move_to"]
|
||||
to_update[:idList] = update_config["move_to"]
|
||||
end
|
||||
|
||||
if !results["closed"] and update_config["archive"]
|
||||
to_update[:closed] = true
|
||||
end
|
||||
|
||||
unless to_update.empty?
|
||||
http.update_card(results["id"], to_update)
|
||||
end
|
||||
end
|
||||
|
||||
""
|
||||
end
|
||||
|
||||
get "/" do
|
||||
"Nothing to see here"
|
||||
end
|
||||
|
||||
def self.config=(config)
|
||||
@config = config
|
||||
@http = GithubTrello::HTTP.new(config["oauth_token"], config["api_key"])
|
||||
end
|
||||
|
||||
def self.config; @config end
|
||||
def self.http; @http end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
module GithubTrello
|
||||
VERSION = "0.0.1"
|
||||
end
|
Загрузка…
Ссылка в новой задаче