github-event-watcher 1.0.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: fbbc0e39a43cb1d647f242f828e71aa38577e32e
4
+ data.tar.gz: 1c1d8274a79420feb01506eca2f121adad53e737
5
+ SHA512:
6
+ metadata.gz: d49f46fc9782cc848954fb4bdc80a6aa1eca0f3a82cfbfc6f9e893eef3ff019c13acb7b4e9e3d079b069105de807a32e7bd4388a5d0fba94281d49d8d25f930d
7
+ data.tar.gz: 2418a9cac647a5d83945d61298515e8447d879d39861689c1d0b40102c5bbf702a49d88904bbc2f1982711488e2cb195e1018eab633bf3d52114583750dbef9d
@@ -0,0 +1,2 @@
1
+ /config.yaml
2
+ /var/
@@ -0,0 +1,8 @@
1
+ rvm:
2
+ - 2.0.0
3
+ - 2.1
4
+ - 2.2
5
+ notifications:
6
+ email:
7
+ recipients:
8
+ - commit@clear-code.com
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,48 @@
1
+ [![Build Status](https://travis-ci.org/clear-code/github-event-watcher.svg?branch=master)](https://travis-ci.org/clear-code/github-event-watcher)
2
+
3
+ # README
4
+
5
+ ## Name
6
+
7
+ github-event-watcher
8
+
9
+ ## Description
10
+
11
+ This package is for developers who want to watch GitHub repositories
12
+ of other people. You can't set
13
+ [GitHub Webhooks](https://developer.github.com/webhooks/) for GitHub
14
+ repositories of other people.
15
+
16
+ This package pulls events from GitHub and sends GitHub compatible
17
+ (subset) POST request to your Webhooks.
18
+
19
+ You can implement commit mail by using with
20
+ [GitHub POST receiver at clear-code/git-utils](https://github.com/clear-code/git-utils/tree/master/github-post-receiver).
21
+
22
+ ## Usage
23
+
24
+ % git clone https://github.com/clear-code/git-utils.git
25
+ % cd github-event-watcher
26
+ % cp config.yaml{.example,}
27
+ % editor config.yaml
28
+ % ruby -I lib bin/github-pull-push-events --daemon
29
+
30
+ `config.yaml` uses the following format:
31
+
32
+ repositories:
33
+ - clear-code/git-utils
34
+ - ruby/ruby
35
+ - rails/rails
36
+ webhook-end-point: http://git-utils.example.com/post-receiver/
37
+
38
+ List repositories by `${owner}/${name}` format into `repositories`.
39
+
40
+ Specify your GitHub Webhook receiver URL to `webhook-end-point`.
41
+
42
+ ## Authors
43
+
44
+ * Kouhei Sutou `<kou@clear-code.com>`
45
+
46
+ ## License
47
+
48
+ GPLv3 or later.
@@ -0,0 +1,23 @@
1
+ # Copyright (C) 2012-2013 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require "bundler/gem_tasks"
17
+
18
+ task :default => :test
19
+
20
+ desc "Run test"
21
+ task :test do
22
+ ruby("test/run-test.rb")
23
+ end
@@ -0,0 +1,21 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # Copyright (C) 2014 Kouhei Sutou <kou@clear-code.com>
4
+ #
5
+ # This program is free software: you can redistribute it and/or modify
6
+ # it under the terms of the GNU General Public License as published by
7
+ # the Free Software Foundation, either version 3 of the License, or
8
+ # (at your option) any later version.
9
+ #
10
+ # This program is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
+ # GNU General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU General Public License
16
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
17
+
18
+ require "github-event-watcher"
19
+
20
+ command = GitHubEventWatcher::Command::GitHubPullPushEvents.new
21
+ exit(command.run)
@@ -0,0 +1,4 @@
1
+ repositories:
2
+ - clear-code/git-utils
3
+ - ruby/ruby
4
+ webhook-end-point: http://git-utils.example.com/post-receiver/
@@ -0,0 +1,25 @@
1
+ lib = File.expand_path('../lib', __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+ require 'github-event-watcher/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = "github-event-watcher"
7
+ spec.version = GitHubEventWatcher::VERSION
8
+ spec.authors = ["Kouhei Sutou"]
9
+ spec.email = ["kou@clear-code.com"]
10
+ spec.summary = %q{GitHub event watcher}
11
+ spec.description = %q{GitHub event watcher}
12
+ spec.homepage = ""
13
+ spec.license = "GPL-3.0+"
14
+
15
+ spec.files = `git ls-files -z`.split("\x0")
16
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
17
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
18
+ spec.require_paths = ["lib"]
19
+
20
+ spec.add_development_dependency "bundler"
21
+ spec.add_development_dependency "rake", "~> 10.0"
22
+ spec.add_development_dependency "test-unit"
23
+ spec.add_development_dependency "test-unit-rr"
24
+ spec.add_development_dependency "test-unit-capybara"
25
+ end
@@ -0,0 +1,22 @@
1
+ # Copyright (C) 2014 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require "github-event-watcher/event"
17
+ require "github-event-watcher/persistent-state"
18
+ require "github-event-watcher/version"
19
+ require "github-event-watcher/watcher"
20
+ require "github-event-watcher/webhook-sender"
21
+
22
+ require "github-event-watcher/command/github-pull-push-events"
@@ -0,0 +1,179 @@
1
+ # Copyright (C) 2014 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require "optparse"
17
+ require "fileutils"
18
+ require "pathname"
19
+ require "time"
20
+ require "logger"
21
+ require "yaml"
22
+
23
+ require "github-event-watcher"
24
+
25
+ module GitHubEventWatcher
26
+ module Command
27
+ class GitHubPullPushEvents
28
+ def initialize
29
+ @state_dir = Pathname.new("var/lib")
30
+ @log_dir = Pathname.new("var/log")
31
+ @config_file = Pathname.new("config.yaml")
32
+ @pid_file = Pathname.new("var/run/github-pull-push-events.pid")
33
+ @daemonize = false
34
+ end
35
+
36
+ def run(argv=ARGV)
37
+ parse_command_line!(argv)
38
+ expand_paths
39
+ start_watcher
40
+ true
41
+ end
42
+
43
+ private
44
+ def parse_command_line!(argv)
45
+ parser = OptionParser.new
46
+ parser.version = VERSION
47
+ parser.on("--state-dir=DIR",
48
+ "The directory to store state file",
49
+ "(#{@state_dir})") do |dir|
50
+ @state_dir = Pathname.new(dir)
51
+ end
52
+ parser.on("--log-dir=DIR",
53
+ "The directory to store logs",
54
+ "(#{@log_dir})") do |dir|
55
+ @log_dir = Pathname.new(dir)
56
+ end
57
+ parser.on("--config-file=FILE",
58
+ "The config file in YAML",
59
+ "(#{@config_file})") do |file|
60
+ @config_file = Pathname.new(file)
61
+ end
62
+ parser.on("--pid-file=FILE",
63
+ "The PID file",
64
+ "(#{@pid_file})") do |file|
65
+ @pid_file = Pathname.new(file)
66
+ end
67
+ parser.on("--[no-]daemonize",
68
+ "Run as a daemon",
69
+ "(#{@daemonize})") do |boolean|
70
+ @daemonize = boolean
71
+ end
72
+ parser.parse!(argv)
73
+ end
74
+
75
+ def expand_paths
76
+ @state_dir = @state_dir.expand_path
77
+ @log_dir = @log_dir.expand_path
78
+ @config_file = @config_file.expand_path
79
+ @pid_file = @pid_file.expand_path
80
+ end
81
+
82
+ def start_watcher
83
+ state = create_state
84
+ logger = create_logger
85
+ watcher = Watcher.new(state, logger)
86
+ config = load_config
87
+ config["repositories"].each do |repository|
88
+ watcher.add_repository(repository)
89
+ end
90
+ webhook_end_point = URI.parse(config["webhook-end-point"])
91
+ webhook_sender = WebhookSender.new(webhook_end_point, logger)
92
+
93
+ setup_signals(watcher)
94
+
95
+ if @daemonize
96
+ Process.daemon
97
+ $stdout = create_io_logger("stdout")
98
+ $stderr = create_io_logger("stderr")
99
+ at_exit do
100
+ $stdout.flush
101
+ $stderr.flush
102
+ end
103
+ end
104
+ create_pid_file
105
+
106
+ begin
107
+ watcher.watch do |event|
108
+ next if event.type != "PushEvent"
109
+ webhook_sender.send_push_event(event)
110
+ end
111
+ ensure
112
+ remove_pid_file
113
+ end
114
+
115
+ logger.close
116
+ end
117
+
118
+ def create_state
119
+ FileUtils.mkdir_p(@state_dir.to_s)
120
+ PersistentState.new(@state_dir + "state.yaml")
121
+ end
122
+
123
+ def create_logger(type=nil)
124
+ FileUtils.mkdir_p(@log_dir.to_s)
125
+ components = ["github-pull-push-events", type, "log"].compact
126
+ log_file = @log_dir + components.join(".")
127
+ logger = Logger.new(log_file.to_s, 10, 1024 ** 2)
128
+ logger.level = Logger::INFO
129
+ logger.formatter = lambda do |severity, timestamp, program_name, message|
130
+ "#{timestamp.iso8601}[#{severity.downcase}] #{message}\n"
131
+ end
132
+ logger
133
+ end
134
+
135
+ def create_io_logger(type)
136
+ logger = create_logger(type)
137
+ logger.level = Logger::DEBUG
138
+ class << logger
139
+ def write(message)
140
+ message = message.strip
141
+ return if message.empty?
142
+ debug(message)
143
+ end
144
+
145
+ def flush
146
+ return if @logdev.nil?
147
+ @logdev.dev.flush
148
+ end
149
+ end
150
+ logger
151
+ end
152
+
153
+ def load_config
154
+ YAML.load(@config_file.read)
155
+ end
156
+
157
+ def setup_signals(watcher)
158
+ trap(:INT) do
159
+ watcher.stop
160
+ end
161
+ trap(:TERM) do
162
+ watcher.stop
163
+ end
164
+ end
165
+
166
+ def create_pid_file
167
+ FileUtils.mkdir_p(@pid_file.dirname.to_s)
168
+ @pid_file.open("w") do |pid_file|
169
+ pid_file.print(Process.pid)
170
+ end
171
+ end
172
+
173
+ def remove_pid_file
174
+ return unless @pid_file.exist?
175
+ FileUtils.rm_f(@pid_file.to_s)
176
+ end
177
+ end
178
+ end
179
+ end
@@ -0,0 +1,55 @@
1
+ # Copyright (C) 2014 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ module GitHubEventWatcher
17
+ class Event
18
+ def initialize(data)
19
+ @data = data
20
+ @repository = @data["repo"]
21
+ end
22
+
23
+ def id
24
+ Integer(@data["id"])
25
+ end
26
+
27
+ def type
28
+ @data["type"]
29
+ end
30
+
31
+ def payload
32
+ @data["payload"]
33
+ end
34
+
35
+ def repository_url
36
+ "https://github.com/#{repository_full_name}"
37
+ end
38
+
39
+ def repository_owner
40
+ owner, name = repository_full_name.split("/", 2)
41
+ _ = name # For suppressing a warning
42
+ owner
43
+ end
44
+
45
+ def repository_name
46
+ owner, name = repository_full_name.split("/", 2)
47
+ _ = owner # For suppressing a warning
48
+ name
49
+ end
50
+
51
+ def repository_full_name
52
+ @repository["name"]
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,53 @@
1
+ # Copyright (C) 2014 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require "yaml"
17
+
18
+ module GitHubEventWatcher
19
+ class PersistentState
20
+ def initialize(path)
21
+ @path = path
22
+ load
23
+ end
24
+
25
+ def processed_event_id(repository_name)
26
+ repository(repository_name)["processed-event-id"] || 0
27
+ end
28
+
29
+ def update_processed_event_id(repository_name, id)
30
+ repository(repository_name)["processed-event-id"] = id
31
+ save
32
+ end
33
+
34
+ private
35
+ def repository(name)
36
+ @repositories[name] ||= {}
37
+ end
38
+
39
+ def load
40
+ if @path.exist?
41
+ @repositories = YAML.load(@path.read)
42
+ else
43
+ @repositories = {}
44
+ end
45
+ end
46
+
47
+ def save
48
+ @path.open("w") do |file|
49
+ file.print(@repositories.to_yaml)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,18 @@
1
+ # Copyright (C) 2014 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ module GitHubEventWatcher
17
+ VERSION = "1.0.0"
18
+ end
@@ -0,0 +1,88 @@
1
+ # Copyright (C) 2014-2015 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require "open-uri"
17
+ require "json"
18
+
19
+ require "github-event-watcher/event"
20
+
21
+ module GitHubEventWatcher
22
+ class Watcher
23
+ NOTIFY_MESSAGE = "X"
24
+
25
+ def initialize(state, logger)
26
+ @repositories = []
27
+ @state = state
28
+ @logger = logger
29
+ @running = true
30
+ @notify_pipe = IO.pipe
31
+ end
32
+
33
+ def add_repository(name)
34
+ @logger.info("[watcher][repository] add: <#{name}>")
35
+ @repositories << name
36
+ end
37
+
38
+ def watch
39
+ i = 0
40
+ while @running
41
+ name = @repositories[i]
42
+ events = fetch_events(name)
43
+ processed_event_id = @state.processed_event_id(name)
44
+ events = remove_processed_events(events, processed_event_id)
45
+ @logger.info("[watcher][watch][#{name}] target events: <#{events.size}>")
46
+ sorted_events = events.sort_by do |event|
47
+ event.id
48
+ end
49
+ sorted_events.each do |event|
50
+ yield(event)
51
+ end
52
+ latest_event = sorted_events.last
53
+ if latest_event
54
+ @logger.info("[watcher][watch][#{name}] last processed event ID: " +
55
+ "<#{latest_event.id}>")
56
+ @state.update_processed_event_id(name, latest_event.id)
57
+ end
58
+ readables, = IO.select([@notify_pipe[0]], nil, nil, 60)
59
+ readables[0].read(NOTIFY_MESSAGE.size) if readables
60
+ i = (i + 1) % @repositories.size
61
+ end
62
+ end
63
+
64
+ def stop
65
+ @running = false
66
+ @notify_pipe[1].write(NOTIFY_MESSAGE)
67
+ end
68
+
69
+ private
70
+ def fetch_events(name)
71
+ open("https://api.github.com/repos/#{name}/events") do |body|
72
+ JSON.parse(body.read).collect do |event|
73
+ Event.new(event)
74
+ end
75
+ end
76
+ rescue OpenURI::HTTPError, SystemCallError, Timeout::Error
77
+ tag = "[watcher][watch][#{name}][fetch]"
78
+ @logger.error("#{tag} Failed to fetch: #{$!.class}: #{$!.message}")
79
+ []
80
+ end
81
+
82
+ def remove_processed_events(events, processed_event_id)
83
+ events.reject do |event|
84
+ event.id <= processed_event_id
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,74 @@
1
+ # Copyright (C) 2014 Kouhei Sutou <kou@clear-code.com>
2
+ #
3
+ # This program is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # This program is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU General Public License
14
+ # along with this program. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require "net/http"
17
+ require "json"
18
+
19
+ module GitHubEventWatcher
20
+ class WebhookSender
21
+ def initialize(end_point, logger)
22
+ @end_point = end_point
23
+ @logger = logger
24
+ @logger.info("[webhook-sender][end-point] <#{@end_point}>")
25
+ end
26
+
27
+ def send_push_event(event)
28
+ @logger.info("[webhook-sender][send][push] " +
29
+ "<#{event.id}>:<#{event.repository_full_name}>")
30
+ options = {
31
+ :use_ssl => (@end_point.scheme == "https"),
32
+ }
33
+ begin
34
+ Net::HTTP.start(@end_point.host, @end_point.port, options) do |http|
35
+ request = Net::HTTP::Post.new(@end_point.request_uri)
36
+ request["Host"] = @end_point.hostname
37
+ request["X-GitHub-Event"] = "push"
38
+ request["Content-Type"] = "application/json"
39
+ request["User-Agent"] = "GitHub Event Watcher/1.0"
40
+ request.body = JSON.generate(convert_to_push_event_payload(event))
41
+ response = http.request(request)
42
+ log_tag = "[webhook-sender][sent][push]"
43
+ case response
44
+ when Net::HTTPSuccess
45
+ @logger.info("#{log_tag}[success]")
46
+ else
47
+ @logger.error("#{log_tag}[error] <#{response.code}>")
48
+ end
49
+ end
50
+ rescue SystemCallError, Timeout::Error
51
+ tag = "[webhook-sender][send][push][error]"
52
+ message = "#{tag} Failed to send push event: #{$!.class}: #{$!.message}"
53
+ @logger.error(message)
54
+ end
55
+ end
56
+
57
+ private
58
+ def convert_to_push_event_payload(event)
59
+ {
60
+ "ref" => event.payload["ref"],
61
+ "before" => event.payload["before"],
62
+ "after" => event.payload["head"],
63
+ "repository" => {
64
+ "url" => event.repository_url,
65
+ "name" => event.repository_name,
66
+ "full_name" => event.repository_full_name,
67
+ "owner" => {
68
+ "name" => event.repository_owner,
69
+ },
70
+ },
71
+ }
72
+ end
73
+ end
74
+ end
metadata ADDED
@@ -0,0 +1,130 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: github-event-watcher
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Kouhei Sutou
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-03-25 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
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: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: test-unit
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
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: test-unit-rr
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
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: test-unit-capybara
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ description: GitHub event watcher
84
+ email:
85
+ - kou@clear-code.com
86
+ executables:
87
+ - github-pull-push-events
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - ".gitignore"
92
+ - ".travis.yml"
93
+ - Gemfile
94
+ - README.md
95
+ - Rakefile
96
+ - bin/github-pull-push-events
97
+ - config.yaml.example
98
+ - github-event-watcher.gemspec
99
+ - lib/github-event-watcher.rb
100
+ - lib/github-event-watcher/command/github-pull-push-events.rb
101
+ - lib/github-event-watcher/event.rb
102
+ - lib/github-event-watcher/persistent-state.rb
103
+ - lib/github-event-watcher/version.rb
104
+ - lib/github-event-watcher/watcher.rb
105
+ - lib/github-event-watcher/webhook-sender.rb
106
+ homepage: ''
107
+ licenses:
108
+ - GPL-3.0+
109
+ metadata: {}
110
+ post_install_message:
111
+ rdoc_options: []
112
+ require_paths:
113
+ - lib
114
+ required_ruby_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ required_rubygems_version: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ requirements: []
125
+ rubyforge_project:
126
+ rubygems_version: 2.4.5
127
+ signing_key:
128
+ specification_version: 4
129
+ summary: GitHub event watcher
130
+ test_files: []