omg_pull_request 0.0.6
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.
- data/.gitignore +47 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +68 -0
- data/LICENSE +22 -0
- data/README.md +66 -0
- data/Rakefile +12 -0
- data/bin/omg_pull_request +13 -0
- data/lib/omg_pull_request.rb +32 -0
- data/lib/omg_pull_request/aws/store.rb +30 -0
- data/lib/omg_pull_request/configuration.rb +55 -0
- data/lib/omg_pull_request/context.rb +29 -0
- data/lib/omg_pull_request/git_client.rb +31 -0
- data/lib/omg_pull_request/github_wrapper.rb +50 -0
- data/lib/omg_pull_request/lolcommits.rb +39 -0
- data/lib/omg_pull_request/notifications.rb +66 -0
- data/lib/omg_pull_request/prowl.rb +77 -0
- data/lib/omg_pull_request/test_logger.rb +20 -0
- data/lib/omg_pull_request/test_runner.rb +22 -0
- data/lib/omg_pull_request/test_runner/base.rb +128 -0
- data/lib/omg_pull_request/test_runner/rails.rb +19 -0
- data/lib/omg_pull_request/test_runner/ruby.rb +9 -0
- data/lib/omg_pull_request/version.rb +3 -0
- data/locales/en.yml +23 -0
- data/locales/omg.yml +20 -0
- data/omg_pull_request.gemspec +26 -0
- data/test/fixtures/comments +431 -0
- data/test/fixtures/config.yml +20 -0
- data/test/fixtures/create_comment +24 -0
- data/test/fixtures/github_commits +183 -0
- data/test/fixtures/kenmazaika +30 -0
- data/test/fixtures/pull_requests +151 -0
- data/test/mocks/git_client.rb +6 -0
- data/test/mocks/pull_request.rb +38 -0
- data/test/omg_pull_request/.gitkeep +0 -0
- data/test/test_helper.rb +53 -0
- data/test/units/omg_pull_request/aws/store_test.rb +22 -0
- data/test/units/omg_pull_request/github_wrapper_test.rb +43 -0
- data/test/units/omg_pull_request/lolcommits_test.rb +42 -0
- data/test/units/omg_pull_request/notifications_test.rb +125 -0
- data/test/units/omg_pull_request/prowl_test.rb +51 -0
- data/test/units/omg_pull_request/test_runner/base_test.rb +58 -0
- metadata +183 -0
data/.gitignore
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
2
|
+
#
|
3
|
+
# If you find yourself ignoring temporary files generated by your text editor
|
4
|
+
# or operating system, you probably want to add a global ignore instead:
|
5
|
+
# git config --global core.excludesfile ~/.gitignore_global
|
6
|
+
|
7
|
+
# Ignore bundler config
|
8
|
+
/.bundle
|
9
|
+
|
10
|
+
# Ignore the default SQLite database.
|
11
|
+
/db/*.sqlite3
|
12
|
+
|
13
|
+
# Ignore all logfiles and tempfiles.
|
14
|
+
/log/*.log
|
15
|
+
/tmp
|
16
|
+
.DS_Store
|
17
|
+
*.rb.pid
|
18
|
+
|
19
|
+
# Assets are precompiled on deploy
|
20
|
+
/public/assets
|
21
|
+
|
22
|
+
# Coverage directory should not be checked in
|
23
|
+
/coverage
|
24
|
+
|
25
|
+
# PEOPLE WHO USE VIM ROCK!
|
26
|
+
*.swp
|
27
|
+
*.swo
|
28
|
+
.swp
|
29
|
+
.swo
|
30
|
+
*.swn
|
31
|
+
*.swm
|
32
|
+
|
33
|
+
test/functional/coverage/**
|
34
|
+
test/unit/coverage/**
|
35
|
+
test/functional/advertisers/coverage/**
|
36
|
+
.cache_rake_t
|
37
|
+
.idea/**
|
38
|
+
public/system
|
39
|
+
.sass-cache
|
40
|
+
|
41
|
+
# Allow using Turn for testing, but don't check in configuration
|
42
|
+
config/initializers/turn.rb
|
43
|
+
config/initializers/error_mass_assign.rb
|
44
|
+
config/initializers/activeresource_debug.rb
|
45
|
+
tags
|
46
|
+
.rbenv-version
|
47
|
+
test/omg_pull_request/config.yml
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
omg_pull_request (0.0.6)
|
5
|
+
activesupport (>= 3.2.8)
|
6
|
+
aws-s3 (>= 0.6.3)
|
7
|
+
faraday (>= 0.8.4)
|
8
|
+
github_api (>= 0.6.5)
|
9
|
+
i18n (>= 0.6.0)
|
10
|
+
rake (>= 0.9.2.2)
|
11
|
+
uuid (>= 2.3.5)
|
12
|
+
|
13
|
+
GEM
|
14
|
+
remote: http://rubygems.org/
|
15
|
+
specs:
|
16
|
+
activesupport (3.2.8)
|
17
|
+
i18n (~> 0.6)
|
18
|
+
multi_json (~> 1.0)
|
19
|
+
aws-s3 (0.6.3)
|
20
|
+
builder
|
21
|
+
mime-types
|
22
|
+
xml-simple
|
23
|
+
builder (3.0.0)
|
24
|
+
fakeweb (1.3.0)
|
25
|
+
faraday (0.8.4)
|
26
|
+
multipart-post (~> 1.1)
|
27
|
+
github_api (0.6.5)
|
28
|
+
faraday (~> 0.8.1)
|
29
|
+
hashie (~> 1.2.0)
|
30
|
+
multi_json (~> 1.3)
|
31
|
+
nokogiri (~> 1.5.2)
|
32
|
+
oauth2
|
33
|
+
hashie (1.2.0)
|
34
|
+
httpauth (0.1)
|
35
|
+
i18n (0.6.0)
|
36
|
+
jwt (0.1.5)
|
37
|
+
multi_json (>= 1.0)
|
38
|
+
macaddr (1.6.1)
|
39
|
+
systemu (~> 2.5.0)
|
40
|
+
metaclass (0.0.1)
|
41
|
+
mime-types (1.19)
|
42
|
+
minitest (3.3.0)
|
43
|
+
mocha (0.11.4)
|
44
|
+
metaclass (~> 0.0.1)
|
45
|
+
multi_json (1.3.6)
|
46
|
+
multipart-post (1.1.5)
|
47
|
+
nokogiri (1.5.5)
|
48
|
+
oauth2 (0.8.0)
|
49
|
+
faraday (~> 0.8)
|
50
|
+
httpauth (~> 0.1)
|
51
|
+
jwt (~> 0.1.4)
|
52
|
+
multi_json (~> 1.0)
|
53
|
+
rack (~> 1.2)
|
54
|
+
rack (1.4.1)
|
55
|
+
rake (0.9.2.2)
|
56
|
+
systemu (2.5.2)
|
57
|
+
uuid (2.3.5)
|
58
|
+
macaddr (~> 1.0)
|
59
|
+
xml-simple (1.1.1)
|
60
|
+
|
61
|
+
PLATFORMS
|
62
|
+
ruby
|
63
|
+
|
64
|
+
DEPENDENCIES
|
65
|
+
fakeweb
|
66
|
+
minitest
|
67
|
+
mocha
|
68
|
+
omg_pull_request!
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Ken Mazaika
|
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/README.md
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
## Omg! Pull Request!
|
2
|
+
|
3
|
+
Omg! Pull Request! is a daemon designed to easily run automated tests for a project that is hosted on GitHub on the submission of a pull request. On completion of the tests the daemon will make a comment on the pull request on the status of the test suite.
|
4
|
+
|
5
|
+
#### Goals
|
6
|
+
|
7
|
+
* Allow simple configuration for a standard rails project
|
8
|
+
* Support flexibilty and extensibility to work in non ruby/rails projects
|
9
|
+
* Reduce test failures caused by merging in code with broken tests
|
10
|
+
|
11
|
+
#### Non Goals
|
12
|
+
|
13
|
+
* Work with non-github environments
|
14
|
+
|
15
|
+
|
16
|
+
### Integrations
|
17
|
+
|
18
|
+
The project integrates with a number of third party services to maximize usefulness / coolness.
|
19
|
+
|
20
|
+
#### Prowl
|
21
|
+
|
22
|
+
Prowl integration allows you to setup a phone to be alerted when the test suite completes. You will be alerted if you are the author, or have commited in the pull request.
|
23
|
+
|
24
|
+
#### Lolcommits
|
25
|
+
|
26
|
+
On running the test suite an animated gif can be generated of the lolcommits that were generated by the pull request. This feature was added for the lulz.
|
27
|
+
|
28
|
+
## Installation
|
29
|
+
|
30
|
+
1. In a rails project, add `omg_pull_request` to the Gemfile.
|
31
|
+
2. Make an `omg_pull_request` directory in the project's `test` directory.
|
32
|
+
3. Add a `database.yml` file in the `omg_pull_request` dir. This will drop databases, so it is suggested this points to different databases than the main `config/database.yml` file
|
33
|
+
4. Create a github user to run the tests as. This user will need to have access to the repo the test is run on. It can be your developer account, or a new account specifically for this.
|
34
|
+
5. Add a `config.yml` file in the `omg_pull_request` dir. It follows this template:
|
35
|
+
|
36
|
+
```
|
37
|
+
repo_owner: kenmazaika
|
38
|
+
repo: pictures
|
39
|
+
locale: en
|
40
|
+
runner: Rails
|
41
|
+
|
42
|
+
github_credentials:
|
43
|
+
login: github_user
|
44
|
+
password: github_password
|
45
|
+
|
46
|
+
aws:
|
47
|
+
access_token: s3_token
|
48
|
+
secret_token: s3_secret
|
49
|
+
bucket: s3_bucket
|
50
|
+
|
51
|
+
prowl:
|
52
|
+
application: wherebot
|
53
|
+
keys:
|
54
|
+
kenmazaika: key
|
55
|
+
kenmazaika@gmail.com: key
|
56
|
+
```
|
57
|
+
|
58
|
+
This is a sample config, with sensitive data scrubbed for running tests on the repo: https://github.com/kenmazaika/pictures. One important note is for the prowl integration it should contain a key for both the github user_name and the email address that can be pulled from git.
|
59
|
+
|
60
|
+
6. On a server someplace clone the repo. This cloned repo will be managed by the daemon, and the tests will run on it from now on.
|
61
|
+
7. In a screen session run `omg_pull_request`.
|
62
|
+
8. Enjoy.
|
63
|
+
|
64
|
+
### Example
|
65
|
+
|
66
|
+
You can see an example of a successful pull request that has been `omg_pull_request`ified here: https://github.com/where/omg_pull_request/pull/1.
|
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'omg_pull_request'
|
4
|
+
|
5
|
+
include OmgPullRequest
|
6
|
+
locale_dir = File.expand_path("../../locales", __FILE__)
|
7
|
+
I18n.load_path = [
|
8
|
+
File.join(locale_dir, "omg.yml"),
|
9
|
+
File.join(locale_dir, "en.yml")
|
10
|
+
]
|
11
|
+
I18n.locale = CONFIGURATION.locale if CONFIGURATION.locale
|
12
|
+
|
13
|
+
TestRunner.start_daemon
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
require 'active_support/all'
|
4
|
+
require 'faraday'
|
5
|
+
require 'github_api'
|
6
|
+
require 'yaml'
|
7
|
+
require 'uuid'
|
8
|
+
require 'aws/s3'
|
9
|
+
require 'i18n'
|
10
|
+
require 'omg_pull_request/configuration'
|
11
|
+
require 'omg_pull_request/test_logger'
|
12
|
+
require 'omg_pull_request/aws/store'
|
13
|
+
require 'omg_pull_request/github_wrapper'
|
14
|
+
require 'omg_pull_request/notifications'
|
15
|
+
require 'omg_pull_request/test_runner'
|
16
|
+
require 'omg_pull_request/test_runner/base'
|
17
|
+
require 'omg_pull_request/test_runner/rails'
|
18
|
+
require 'omg_pull_request/test_runner/ruby'
|
19
|
+
require 'omg_pull_request/context'
|
20
|
+
require 'omg_pull_request/git_client'
|
21
|
+
require 'omg_pull_request/prowl'
|
22
|
+
require 'omg_pull_request/lolcommits'
|
23
|
+
require 'omg_pull_request/version'
|
24
|
+
|
25
|
+
module OmgPullRequest
|
26
|
+
CONFIGURATION = Configuration.new
|
27
|
+
STORE = Aws::Store.new(:storage_config => CONFIGURATION.aws.symbolize_keys)
|
28
|
+
CONTEXT = Context.new
|
29
|
+
GITHUB_WRAPPER = GithubWrapper.new(:configuration => CONFIGURATION)
|
30
|
+
end
|
31
|
+
|
32
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module OmgPullRequest
|
2
|
+
module Aws
|
3
|
+
class Store
|
4
|
+
attr_accessor :storage_config
|
5
|
+
def initialize(attributes={})
|
6
|
+
attributes.each do |attr, value|
|
7
|
+
self.send("#{attr}=", value)
|
8
|
+
end
|
9
|
+
|
10
|
+
AWS::S3::Base.establish_connection!(
|
11
|
+
:access_key_id => access_token,
|
12
|
+
:secret_access_key => secret_token
|
13
|
+
)
|
14
|
+
end
|
15
|
+
|
16
|
+
def store(data, file_name)
|
17
|
+
AWS::S3::S3Object.store(file_name, data, bucket, :access => :public_read)
|
18
|
+
"http://s3.amazonaws.com/#{bucket}/#{file_name}"
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
[:access_token, :secret_token, :bucket].each do |attr|
|
24
|
+
define_method attr do
|
25
|
+
storage_config[attr]
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
module OmgPullRequest
|
2
|
+
class Configuration
|
3
|
+
attr_reader :config
|
4
|
+
|
5
|
+
def initialize(attributes={})
|
6
|
+
attributes.each do |attr, value|
|
7
|
+
self.send("#{attr}=", value)
|
8
|
+
end
|
9
|
+
@config = YAML.load(File.open(self.config_file))
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
[:repo_owner, :repo, :database_yml, :aws, :github_credentials,
|
14
|
+
:lolcommits_server_url, :prowl, :locale].each do |attr|
|
15
|
+
define_method attr do
|
16
|
+
self.config[attr.to_s]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def local_repo
|
21
|
+
self.config['local_repo'] || Dir.pwd
|
22
|
+
end
|
23
|
+
|
24
|
+
def database_yml
|
25
|
+
self.config['database_yml'] || File.join(omg_dir, 'database.yml')
|
26
|
+
end
|
27
|
+
|
28
|
+
def config_file
|
29
|
+
file = ENV['yml'] || File.join(omg_dir, 'config.yml')
|
30
|
+
unless File.exist?(file)
|
31
|
+
raise "Configuration file does not exist: #{file}"
|
32
|
+
end
|
33
|
+
|
34
|
+
file
|
35
|
+
end
|
36
|
+
|
37
|
+
def omg_dir
|
38
|
+
File.join(Dir.pwd, 'test/omg_pull_request')
|
39
|
+
end
|
40
|
+
|
41
|
+
def runner_class
|
42
|
+
"OmgPullRequest::TestRunner::#{config['runner'] || 'Rails'}".constantize
|
43
|
+
end
|
44
|
+
|
45
|
+
module Helpers
|
46
|
+
def delegate_config_to(config, *attrs)
|
47
|
+
attrs.each do |attr|
|
48
|
+
define_method attr do
|
49
|
+
self.send(config).send(attr)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module OmgPullRequest
|
2
|
+
class Context
|
3
|
+
def ran(request_sha)
|
4
|
+
ran_hash[request_sha] = true
|
5
|
+
end
|
6
|
+
|
7
|
+
def ran?(request_sha)
|
8
|
+
ran_hash[request_sha] == true
|
9
|
+
end
|
10
|
+
|
11
|
+
def get_animated_shas(issue_number)
|
12
|
+
animated_shas[issue_number] || []
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_animated_shas(issue_number, shas)
|
16
|
+
animated_shas[issue_number] = get_animated_shas(issue_number) + shas
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def ran_hash
|
22
|
+
@ran_hash ||= Hash.new
|
23
|
+
end
|
24
|
+
|
25
|
+
def animated_shas
|
26
|
+
@animated_sha || Hash.new
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module OmgPullRequest
|
2
|
+
class GitClient
|
3
|
+
attr_accessor :logger, :configuration
|
4
|
+
|
5
|
+
def initialize(attributes=Hash.new)
|
6
|
+
attributes.each do |attr, value|
|
7
|
+
self.send("#{attr}=", value)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def committers(from_sha, to_sha)
|
12
|
+
`cd #{local_repo} && git shortlog -sne #{from_sha}..#{to_sha} | awk '{ print $NF}' | cut -d'<' -f2 | cut -d'>' -f1`.split
|
13
|
+
end
|
14
|
+
|
15
|
+
def checkout!(sha)
|
16
|
+
logger.log `cd #{local_repo} && git reset --hard && git fetch && git checkout #{sha}`
|
17
|
+
end
|
18
|
+
|
19
|
+
def merge!(sha)
|
20
|
+
merge_response = `cd #{local_repo} && git merge #{sha}`
|
21
|
+
self.logger.log merge_response
|
22
|
+
merge_response.match(/CONFLICT/) ? :conflict : :success
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
extend Configuration::Helpers
|
29
|
+
delegate_config_to(:configuration, :local_repo)
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module OmgPullRequest
|
2
|
+
class GithubWrapper
|
3
|
+
attr_accessor :configuration
|
4
|
+
|
5
|
+
def initialize(attributes={})
|
6
|
+
attributes.each do |attr, value|
|
7
|
+
self.send("#{attr}=", value)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def author_logins(pull_request)
|
12
|
+
[pull_request.user.login, github_client.users.get(:user => pull_request.user.login).email]
|
13
|
+
end
|
14
|
+
|
15
|
+
def all_logins(pull_request)
|
16
|
+
logins = [pull_request.user.login]
|
17
|
+
|
18
|
+
logins |= github_client.issues.comments.list(repo_owner, repo, pull_request.number).collect do |c|
|
19
|
+
c.user.login
|
20
|
+
end
|
21
|
+
|
22
|
+
logins.uniq
|
23
|
+
end
|
24
|
+
|
25
|
+
def commit_shas(pull_request)
|
26
|
+
commits = github_client.pull_requests.commits(repo_owner, repo, pull_request.number)
|
27
|
+
|
28
|
+
commits.collect do |commit|
|
29
|
+
commit.sha[0..10]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def make_comment(issue_number, body)
|
34
|
+
github_client.issues.comments.create(repo_owner, repo, issue_number, :body => body)
|
35
|
+
end
|
36
|
+
|
37
|
+
def pull_requests
|
38
|
+
github_client.pull_requests.list(repo_owner, repo)
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
extend Configuration::Helpers
|
44
|
+
delegate_config_to(:configuration, :repo_owner, :repo, :github_credentials)
|
45
|
+
|
46
|
+
def github_client
|
47
|
+
@github_client ||= Github.new(github_credentials.symbolize_keys)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|