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.
@@ -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
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.1.1
4
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in octogate.gemspec
4
+ gemspec
@@ -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.
@@ -0,0 +1 @@
1
+ web: bundle exec octogate -c ./config.rb -p $PORT
@@ -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
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
@@ -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)
@@ -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,13 @@
1
+ require "singleton"
2
+
3
+ module Octogate
4
+ class Configuration
5
+ include Singleton
6
+ attr_accessor :targets, :token, :ca_file, :ssl_verify
7
+
8
+ def initialize
9
+ @targets ||= []
10
+ @ssl_verify = true
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ module Octogate
2
+ module Event
3
+ end
4
+ end
5
+
6
+ require "octogate/events/base"
7
+ require "octogate/events/push"
@@ -0,0 +1,9 @@
1
+ module Octogate
2
+ class Event::Base
3
+ include Octogate::Model
4
+
5
+ def default_condition
6
+ true
7
+ end
8
+ end
9
+ 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
@@ -0,0 +1,8 @@
1
+ module Octogate
2
+ module GH
3
+ end
4
+ end
5
+
6
+ require "octogate/gh/commit"
7
+ require "octogate/gh/repository"
8
+ require "octogate/gh/user"
@@ -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,7 @@
1
+ module Octogate
2
+ class GH::User
3
+ include Model
4
+
5
+ attr_reader :name, :email, :username
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ module Octogate::Model
2
+ def initialize(**args)
3
+ args.each do |k, v|
4
+ send("instance_variable_set", "@#{k}", v)
5
+ end
6
+ end
7
+ 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,7 @@
1
+ module Octogate
2
+ class Target
3
+ include Model
4
+
5
+ attr_reader :url, :username, :password, :hook_type, :http_method, :parameter_type, :params, :match
6
+ end
7
+ 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
@@ -0,0 +1,3 @@
1
+ module Octogate
2
+ VERSION = "0.1.0"
3
+ end
@@ -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
+ }
@@ -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