tutter 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gemspec +20 -0
- data/.gitignore +3 -0
- data/Gemfile +9 -0
- data/README.md +59 -0
- data/bin/tutter +75 -0
- data/conf/tutter.yaml +11 -0
- data/lib/tutter/action/thanks.rb +24 -0
- data/lib/tutter/action.rb +11 -0
- data/lib/tutter.rb +68 -0
- metadata +84 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b51fa2f78d6e5c075b9e5d5277d8bbe842e3a7bb
|
4
|
+
data.tar.gz: e066f2ee612e05aaf55d40faf93429a835da4f95
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: dfa1ad7f83fa9d5598c4d3ce254e3bce5b29690fe46d3ae3f7b95e7d6d9eb9ebc7342ca971c9534bb4e2375cc16131f265406879bb7569eb769f98f61cc73016
|
7
|
+
data.tar.gz: 41d9de92f0dab613efbc2e2323fae987582eed6ed9e24b464cff5b557b46e5160438a107aeef807cb14c160b08869891baaf335d15f29f685df5535c5eacca1b
|
data/.gemspec
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
Gem::Specification.new do |s|
|
3
|
+
s.name = 'tutter'
|
4
|
+
s.version = '0.0.1'
|
5
|
+
s.author = 'Johan Haals'
|
6
|
+
s.email = ['johan.haals@gmail.com']
|
7
|
+
s.homepage = 'https://github.com/jhaals/tutter'
|
8
|
+
s.summary = 'Plugin based Github robot'
|
9
|
+
s.description = 'Tutter is a web app that trigger actions based on Github events(push, pull_reqeust, release, issue, ...)'
|
10
|
+
s.license = 'Apache 2.0'
|
11
|
+
|
12
|
+
s.files = `git ls-files`.split("\n")
|
13
|
+
s.executables = `git ls-files bin`.split("\n").map { |f| File.basename f }
|
14
|
+
s.require_paths = ['lib', 'conf']
|
15
|
+
|
16
|
+
s.required_ruby_version = '>= 1.8.7'
|
17
|
+
s.add_runtime_dependency 'sinatra', '~> 1.4.4'
|
18
|
+
s.add_runtime_dependency 'octokit', '~> 2.7.1'
|
19
|
+
end
|
20
|
+
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
# Tutter - Plugin based Github robot
|
2
|
+
Tutter is a web app that trigger actions based on Github events(push, pull_reqeust, release, issue, ...)
|
3
|
+
|
4
|
+
# Features
|
5
|
+
* Pluggable with custom actions
|
6
|
+
* Supports multiple projects
|
7
|
+
|
8
|
+
# Installation
|
9
|
+
|
10
|
+
gem install tutter
|
11
|
+
|
12
|
+
put a configuration file in `/etc/tutter.yaml`
|
13
|
+
an example can be found under `conf/tutter.yaml`
|
14
|
+
|
15
|
+
Let's install the `thanks` action that thank anyone that creates an issue in your project.
|
16
|
+
|
17
|
+
### tutter.yaml settings
|
18
|
+
|
19
|
+
* `name` - username/projectname
|
20
|
+
* `access_token` - github access token (can be generated [here](https://github.com/settings/applications))
|
21
|
+
* `github_site` - github website
|
22
|
+
* `github_api_enpoint` - github api endpint
|
23
|
+
* `action` - action you wish to use for the project
|
24
|
+
* `action_settings` - whatever settings your action require
|
25
|
+
|
26
|
+
### Create the Github hook
|
27
|
+
Github has no UI for creating hooks other then hooks triggered on push.
|
28
|
+
|
29
|
+
Let's create one that triggers on issues
|
30
|
+
|
31
|
+
$ tutter --project jhaals/testing \
|
32
|
+
--url https://tutter.jhaals.se \
|
33
|
+
--access-token <github_api_token> \
|
34
|
+
--github-web-url https://github.com \
|
35
|
+
--github-api-endpoint https://api.github.com \
|
36
|
+
--events issues
|
37
|
+
|
38
|
+
## Build custom action
|
39
|
+
|
40
|
+
Another example action [github.com/jhaals/tutter-sppuppet](https://github.com/jhaals/tutter-sppuppet)
|
41
|
+
|
42
|
+
#####Required methods and their arguments
|
43
|
+
|
44
|
+
`initialize`
|
45
|
+
|
46
|
+
settings - contains a hash of action specific settings
|
47
|
+
client - Used to access the github api, all authentication is already done by tutter
|
48
|
+
project - Project name, eg jhaals/tutter
|
49
|
+
data - POST data that github send when a hook is triggered
|
50
|
+
|
51
|
+
`run` - Run action
|
52
|
+
|
53
|
+
Tutter uses [octokit.rb](https://github.com/octokit/octokit.rb) to communicate with the Github [API](http://developer.github.com/v3/)
|
54
|
+
|
55
|
+
### Features to implement
|
56
|
+
* Add web hooks in Github automatically
|
57
|
+
* Support multiple actions per project
|
58
|
+
* Authenticate as a Github application
|
59
|
+
* Features your're missing (please contribute)
|
data/bin/tutter
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'optparse'
|
3
|
+
require 'octokit'
|
4
|
+
|
5
|
+
options = {}
|
6
|
+
|
7
|
+
OptionParser.new do |opts|
|
8
|
+
opts.banner = "Usage: tutter --project [project] [options]"
|
9
|
+
opts.on("-p", "--project [PROJECT]", "Github project name (jhaals/tutter)") do |p|
|
10
|
+
options[:project] = p
|
11
|
+
end
|
12
|
+
opts.on("-e", "--events [EVENTS]", "Github events that will trigger tutter") do |e|
|
13
|
+
options[:events] = e
|
14
|
+
end
|
15
|
+
opts.on("-u", "--url [URL]", "URL to the tutter service") do |u|
|
16
|
+
options[:url] = u
|
17
|
+
end
|
18
|
+
opts.on("-t", "--access-token [TOKEN]", "Github access token") do |t|
|
19
|
+
options[:access_token] = t
|
20
|
+
end
|
21
|
+
opts.on("--github-api-endpoint [api-endpoint]", "Github API endpoint") do |t|
|
22
|
+
options[:api_endpoint] = t
|
23
|
+
end
|
24
|
+
opts.on("--github-web-url [GITHUBWEBSITE]", "Github website url") do |t|
|
25
|
+
options[:base_url] = t
|
26
|
+
end
|
27
|
+
end.parse!
|
28
|
+
|
29
|
+
if options[:project].nil?
|
30
|
+
puts '--project required'
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
|
34
|
+
if options[:url].nil?
|
35
|
+
puts '--url required'
|
36
|
+
exit 1
|
37
|
+
end
|
38
|
+
|
39
|
+
if options[:access_token].nil?
|
40
|
+
puts '--access-token required'
|
41
|
+
exit 1
|
42
|
+
end
|
43
|
+
|
44
|
+
if options[:base_url].nil?
|
45
|
+
puts '--github-web-url required'
|
46
|
+
exit 1
|
47
|
+
end
|
48
|
+
|
49
|
+
if options[:api_endpoint].nil?
|
50
|
+
puts '--github-api-endpoint required'
|
51
|
+
exit 1
|
52
|
+
end
|
53
|
+
|
54
|
+
Octokit.configure do |c|
|
55
|
+
c.api_endpoint = options[:api_endpoint]
|
56
|
+
c.web_endpoint = options[:base_url]
|
57
|
+
end
|
58
|
+
|
59
|
+
client = Octokit::Client.new :access_token => options[:access_token]
|
60
|
+
client.login
|
61
|
+
|
62
|
+
p client.create_hook(
|
63
|
+
options[:project],
|
64
|
+
'web',
|
65
|
+
{
|
66
|
+
:url => options[:url],
|
67
|
+
:content_type => 'json'
|
68
|
+
},
|
69
|
+
{
|
70
|
+
:events => options[:events].split(','),
|
71
|
+
:active => true
|
72
|
+
}
|
73
|
+
)
|
74
|
+
|
75
|
+
|
data/conf/tutter.yaml
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# Example action
|
2
|
+
# Thank the person who submit an issue
|
3
|
+
|
4
|
+
class Thanks
|
5
|
+
def initialize(settings, client, project, data)
|
6
|
+
@settings = settings # action specific settings
|
7
|
+
@client = client # Octokit client
|
8
|
+
@project = project # project name
|
9
|
+
@data = data
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
# Only trigger if a new issue is created
|
14
|
+
return unless @data['action'] == 'opened'
|
15
|
+
|
16
|
+
issue = @data['issue']['number']
|
17
|
+
submitter = @data['issue']['user']['login']
|
18
|
+
comment = "@#{submitter} thanks for submitting this issue!"
|
19
|
+
|
20
|
+
puts comment # just for debug purpose
|
21
|
+
@client.add_comment(@project, issue, comment)
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class Action
|
2
|
+
def self.create(action, settings, client, project, data)
|
3
|
+
begin
|
4
|
+
require "tutter/action/#{action.downcase}"
|
5
|
+
rescue LoadError => e
|
6
|
+
raise "Unsupported action #{action}: #{e}"
|
7
|
+
end
|
8
|
+
class_name = action.split("_").map {|v| v.capitalize }.join
|
9
|
+
const_get(class_name).new settings, client, project, data
|
10
|
+
end
|
11
|
+
end
|
data/lib/tutter.rb
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
require 'octokit'
|
2
|
+
require 'yaml'
|
3
|
+
require 'sinatra'
|
4
|
+
require 'tutter/action'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
class Tutter < Sinatra::Base
|
8
|
+
configure :development do
|
9
|
+
require 'sinatra/reloader'
|
10
|
+
register Sinatra::Reloader
|
11
|
+
set :config, YAML.load_file('conf/tutter.yaml')
|
12
|
+
set :bind, '0.0.0.0'
|
13
|
+
end
|
14
|
+
|
15
|
+
configure :production do
|
16
|
+
set :config, YAML.load_file('/etc/tutter.yaml')
|
17
|
+
end
|
18
|
+
|
19
|
+
# Return project settings from config
|
20
|
+
def get_project_settings project
|
21
|
+
settings.config['projects'].each do |p|
|
22
|
+
return p if p['name'] == project
|
23
|
+
end
|
24
|
+
false
|
25
|
+
end
|
26
|
+
|
27
|
+
post '/' do
|
28
|
+
# Github send data in JSON format, parse it!
|
29
|
+
data = JSON.parse request.body.read
|
30
|
+
project = data['repository']['full_name']
|
31
|
+
|
32
|
+
conf = get_project_settings(project)
|
33
|
+
return 'Project does not exist in tutter.conf' unless conf
|
34
|
+
|
35
|
+
# Setup octokit endpoints
|
36
|
+
Octokit.configure do |c|
|
37
|
+
c.api_endpoint = conf['github_api_endpoint']
|
38
|
+
c.web_endpoint = conf['github_site']
|
39
|
+
end
|
40
|
+
|
41
|
+
# Authenticate to Github
|
42
|
+
begin
|
43
|
+
client = Octokit::Client.new :access_token => conf['access_token']
|
44
|
+
rescue Octokit::Unauthorized
|
45
|
+
return "Authorization to #{project} failed, please verify your access token"
|
46
|
+
rescue Octokit::TooManyLoginAttempts
|
47
|
+
return "Account for #{project} has been temporary locked down due to to many failed login attempts"
|
48
|
+
end
|
49
|
+
|
50
|
+
# Load action
|
51
|
+
action = Action.create(conf['action'],
|
52
|
+
conf['action_settings'],
|
53
|
+
client,
|
54
|
+
project,
|
55
|
+
data)
|
56
|
+
|
57
|
+
action.run
|
58
|
+
# Github does not care about status codes or return values.
|
59
|
+
# Output url to source if someone is interested
|
60
|
+
'Source code and documentation at https://github.com/jhaals/tutter'
|
61
|
+
end
|
62
|
+
|
63
|
+
get '/' do
|
64
|
+
'Source code and documentation at https://github.com/jhaals/tutter'
|
65
|
+
end
|
66
|
+
|
67
|
+
run! if app_file == $0
|
68
|
+
end
|
metadata
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tutter
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Johan Haals
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-02-03 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: sinatra
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.4.4
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.4.4
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: octokit
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 2.7.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 2.7.1
|
41
|
+
description: Tutter is a web app that trigger actions based on Github events(push,
|
42
|
+
pull_reqeust, release, issue, ...)
|
43
|
+
email:
|
44
|
+
- johan.haals@gmail.com
|
45
|
+
executables:
|
46
|
+
- tutter
|
47
|
+
extensions: []
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- .gemspec
|
51
|
+
- .gitignore
|
52
|
+
- Gemfile
|
53
|
+
- README.md
|
54
|
+
- bin/tutter
|
55
|
+
- conf/tutter.yaml
|
56
|
+
- lib/tutter.rb
|
57
|
+
- lib/tutter/action.rb
|
58
|
+
- lib/tutter/action/thanks.rb
|
59
|
+
homepage: https://github.com/jhaals/tutter
|
60
|
+
licenses:
|
61
|
+
- Apache 2.0
|
62
|
+
metadata: {}
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
require_paths:
|
66
|
+
- lib
|
67
|
+
- conf
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.8.7
|
73
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements: []
|
79
|
+
rubyforge_project:
|
80
|
+
rubygems_version: 2.0.3
|
81
|
+
signing_key:
|
82
|
+
specification_version: 4
|
83
|
+
summary: Plugin based Github robot
|
84
|
+
test_files: []
|