octogate 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/Procfile.sample +1 -0
- data/README.md +76 -0
- data/Rakefile +6 -0
- data/bin/octogate +19 -0
- data/lib/octogate.rb +23 -0
- data/lib/octogate/client.rb +77 -0
- data/lib/octogate/config_loader.rb +38 -0
- data/lib/octogate/configuration.rb +13 -0
- data/lib/octogate/events.rb +7 -0
- data/lib/octogate/events/base.rb +9 -0
- data/lib/octogate/events/push.rb +35 -0
- data/lib/octogate/gh.rb +8 -0
- data/lib/octogate/gh/commit.rb +14 -0
- data/lib/octogate/gh/repository.rb +13 -0
- data/lib/octogate/gh/user.rb +7 -0
- data/lib/octogate/model.rb +7 -0
- data/lib/octogate/server.rb +24 -0
- data/lib/octogate/target.rb +7 -0
- data/lib/octogate/target_builder.rb +58 -0
- data/lib/octogate/version.rb +3 -0
- data/octogate.gemspec +33 -0
- data/spec/config_sample.rb +74 -0
- data/spec/lib/octogate/client_spec.rb +77 -0
- data/spec/lib/octogate/config_loader_spec.rb +26 -0
- data/spec/lib/octogate/events/push_spec.rb +14 -0
- data/spec/push_payload.json +94 -0
- data/spec/spec_helper.rb +26 -0
- metadata +237 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9d8aa41425c8878a5c93d417a2860bee799fd838
|
4
|
+
data.tar.gz: 42f4002ab39a5520b20993556bdefc6c6a4b9a2a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6efc13bf5526eb0605be1b4034a577bfb6a7845d65d82746b7bd60fddc127b459ccc816185d51d331df2bc6bb87ddfebe62ba9bb93b028456102b95d74bf8544
|
7
|
+
data.tar.gz: 1d2ce3e644677d8499b683e676b7a67eef6d0411eb96a67bd7f2e2754da53ada822fba704642ba589d8df82ba7b732a9c125bf06c9ea53758ace7bcecde632f7
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 joker1007
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Procfile.sample
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
web: bundle exec octogate -c ./config.rb -p $PORT
|
data/README.md
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
# Octogate
|
2
|
+
[![Build Status](https://travis-ci.org/joker1007/octogate.png?branch=master)](https://travis-ci.org/joker1007/octogate)
|
3
|
+
[![Code Climate](https://codeclimate.com/github/joker1007/octogate.png)](https://codeclimate.com/github/joker1007/octogate)
|
4
|
+
|
5
|
+
Github hook proxy server of Sinatra Framework.
|
6
|
+
|
7
|
+
You can write about request destination in Ruby DSL
|
8
|
+
|
9
|
+
## Installation
|
10
|
+
|
11
|
+
Add this line to your application's Gemfile:
|
12
|
+
|
13
|
+
gem 'octogate'
|
14
|
+
|
15
|
+
And then execute:
|
16
|
+
|
17
|
+
$ bundle
|
18
|
+
|
19
|
+
Or install it yourself as:
|
20
|
+
|
21
|
+
$ gem install octogate
|
22
|
+
|
23
|
+
## Usage
|
24
|
+
|
25
|
+
Write config.rb.
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
token "token_string"
|
29
|
+
|
30
|
+
target "jenkins" do
|
31
|
+
hook_type [:push, :pull_request]
|
32
|
+
url "http://targethost.dev/job/CommitStage"
|
33
|
+
http_method :get
|
34
|
+
|
35
|
+
parameter_type :query
|
36
|
+
params key1: "value1", key2: "value2"
|
37
|
+
|
38
|
+
match -> {
|
39
|
+
hook.ref =~ /master/
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
target "jenkins2" do
|
44
|
+
hook_type [:push, :pull_request]
|
45
|
+
url "http://targethost2.dev/job/CommitStage"
|
46
|
+
http_method :get
|
47
|
+
|
48
|
+
parameter_type :json
|
49
|
+
params key1: "value1", key2: "value2"
|
50
|
+
|
51
|
+
match -> {
|
52
|
+
!(hook.ref =~ /master/)
|
53
|
+
}
|
54
|
+
end
|
55
|
+
```
|
56
|
+
|
57
|
+
And launch server.
|
58
|
+
|
59
|
+
```sh
|
60
|
+
% bundle exec octogate -h
|
61
|
+
Usage: octogate [options]
|
62
|
+
-c config Set config file (default = ./config.rb)
|
63
|
+
-p port Set port number (default = 4567)
|
64
|
+
-o address Set address to bind (default = 0.0.0.0)
|
65
|
+
|
66
|
+
% bundle exec octogate -c config.rb
|
67
|
+
# => Endpoint is http://hostname:4567/token_string
|
68
|
+
```
|
69
|
+
|
70
|
+
## Contributing
|
71
|
+
|
72
|
+
1. Fork it ( https://github.com/joker1007/octogate/fork )
|
73
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
74
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
75
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
76
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
data/bin/octogate
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "octogate"
|
4
|
+
require "octogate/server"
|
5
|
+
require 'optparse'
|
6
|
+
|
7
|
+
options = {config_file: "./config.rb", bind: "0.0.0.0"}
|
8
|
+
OptionParser.new { |o|
|
9
|
+
o.on('-c config', 'Set config file (default = ./config.rb)') { |config_file| options[:config_file] = config_file }
|
10
|
+
o.on('-p port', 'Set port number (default = 4567)') { |port| options[:port] = port.to_i }
|
11
|
+
o.on('-o address', 'Set address to bind (default = 0.0.0.0)') { |addr| options[:bind] = addr }
|
12
|
+
o.on('-s server', 'Set Rack server handler name') { |handler| options[:server] = handler }
|
13
|
+
}.parse!(ARGV.dup)
|
14
|
+
|
15
|
+
|
16
|
+
Octogate::ConfigLoader.load_config(options[:config_file])
|
17
|
+
puts "Load Config: #{options[:config_file]}"
|
18
|
+
|
19
|
+
Octogate::Server.run!(options)
|
data/lib/octogate.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "octogate/version"
|
2
|
+
|
3
|
+
require "active_support/core_ext/hash"
|
4
|
+
require "active_support/core_ext/object"
|
5
|
+
require "oj"
|
6
|
+
|
7
|
+
require "octogate/configuration"
|
8
|
+
|
9
|
+
module Octogate
|
10
|
+
class << self
|
11
|
+
def config
|
12
|
+
@config ||= Configuration.instance
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
require "octogate/model"
|
18
|
+
require "octogate/client"
|
19
|
+
require "octogate/config_loader"
|
20
|
+
require "octogate/target"
|
21
|
+
require "octogate/target_builder"
|
22
|
+
require "octogate/events"
|
23
|
+
require "octogate/gh"
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require "faraday"
|
2
|
+
require "uri"
|
3
|
+
|
4
|
+
class Octogate::Client
|
5
|
+
attr_reader :event
|
6
|
+
|
7
|
+
def initialize(event)
|
8
|
+
@event = event
|
9
|
+
end
|
10
|
+
|
11
|
+
def request_to_targets
|
12
|
+
Octogate.config.targets.each do |t|
|
13
|
+
condition = event.default_condition
|
14
|
+
case t.match
|
15
|
+
when Proc
|
16
|
+
condition = condition && instance_exec(event, &t.match)
|
17
|
+
when nil
|
18
|
+
else
|
19
|
+
condition = condition && !!t.match
|
20
|
+
end
|
21
|
+
|
22
|
+
if condition
|
23
|
+
request(t)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def request(t)
|
29
|
+
uri = URI(t.url)
|
30
|
+
|
31
|
+
options = {url: t.url}
|
32
|
+
options.merge!(ssl_options) if uri.scheme == "https"
|
33
|
+
|
34
|
+
conn = build_connection(options, t.username, t.password)
|
35
|
+
|
36
|
+
params = t.params.respond_to?(:call) ? t.params.call(event) : t.params
|
37
|
+
|
38
|
+
case t.http_method
|
39
|
+
when :get
|
40
|
+
conn.get do |req|
|
41
|
+
req.url uri.path
|
42
|
+
params.each do |k, v|
|
43
|
+
req.params[k] = v
|
44
|
+
end
|
45
|
+
end
|
46
|
+
when :post
|
47
|
+
if t.parameter_type == :json
|
48
|
+
conn.post uri.path do |req|
|
49
|
+
req.headers['Content-Type'] = 'application/json'
|
50
|
+
req.body = Oj.dump(params)
|
51
|
+
end
|
52
|
+
else
|
53
|
+
conn.post uri.path, params
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def build_connection(options, username = nil, password = nil)
|
61
|
+
conn = Faraday.new(options) do |faraday|
|
62
|
+
faraday.request :url_encoded
|
63
|
+
faraday.response :logger if ENV["RACK_ENV"] == "development" || ENV["RACK_ENV"] == "production"
|
64
|
+
faraday.adapter Faraday.default_adapter
|
65
|
+
end
|
66
|
+
conn.basic_auth(username, password) if username && password
|
67
|
+
conn
|
68
|
+
end
|
69
|
+
|
70
|
+
def ssl_options
|
71
|
+
if Octogate.config.ssl_verify
|
72
|
+
Octogate.config.ca_file ? {ssl: {ca_file: Octogate.config.ca_file}} : {}
|
73
|
+
else
|
74
|
+
{ssl: {verify: false}}
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Octogate
|
2
|
+
class ConfigLoader
|
3
|
+
class << self
|
4
|
+
def load_config(config_file)
|
5
|
+
instance = new
|
6
|
+
instance.instance_eval(File.read(config_file), config_file)
|
7
|
+
instance.instance_eval do
|
8
|
+
@_target_builders.each do |tb|
|
9
|
+
Octogate.config.targets ||= []
|
10
|
+
Octogate.config.targets << tb.__to_target__
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@_target_builders = []
|
18
|
+
end
|
19
|
+
|
20
|
+
def token(token)
|
21
|
+
Octogate.config.token = token
|
22
|
+
end
|
23
|
+
|
24
|
+
def target(name, &block)
|
25
|
+
builder = TargetBuilder.new
|
26
|
+
builder.instance_eval(&block)
|
27
|
+
@_target_builders << builder
|
28
|
+
end
|
29
|
+
|
30
|
+
def ca_file(ca_file)
|
31
|
+
Octogate.config.ca_file = ca_file
|
32
|
+
end
|
33
|
+
|
34
|
+
def ssl_verify(verify)
|
35
|
+
Octogate.config.ssl_verify = verify
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Octogate
|
2
|
+
class Event::Push < Event::Base
|
3
|
+
attr_reader :ref, :after, :before, :created, :deleted, :forced, :compare, :commits, :head_commit, :repository, :pusher
|
4
|
+
class << self
|
5
|
+
def parse(json)
|
6
|
+
payload = Oj.load(json).deep_symbolize_keys
|
7
|
+
|
8
|
+
commits = payload[:commits].map do |c|
|
9
|
+
GH::Commit.new(c.symbolize_keys)
|
10
|
+
end
|
11
|
+
|
12
|
+
head_commit = payload[:head_commit] ? GH::Commit.new(payload[:head_commit]) : nil
|
13
|
+
|
14
|
+
repository = GH::Repository.new(payload[:repository])
|
15
|
+
|
16
|
+
new(
|
17
|
+
ref: payload[:ref],
|
18
|
+
after: payload[:after],
|
19
|
+
before: payload[:before],
|
20
|
+
created: payload[:created],
|
21
|
+
deleted: payload[:deleted],
|
22
|
+
forced: payload[:forced],
|
23
|
+
compare: payload[:compare],
|
24
|
+
commits: commits,
|
25
|
+
head_commit: head_commit,
|
26
|
+
repository: repository,
|
27
|
+
)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def default_condition
|
32
|
+
!deleted
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/octogate/gh.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module Octogate
|
2
|
+
class GH::Commit
|
3
|
+
include Model
|
4
|
+
|
5
|
+
attr_reader :id, :distinct, :message, :timestamp, :url, :author, :commiter, :added, :removed, :modified
|
6
|
+
|
7
|
+
def initialize(**args)
|
8
|
+
new_args = args.deep_symbolize_keys
|
9
|
+
new_args[:author] = GH::User.new(new_args[:author]) if new_args[:author]
|
10
|
+
new_args[:committer] = GH::User.new(new_args[:committer]) if new_args[:committer]
|
11
|
+
super(new_args)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Octogate
|
2
|
+
class GH::Repository
|
3
|
+
include Model
|
4
|
+
|
5
|
+
attr_reader :id, :name, :description, :homepage, :watchers, :stargazers, :forks, :fork, :size, :owner, :private, :open_issues, :has_issues, :has_downloads, :has_wiki, :language, :created_at, :pushed_at, :master_branch, :pusher
|
6
|
+
|
7
|
+
def initialize(**args)
|
8
|
+
new_args = args.deep_symbolize_keys
|
9
|
+
new_args[:owner] = GH::User.new(new_args[:owner]) if new_args[:owner]
|
10
|
+
super(new_args)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require "sinatra"
|
2
|
+
|
3
|
+
class Octogate::Server < Sinatra::Base
|
4
|
+
configure :production, :development do
|
5
|
+
enable :logging
|
6
|
+
end
|
7
|
+
|
8
|
+
post '/:token' do
|
9
|
+
unless Octogate.config.token == params[:token]
|
10
|
+
status 403
|
11
|
+
body "Access forbidden"
|
12
|
+
return
|
13
|
+
end
|
14
|
+
|
15
|
+
event_name = request.env["HTTP_X_GITHUB_EVENT"]
|
16
|
+
case event_name
|
17
|
+
when "push"
|
18
|
+
event = Octogate::Event::Push.parse(params[:payload])
|
19
|
+
Octogate::Client.new(event).request_to_targets
|
20
|
+
end
|
21
|
+
|
22
|
+
return
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
module Octogate
|
2
|
+
class TargetBuilder
|
3
|
+
def initialize
|
4
|
+
@url = nil
|
5
|
+
@username = nil
|
6
|
+
@password = nil
|
7
|
+
@hook_type = [:push]
|
8
|
+
@http_method = :get
|
9
|
+
@parameter_type = :query
|
10
|
+
@match = nil
|
11
|
+
end
|
12
|
+
|
13
|
+
def url(url)
|
14
|
+
@url = url
|
15
|
+
end
|
16
|
+
|
17
|
+
def username(username)
|
18
|
+
@username = username
|
19
|
+
end
|
20
|
+
|
21
|
+
def password(password)
|
22
|
+
@password = password
|
23
|
+
end
|
24
|
+
|
25
|
+
def hook_type(types)
|
26
|
+
@hook_type = Array(types)
|
27
|
+
end
|
28
|
+
|
29
|
+
def http_method(http_method)
|
30
|
+
@http_method = http_method
|
31
|
+
end
|
32
|
+
|
33
|
+
def parameter_type(parameter_type)
|
34
|
+
@parameter_type = parameter_type
|
35
|
+
end
|
36
|
+
|
37
|
+
def match(match_proc)
|
38
|
+
@match = match_proc
|
39
|
+
end
|
40
|
+
|
41
|
+
def params(params)
|
42
|
+
@params = params
|
43
|
+
end
|
44
|
+
|
45
|
+
def __to_target__
|
46
|
+
Target.new(
|
47
|
+
url: @url,
|
48
|
+
username: @username,
|
49
|
+
password: @password,
|
50
|
+
hook_type: @hook_type,
|
51
|
+
http_method: @http_method,
|
52
|
+
parameter_type: @parameter_type,
|
53
|
+
params: @params,
|
54
|
+
match: @match,
|
55
|
+
)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
data/octogate.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'octogate/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "octogate"
|
8
|
+
spec.version = Octogate::VERSION
|
9
|
+
spec.authors = ["joker1007"]
|
10
|
+
spec.email = ["kakyoin.hierophant@gmail.com"]
|
11
|
+
spec.summary = %q{Github webhook proxy server}
|
12
|
+
spec.description = %q{Github webhook proxy server. Request target is defined by Ruby DSL}
|
13
|
+
spec.homepage = "https://github.com/joker1007/octogate"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency "sinatra"
|
22
|
+
spec.add_runtime_dependency "activesupport", ">= 4"
|
23
|
+
spec.add_runtime_dependency "oj"
|
24
|
+
spec.add_runtime_dependency "faraday"
|
25
|
+
|
26
|
+
spec.add_development_dependency "bundler", ">= 1.5"
|
27
|
+
spec.add_development_dependency "rake"
|
28
|
+
spec.add_development_dependency "rspec"
|
29
|
+
spec.add_development_dependency "tapp"
|
30
|
+
spec.add_development_dependency "awesome_print"
|
31
|
+
spec.add_development_dependency "webmock"
|
32
|
+
spec.add_development_dependency "thin"
|
33
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
token "token"
|
2
|
+
|
3
|
+
target "jenkins" do
|
4
|
+
hook_type [:push, :pull_request]
|
5
|
+
url "http://targethost.dev/job/JobName"
|
6
|
+
http_method :post
|
7
|
+
|
8
|
+
parameter_type :query
|
9
|
+
params key1: "value1", key2: "value2"
|
10
|
+
|
11
|
+
match ->(event) {
|
12
|
+
event.ref =~ /master/
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
target "jenkins2" do
|
17
|
+
hook_type [:push, :pull_request]
|
18
|
+
url "http://targethost.dev/job/JobName"
|
19
|
+
http_method :post
|
20
|
+
|
21
|
+
parameter_type :json
|
22
|
+
params key1: "value1", key2: "value2"
|
23
|
+
|
24
|
+
match ->(event) {
|
25
|
+
event.ref =~ /json_params/
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
target "block params" do
|
30
|
+
|
31
|
+
hook_type [:push, :pull_request]
|
32
|
+
url "http://targethost.dev/job/JobName"
|
33
|
+
http_method :post
|
34
|
+
|
35
|
+
parameter_type :query
|
36
|
+
params ->(event) { {ref: event.ref, head_commit_id: event.head_commit.id} }
|
37
|
+
|
38
|
+
match ->(event) {
|
39
|
+
event.ref =~ /block_parameters/
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
target "basic auth" do
|
44
|
+
hook_type [:push, :pull_request]
|
45
|
+
url "http://targethost.dev/job/JobName"
|
46
|
+
http_method :post
|
47
|
+
|
48
|
+
username "username_sample"
|
49
|
+
password "password_sample"
|
50
|
+
|
51
|
+
parameter_type :query
|
52
|
+
params key1: "value1", key2: "value2"
|
53
|
+
|
54
|
+
match ->(event) {
|
55
|
+
event.ref =~ /basic_auth/
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
target "always" do
|
60
|
+
hook_type [:push, :pull_request]
|
61
|
+
url "http://targethost.dev/job/JobName"
|
62
|
+
http_method :post
|
63
|
+
|
64
|
+
params always: "true"
|
65
|
+
end
|
66
|
+
|
67
|
+
target "never" do
|
68
|
+
hook_type [:push, :pull_request]
|
69
|
+
url "http://targethost.dev/job/JobName"
|
70
|
+
http_method :post
|
71
|
+
|
72
|
+
params never: "true"
|
73
|
+
match false
|
74
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Octogate::Client do
|
4
|
+
describe "#request_to_targets" do
|
5
|
+
let(:event) { Octogate::Event::Push.parse(push_payload) }
|
6
|
+
|
7
|
+
before do
|
8
|
+
stub_request(:post, "http://targethost.dev/job/JobName")
|
9
|
+
.to_return(:status => 200, :body => "", :headers => {})
|
10
|
+
end
|
11
|
+
|
12
|
+
after do
|
13
|
+
WebMock.reset!
|
14
|
+
end
|
15
|
+
|
16
|
+
it "request to target host" do
|
17
|
+
client = Octogate::Client.new(event)
|
18
|
+
client.request_to_targets
|
19
|
+
expect(WebMock).to have_requested(:post, "http://targethost.dev/job/JobName").with(body: {key1: "value1", key2: "value2"})
|
20
|
+
expect(WebMock).to have_requested(:post, "http://targethost.dev/job/JobName").with(body: {always: "true"})
|
21
|
+
end
|
22
|
+
|
23
|
+
it "can use event attributes on request parameter" do
|
24
|
+
event = Octogate::Event::Push.new(
|
25
|
+
ref: "refs/heads/block_parameters",
|
26
|
+
head_commit: Octogate::GH::Commit.new(id: "dummy commit id")
|
27
|
+
)
|
28
|
+
|
29
|
+
client = Octogate::Client.new(event)
|
30
|
+
client.request_to_targets
|
31
|
+
expect(WebMock).to have_requested(:post, "http://targethost.dev/job/JobName").with(body: {ref: event.ref, head_commit_id: event.head_commit.id})
|
32
|
+
end
|
33
|
+
|
34
|
+
it "request always to target that have no match rule" do
|
35
|
+
event = Octogate::Event::Push.new(
|
36
|
+
ref: "refs/heads/match_rule_nothing",
|
37
|
+
)
|
38
|
+
|
39
|
+
client = Octogate::Client.new(event)
|
40
|
+
client.request_to_targets
|
41
|
+
expect(WebMock).to have_requested(:post, "http://targethost.dev/job/JobName").with(body: {always: "true"})
|
42
|
+
end
|
43
|
+
|
44
|
+
it "never request to target that have false match rule" do
|
45
|
+
event = Octogate::Event::Push.new(
|
46
|
+
ref: "refs/heads/master",
|
47
|
+
)
|
48
|
+
|
49
|
+
client = Octogate::Client.new(event)
|
50
|
+
client.request_to_targets
|
51
|
+
expect(WebMock).not_to have_requested(:post, "http://targethost.dev/job/JobName").with(body: {never: "true"})
|
52
|
+
end
|
53
|
+
|
54
|
+
it "can request with json parameters" do
|
55
|
+
event = Octogate::Event::Push.new(
|
56
|
+
ref: "refs/heads/json_params",
|
57
|
+
)
|
58
|
+
|
59
|
+
client = Octogate::Client.new(event)
|
60
|
+
client.request_to_targets
|
61
|
+
expect(WebMock).to have_requested(:post, "http://targethost.dev/job/JobName").with(body: Oj.dump({key1: "value1", key2: "value2"}), headers: {'Content-Type' => 'application/json'})
|
62
|
+
end
|
63
|
+
|
64
|
+
it "can use basic authentication" do
|
65
|
+
stub_request(:post, "http://username_sample:password_sample@targethost.dev/job/JobName")
|
66
|
+
.to_return(:status => 200, :body => "", :headers => {})
|
67
|
+
|
68
|
+
event = Octogate::Event::Push.new(
|
69
|
+
ref: "refs/heads/basic_auth",
|
70
|
+
)
|
71
|
+
|
72
|
+
client = Octogate::Client.new(event)
|
73
|
+
client.request_to_targets
|
74
|
+
expect(WebMock).to have_requested(:post, "http://username_sample:password_sample@targethost.dev/job/JobName").with(body: {key1: "value1", key2: "value2"})
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Octogate::ConfigLoader do
|
4
|
+
describe ".load_config" do
|
5
|
+
before do
|
6
|
+
Octogate.config.token = nil
|
7
|
+
Octogate.config.targets = []
|
8
|
+
end
|
9
|
+
|
10
|
+
subject { Octogate::ConfigLoader.load_config(config_file) }
|
11
|
+
|
12
|
+
it "evaluate config on ConfigLoader instance binding" do
|
13
|
+
from_token = Octogate.config.token
|
14
|
+
from_targets = Octogate.config.targets
|
15
|
+
|
16
|
+
expect(from_token).to be_nil
|
17
|
+
expect(from_targets).to eq([])
|
18
|
+
|
19
|
+
subject
|
20
|
+
|
21
|
+
expect(Octogate.config.token).to eq("token")
|
22
|
+
expect(Octogate.config.targets).to have(6).item
|
23
|
+
expect(Octogate.config.targets.first).to be_a Octogate::Target
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Octogate::Event::Push do
|
4
|
+
describe ".parse" do
|
5
|
+
subject { described_class.parse(push_payload) }
|
6
|
+
it { should be_a described_class }
|
7
|
+
|
8
|
+
it { expect(subject.ref).to eq "refs/heads/master" }
|
9
|
+
it { expect(subject.commits).to be_a Array }
|
10
|
+
it { expect(subject.commits.first).to be_a Octogate::GH::Commit }
|
11
|
+
it { expect(subject.head_commit).to be_a Octogate::GH::Commit }
|
12
|
+
it { expect(subject.repository).to be_a Octogate::GH::Repository }
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,94 @@
|
|
1
|
+
{
|
2
|
+
"ref": "refs/heads/master",
|
3
|
+
"after": "350acda637a9f5be559144dd515641ea9bc47862",
|
4
|
+
"before": "aad61c66fa4917f184d2140052c96541aa7b867e",
|
5
|
+
"created": false,
|
6
|
+
"deleted": false,
|
7
|
+
"forced": false,
|
8
|
+
"compare": "https://github.com/joker1007/simple_note/compare/aad61c66fa49...350acda637a9",
|
9
|
+
"commits": [
|
10
|
+
{
|
11
|
+
"id": "350acda637a9f5be559144dd515641ea9bc47862",
|
12
|
+
"distinct": true,
|
13
|
+
"message": "bundle update",
|
14
|
+
"timestamp": "2014-02-28T18:52:59-08:00",
|
15
|
+
"url": "https://github.com/joker1007/simple_note/commit/350acda637a9f5be559144dd515641ea9bc47862",
|
16
|
+
"author": {
|
17
|
+
"name": "joker1007",
|
18
|
+
"email": "kakyoin.hierophant@gmail.com",
|
19
|
+
"username": "joker1007"
|
20
|
+
},
|
21
|
+
"committer": {
|
22
|
+
"name": "joker1007",
|
23
|
+
"email": "kakyoin.hierophant@gmail.com",
|
24
|
+
"username": "joker1007"
|
25
|
+
},
|
26
|
+
"added": [
|
27
|
+
|
28
|
+
],
|
29
|
+
"removed": [
|
30
|
+
|
31
|
+
],
|
32
|
+
"modified": [
|
33
|
+
"Gemfile",
|
34
|
+
"Gemfile.lock"
|
35
|
+
]
|
36
|
+
}
|
37
|
+
],
|
38
|
+
"head_commit": {
|
39
|
+
"id": "350acda637a9f5be559144dd515641ea9bc47862",
|
40
|
+
"distinct": true,
|
41
|
+
"message": "bundle update",
|
42
|
+
"timestamp": "2014-02-28T18:52:59-08:00",
|
43
|
+
"url": "https://github.com/joker1007/simple_note/commit/350acda637a9f5be559144dd515641ea9bc47862",
|
44
|
+
"author": {
|
45
|
+
"name": "joker1007",
|
46
|
+
"email": "kakyoin.hierophant@gmail.com",
|
47
|
+
"username": "joker1007"
|
48
|
+
},
|
49
|
+
"committer": {
|
50
|
+
"name": "joker1007",
|
51
|
+
"email": "kakyoin.hierophant@gmail.com",
|
52
|
+
"username": "joker1007"
|
53
|
+
},
|
54
|
+
"added": [
|
55
|
+
|
56
|
+
],
|
57
|
+
"removed": [
|
58
|
+
|
59
|
+
],
|
60
|
+
"modified": [
|
61
|
+
"Gemfile",
|
62
|
+
"Gemfile.lock"
|
63
|
+
]
|
64
|
+
},
|
65
|
+
"repository": {
|
66
|
+
"id": 15564569,
|
67
|
+
"name": "simple_note",
|
68
|
+
"url": "https://github.com/joker1007/simple_note",
|
69
|
+
"description": "Rails and Backbone sample",
|
70
|
+
"homepage": "",
|
71
|
+
"watchers": 0,
|
72
|
+
"stargazers": 0,
|
73
|
+
"forks": 0,
|
74
|
+
"fork": false,
|
75
|
+
"size": 172,
|
76
|
+
"owner": {
|
77
|
+
"name": "joker1007",
|
78
|
+
"email": "kakyoin.hierophant@gmail.com"
|
79
|
+
},
|
80
|
+
"private": false,
|
81
|
+
"open_issues": 0,
|
82
|
+
"has_issues": true,
|
83
|
+
"has_downloads": true,
|
84
|
+
"has_wiki": true,
|
85
|
+
"language": "Ruby",
|
86
|
+
"created_at": 1388583231,
|
87
|
+
"pushed_at": 1393642393,
|
88
|
+
"master_branch": "master"
|
89
|
+
},
|
90
|
+
"pusher": {
|
91
|
+
"name": "joker1007",
|
92
|
+
"email": "kakyoin.hierophant@gmail.com"
|
93
|
+
}
|
94
|
+
}
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
2
|
+
require 'octogate'
|
3
|
+
require 'tapp'
|
4
|
+
require 'webmock/rspec'
|
5
|
+
|
6
|
+
WebMock.disable_net_connect!
|
7
|
+
|
8
|
+
RSpec.configure do |config|
|
9
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
10
|
+
config.run_all_when_everything_filtered = true
|
11
|
+
config.filter_run :focus
|
12
|
+
|
13
|
+
config.order = 'random'
|
14
|
+
|
15
|
+
config.before(:suite) do
|
16
|
+
Octogate::ConfigLoader.load_config(config_file)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def push_payload
|
21
|
+
File.read(File.join(File.dirname(File.expand_path(__FILE__)), 'push_payload.json'))
|
22
|
+
end
|
23
|
+
|
24
|
+
def config_file
|
25
|
+
File.join(File.dirname(File.expand_path(__FILE__)), 'config_sample.rb')
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,237 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: octogate
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- joker1007
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-03-02 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: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '4'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '4'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: oj
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: faraday
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: bundler
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '1.5'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '1.5'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: rake
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: tapp
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ">="
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - ">="
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '0'
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
name: awesome_print
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
128
|
+
requirements:
|
129
|
+
- - ">="
|
130
|
+
- !ruby/object:Gem::Version
|
131
|
+
version: '0'
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
135
|
+
requirements:
|
136
|
+
- - ">="
|
137
|
+
- !ruby/object:Gem::Version
|
138
|
+
version: '0'
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
name: webmock
|
141
|
+
requirement: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
type: :development
|
147
|
+
prerelease: false
|
148
|
+
version_requirements: !ruby/object:Gem::Requirement
|
149
|
+
requirements:
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
name: thin
|
155
|
+
requirement: !ruby/object:Gem::Requirement
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
version: '0'
|
160
|
+
type: :development
|
161
|
+
prerelease: false
|
162
|
+
version_requirements: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
description: Github webhook proxy server. Request target is defined by Ruby DSL
|
168
|
+
email:
|
169
|
+
- kakyoin.hierophant@gmail.com
|
170
|
+
executables:
|
171
|
+
- octogate
|
172
|
+
extensions: []
|
173
|
+
extra_rdoc_files: []
|
174
|
+
files:
|
175
|
+
- ".gitignore"
|
176
|
+
- ".rspec"
|
177
|
+
- ".travis.yml"
|
178
|
+
- Gemfile
|
179
|
+
- LICENSE.txt
|
180
|
+
- Procfile.sample
|
181
|
+
- README.md
|
182
|
+
- Rakefile
|
183
|
+
- bin/octogate
|
184
|
+
- lib/octogate.rb
|
185
|
+
- lib/octogate/client.rb
|
186
|
+
- lib/octogate/config_loader.rb
|
187
|
+
- lib/octogate/configuration.rb
|
188
|
+
- lib/octogate/events.rb
|
189
|
+
- lib/octogate/events/base.rb
|
190
|
+
- lib/octogate/events/push.rb
|
191
|
+
- lib/octogate/gh.rb
|
192
|
+
- lib/octogate/gh/commit.rb
|
193
|
+
- lib/octogate/gh/repository.rb
|
194
|
+
- lib/octogate/gh/user.rb
|
195
|
+
- lib/octogate/model.rb
|
196
|
+
- lib/octogate/server.rb
|
197
|
+
- lib/octogate/target.rb
|
198
|
+
- lib/octogate/target_builder.rb
|
199
|
+
- lib/octogate/version.rb
|
200
|
+
- octogate.gemspec
|
201
|
+
- spec/config_sample.rb
|
202
|
+
- spec/lib/octogate/client_spec.rb
|
203
|
+
- spec/lib/octogate/config_loader_spec.rb
|
204
|
+
- spec/lib/octogate/events/push_spec.rb
|
205
|
+
- spec/push_payload.json
|
206
|
+
- spec/spec_helper.rb
|
207
|
+
homepage: https://github.com/joker1007/octogate
|
208
|
+
licenses:
|
209
|
+
- MIT
|
210
|
+
metadata: {}
|
211
|
+
post_install_message:
|
212
|
+
rdoc_options: []
|
213
|
+
require_paths:
|
214
|
+
- lib
|
215
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
216
|
+
requirements:
|
217
|
+
- - ">="
|
218
|
+
- !ruby/object:Gem::Version
|
219
|
+
version: '0'
|
220
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
221
|
+
requirements:
|
222
|
+
- - ">="
|
223
|
+
- !ruby/object:Gem::Version
|
224
|
+
version: '0'
|
225
|
+
requirements: []
|
226
|
+
rubyforge_project:
|
227
|
+
rubygems_version: 2.2.2
|
228
|
+
signing_key:
|
229
|
+
specification_version: 4
|
230
|
+
summary: Github webhook proxy server
|
231
|
+
test_files:
|
232
|
+
- spec/config_sample.rb
|
233
|
+
- spec/lib/octogate/client_spec.rb
|
234
|
+
- spec/lib/octogate/config_loader_spec.rb
|
235
|
+
- spec/lib/octogate/events/push_spec.rb
|
236
|
+
- spec/push_payload.json
|
237
|
+
- spec/spec_helper.rb
|