octogate 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
[](https://travis-ci.org/joker1007/octogate)
|
3
|
+
[](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
|