fourchette 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +19 -31
- data/bin/fourchette +26 -0
- data/fourchette.gemspec +1 -1
- data/lib/fourchette.rb +3 -2
- data/lib/fourchette/callbacks.rb +2 -2
- data/lib/fourchette/fork.rb +16 -56
- data/lib/fourchette/github.rb +1 -1
- data/lib/fourchette/heroku.rb +2 -6
- data/lib/fourchette/version.rb +1 -1
- data/templates/Gemfile +4 -0
- data/templates/Procfile +1 -0
- data/templates/Rakefile +1 -0
- data/templates/callbacks.rb +16 -0
- data/templates/config.ru +3 -0
- data/templates/config/puma.rb +8 -0
- metadata +21 -13
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87df619b48e95219f34009934e3a32ef4433d059
|
4
|
+
data.tar.gz: a6885be58afb51d2c87d7131df0b6b77c330c49a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6d3aa7737f01674126abf2bb3d7ebe7df059ad2bb82272e43ff74cad82503bef15b64c57148d55cee990e72de37a6f55694c1f9f9cacd4d9b510aeb2c2dca154
|
7
|
+
data.tar.gz: 7324d4a14c3a4b7c252646e26fe56db2e6087d8fba84447ad015406be800d86d18b5f2c6c0247e25bafe7480690e2e1490bb85b4cd17e32b122905d709d014f4
|
data/README.md
CHANGED
@@ -11,13 +11,25 @@
|
|
11
11
|
<a href="http://badge.fury.io/rb/fourchette"><img src="https://badge.fury.io/rb/fourchette.svg" alt="Gem Version" height="18"></a>
|
12
12
|
</p>
|
13
13
|
|
14
|
-
**IMPORTANT: this is a work in progress, use at your own risk.**
|
15
|
-
|
16
14
|
Fourchette is your new best friend for having isolated testing environements. It will help you test your GitHub PRs against a fork of one your Heroku apps. You will have one Heroku app per PR now. Isn't that amazing? It will make testing way easier and you won't have the (maybe) broken code from other PRs on staging but only the code that requires testing.
|
17
15
|
|
18
16
|
**IMPORTANT: Please note that forking your Heroku app means it will copy the same addon plans and that you will pay for multiple apps and their addons. Watch out!**
|
19
17
|
|
20
|
-
##
|
18
|
+
## Table of content
|
19
|
+
1. How does that work exactly?
|
20
|
+
- Features
|
21
|
+
- Installation
|
22
|
+
* Configuration
|
23
|
+
* Enable your Fourchette instance
|
24
|
+
* Enable, disable, update or delete the hook
|
25
|
+
* Before & after steps, aka, callbacks
|
26
|
+
- Rake tasks
|
27
|
+
- Async processing note
|
28
|
+
- Contribute
|
29
|
+
- Logging
|
30
|
+
- Contributors
|
31
|
+
|
32
|
+
## How does that work exactly?
|
21
33
|
|
22
34
|
- a PR is created against your GitHub project
|
23
35
|
- Fourchette receives an event via GitHub Hooks
|
@@ -26,24 +38,12 @@ Fourchette is your new best friend for having isolated testing environements. It
|
|
26
38
|
- closing the PR will delete the forked app
|
27
39
|
- re-opening the PR will re-create a fork
|
28
40
|
|
29
|
-
## Diagram
|
30
|
-
|
31
|
-
Seriously? You need a diagram for that? Nope. Not going to do this. PRs accepted...I guess.
|
32
|
-
|
33
|
-
## Features
|
34
|
-
- single project
|
35
|
-
- configuration is made via environement variables
|
36
|
-
- async processing
|
37
|
-
- it works, but that's about it for now
|
38
|
-
|
39
41
|
## Installation
|
40
42
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
3. Add `require 'fourchette/rake_tasks'` to your `Rakefile`
|
46
|
-
4. Create a `Procfile` and a `config.ru` (using the ones from this repo as example)
|
43
|
+
1. run `gem install fourchette`
|
44
|
+
2. run `fourchette new my-app-name`. You can replace "my-app-name" by whatever you want it, this is the name of the directory your Fourchette app will be created in.
|
45
|
+
3. run `cd my-app-name` (replace app name, again)
|
46
|
+
4. run `git init && git add . && git commit -m "Initial commit :tada:"`
|
47
47
|
5. push to Heroku
|
48
48
|
6. configure the right environement variables (see [#configuration](#configuration))
|
49
49
|
7. Enable your Fourchette instance
|
@@ -53,7 +53,6 @@ Those steps could be made way easier, but this is a really minimal implementatio
|
|
53
53
|
- `export FOURCHETTE_GITHUB_PROJECT="jipiboily/fourchette"`
|
54
54
|
- `export FOURCHETTE_GITHUB_USERNAME="jipiboily"`
|
55
55
|
- `export FOURCHETTE_GITHUB_PERSONAL_TOKEN='a token here...'` # You can create one here: https://github.com/settings/applications
|
56
|
-
- `export FOURCHETTE_HEROKU_USERNAME='me@domain'`
|
57
56
|
- `export FOURCHETTE_HEROKU_API_KEY='API key here'`
|
58
57
|
- `export FOURCHETTE_HEROKU_APP_TO_FORK='the name of the app to fork from'`
|
59
58
|
- `export FOURCHETTE_APP_URL="http://fourchette-app.herokuapp.com"`
|
@@ -108,17 +107,6 @@ If you want the maximum output in your GitHub comments, set this environment var
|
|
108
107
|
export DEBUG='true'
|
109
108
|
```
|
110
109
|
|
111
|
-
## It needs some love...
|
112
|
-
|
113
|
-
What needs to be improved?
|
114
|
-
|
115
|
-
- currently, it is assuming everything goes well, very little to no error management. This needs to improved.
|
116
|
-
- make it simpler to bootstrap a Fourchette app (possibily a rake task to generate the required files and callback overrides)
|
117
|
-
- it is not serious until there are specs for it, so add specs for that once we have a solid direction
|
118
|
-
- security improvements (we should not accept hooks from anyone else than GitHub)
|
119
|
-
- oAuth instead of GitHub token?
|
120
|
-
- multi project would be great
|
121
|
-
|
122
110
|
# Contributors
|
123
111
|
|
124
112
|
Thanks to [@jpsirois](https://github.com/jpsirois/) for the logo!
|
data/bin/fourchette
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "thor"
|
4
|
+
|
5
|
+
module Fourchette
|
6
|
+
class CLI < Thor
|
7
|
+
include Thor::Actions
|
8
|
+
|
9
|
+
desc "new APP_NAME", "This will create a fourchette app for you under APP_NAME directory."
|
10
|
+
def new(name)
|
11
|
+
# Create directory
|
12
|
+
empty_directory(name)
|
13
|
+
|
14
|
+
# Copy template files
|
15
|
+
['Gemfile','config.ru', 'Procfile', 'Rakefile', 'config/puma.rb', 'callbacks.rb'].each do |file_name|
|
16
|
+
copy_file(file_name, "#{name}/#{file_name}")
|
17
|
+
end
|
18
|
+
|
19
|
+
# Run bundle install
|
20
|
+
run("bundle install --gemfile #{name}/Gemfile")
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
Fourchette::CLI.source_root(File.expand_path("../../templates", __FILE__))
|
26
|
+
Fourchette::CLI.start(ARGV)
|
data/fourchette.gemspec
CHANGED
@@ -23,8 +23,8 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_dependency "sinatra-contrib"
|
24
24
|
spec.add_dependency "octokit"
|
25
25
|
spec.add_dependency "git"
|
26
|
-
spec.add_dependency "heroics", "0.0.2"
|
27
26
|
spec.add_dependency "heroku" # Deprecated, but best/easiest solution for the pgbackups...
|
27
|
+
spec.add_dependency 'platform-api', '~> 0.2.0'
|
28
28
|
spec.add_dependency "sucker_punch"
|
29
29
|
|
30
30
|
spec.add_development_dependency 'foreman'
|
data/lib/fourchette.rb
CHANGED
@@ -1,8 +1,7 @@
|
|
1
1
|
require "fourchette/version"
|
2
2
|
require 'sinatra'
|
3
3
|
require 'json'
|
4
|
-
require '
|
5
|
-
require 'heroics'
|
4
|
+
require 'platform-api'
|
6
5
|
require 'octokit'
|
7
6
|
require 'git'
|
8
7
|
require 'sucker_punch'
|
@@ -30,6 +29,8 @@ end
|
|
30
29
|
|
31
30
|
module Fourchette
|
32
31
|
DEBUG = ENV['DEBUG'] ? true : false
|
32
|
+
|
33
|
+
class DeployException < StandardError; end
|
33
34
|
end
|
34
35
|
|
35
36
|
require_relative 'fourchette/logger'
|
data/lib/fourchette/callbacks.rb
CHANGED
@@ -6,10 +6,10 @@ class Fourchette::Callbacks
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def before
|
9
|
-
logger.info '
|
9
|
+
logger.info 'Placeholder for before steps...'
|
10
10
|
end
|
11
11
|
|
12
12
|
def after
|
13
|
-
logger.info '
|
13
|
+
logger.info 'Placeholder for after steps...'
|
14
14
|
end
|
15
15
|
end
|
data/lib/fourchette/fork.rb
CHANGED
@@ -10,59 +10,23 @@ class Fourchette::Fork
|
|
10
10
|
def update
|
11
11
|
create_unless_exists
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
public_key_content = `cat #{public_key_path}`
|
23
|
-
|
24
|
-
# Create SSH config file, so that it uses the right SSH key
|
25
|
-
ssh_config_path = "~/.ssh/config"
|
26
|
-
if `cat #{ssh_config_path}`.length == 0
|
27
|
-
# Set the SSH key used, and disable strict host key checking
|
28
|
-
`echo "Host heroku.com\n IdentityFile #{key_path}\n StrictHostKeyChecking no" >> ~/.ssh/config`
|
29
|
-
end
|
30
|
-
|
31
|
-
# Add SSH key to the Heroku account
|
32
|
-
logger.info "Adding the SSH key to your Heroku account"
|
33
|
-
heroku_public_key = @heroku.client.key.create(public_key: public_key_content)
|
34
|
-
|
35
|
-
# Clone & push
|
36
|
-
logger.info "Cloning repository..."
|
37
|
-
repo = Git.clone(github_git_url, 'tmp')
|
38
|
-
repo.checkout(branch_name)
|
13
|
+
options = {
|
14
|
+
source_blob: {
|
15
|
+
url: "https://github.com/#{ENV['FOURCHETTE_GITHUB_PROJECT']}/archive/#{branch_name}.tar.gz?token=#{ENV['FOURCHETTE_GITHUB_PERSONAL_TOKEN']}"
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
19
|
+
build = @heroku.client.build.create(fork_name, options)
|
20
|
+
monitor_build(build)
|
21
|
+
end
|
39
22
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
# There is no master branch? Hmmm
|
23
|
+
def monitor_build build
|
24
|
+
build_info = @heroku.client.build.info(fork_name, build['id'])
|
25
|
+
while build_info['status'] == 'pending'
|
26
|
+
build_info = @heroku.client.build.info(fork_name, build['id'])
|
27
|
+
sleep 5
|
46
28
|
end
|
47
|
-
|
48
|
-
begin
|
49
|
-
repo.branch('master').merge(branch_name)
|
50
|
-
rescue Git::GitExecuteError
|
51
|
-
# TODO - HACK ALERT! There is certainly a cleaner way to do this...
|
52
|
-
end
|
53
|
-
repo.add_remote('heroku', heroku_git_url)
|
54
|
-
|
55
|
-
logger.info "Pushing to Heroku..."
|
56
|
-
repo.push(repo.remote('heroku'))
|
57
|
-
logger.info "Done pushing to Heroku, apparently!"
|
58
|
-
|
59
|
-
# REMOVE key to the Heroku account
|
60
|
-
logger.info "Removing SSH key from your Heroku account"
|
61
|
-
@heroku.client.key.delete(heroku_public_key['id'])
|
62
|
-
|
63
|
-
# Remove ssh key
|
64
|
-
logger.info "Removing SSH key for file system"
|
65
|
-
FileUtils.rm_rf("~./ssh/id_rsa-fourchette*")
|
29
|
+
fail Fourchette::DeployException if build_info['status'] == 'failed'
|
66
30
|
end
|
67
31
|
|
68
32
|
def create
|
@@ -82,12 +46,8 @@ class Fourchette::Fork
|
|
82
46
|
"#{ENV['FOURCHETTE_HEROKU_APP_PREFIX']}-PR-#{pr_number}".downcase # It needs to be lowercase only.
|
83
47
|
end
|
84
48
|
|
85
|
-
def github_git_url
|
86
|
-
@params['pull_request']['head']['repo']['clone_url'].gsub("//github.com", "//#{ENV['FOURCHETTE_GITHUB_USERNAME']}:#{ENV['FOURCHETTE_GITHUB_PERSONAL_TOKEN']}@github.com")
|
87
|
-
end
|
88
|
-
|
89
49
|
def branch_name
|
90
|
-
|
50
|
+
@params['pull_request']['head']['ref']
|
91
51
|
end
|
92
52
|
|
93
53
|
def pr_number
|
data/lib/fourchette/github.rb
CHANGED
data/lib/fourchette/heroku.rb
CHANGED
@@ -18,13 +18,9 @@ class Fourchette::Heroku
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def client
|
21
|
-
# TODO: add caching... https://github.com/heroku/heroics/#client-side-caching
|
22
21
|
unless @heroku_client
|
23
|
-
|
24
|
-
|
25
|
-
url = "https://#{username}:#{token}@api.heroku.com/schema"
|
26
|
-
options = {default_headers: {'Accept' => 'application/vnd.heroku+json; version=3'}}
|
27
|
-
@heroku_client = Heroics.client_from_schema_url(url, options)
|
22
|
+
api_key = ENV['FOURCHETTE_HEROKU_API_KEY']
|
23
|
+
@heroku_client = PlatformAPI.connect(api_key)
|
28
24
|
end
|
29
25
|
@heroku_client
|
30
26
|
end
|
data/lib/fourchette/version.rb
CHANGED
data/templates/Gemfile
ADDED
data/templates/Procfile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
web: bundle exec puma -C config/puma.rb
|
data/templates/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'fourchette/rake_tasks'
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# This is a sample
|
2
|
+
class Fourchette::Callbacks
|
3
|
+
include Fourchette::Logger
|
4
|
+
|
5
|
+
def initialize params
|
6
|
+
@params = params
|
7
|
+
end
|
8
|
+
|
9
|
+
def before
|
10
|
+
logger.info 'Placeholder for before steps... (see callbacks.rb to override)'
|
11
|
+
end
|
12
|
+
|
13
|
+
def after
|
14
|
+
logger.info 'Placeholder for after steps... (see callbacks.rb to override)'
|
15
|
+
end
|
16
|
+
end
|
data/templates/config.ru
ADDED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fourchette
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean-Philippe Boily
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -81,33 +81,33 @@ dependencies:
|
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
|
-
name:
|
84
|
+
name: heroku
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
88
|
- !ruby/object:Gem::Version
|
89
|
-
version: 0
|
89
|
+
version: '0'
|
90
90
|
type: :runtime
|
91
91
|
prerelease: false
|
92
92
|
version_requirements: !ruby/object:Gem::Requirement
|
93
93
|
requirements:
|
94
|
-
- -
|
94
|
+
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
|
-
version: 0
|
96
|
+
version: '0'
|
97
97
|
- !ruby/object:Gem::Dependency
|
98
|
-
name:
|
98
|
+
name: platform-api
|
99
99
|
requirement: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - "
|
101
|
+
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
103
|
+
version: 0.2.0
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
|
-
- - "
|
108
|
+
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version:
|
110
|
+
version: 0.2.0
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: sucker_punch
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -185,7 +185,8 @@ description: Fourchette is your new best friend for having isolated testing envi
|
|
185
185
|
only the code that requires testing.
|
186
186
|
email:
|
187
187
|
- j@jipi.ca
|
188
|
-
executables:
|
188
|
+
executables:
|
189
|
+
- fourchette
|
189
190
|
extensions: []
|
190
191
|
extra_rdoc_files: []
|
191
192
|
files:
|
@@ -196,6 +197,7 @@ files:
|
|
196
197
|
- Procfile
|
197
198
|
- README.md
|
198
199
|
- Rakefile
|
200
|
+
- bin/fourchette
|
199
201
|
- config.ru
|
200
202
|
- fourchette.gemspec
|
201
203
|
- lib/fourchette.rb
|
@@ -214,6 +216,12 @@ files:
|
|
214
216
|
- spec/lib/fourchette/pull_request_spec.rb
|
215
217
|
- spec/spec_helper.rb
|
216
218
|
- spec/support/silent-logger.rb
|
219
|
+
- templates/Gemfile
|
220
|
+
- templates/Procfile
|
221
|
+
- templates/Rakefile
|
222
|
+
- templates/callbacks.rb
|
223
|
+
- templates/config.ru
|
224
|
+
- templates/config/puma.rb
|
217
225
|
homepage: https://github.com/jipiboily/fourchette
|
218
226
|
licenses:
|
219
227
|
- MIT
|