dual_burner 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 +10 -0
- data/.rspec +1 -0
- data/.rubocop.yml +25 -0
- data/.ruby-version +1 -0
- data/Gemfile +4 -0
- data/README.md +108 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/circle.yml +9 -0
- data/dual_burner.gemspec +31 -0
- data/exe/dual_burner +6 -0
- data/lib/dual_burner/base_command.rb +122 -0
- data/lib/dual_burner/commands/deployer.rb +76 -0
- data/lib/dual_burner/commands/heroku_config.rb +39 -0
- data/lib/dual_burner/commands/last_release.rb +31 -0
- data/lib/dual_burner/configuration.rb +17 -0
- data/lib/dual_burner/configuration_error.rb +4 -0
- data/lib/dual_burner/environment_not_found_error.rb +4 -0
- data/lib/dual_burner/runner.rb +75 -0
- data/lib/dual_burner/version.rb +3 -0
- data/lib/dual_burner.rb +11 -0
- metadata +178 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b12d52c907a72c8b457e012cd28033a272da5975
|
4
|
+
data.tar.gz: e46f66e90b6c1709d21a6726d2ea32ece06176c7
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c3d7ca6bad54f606ecd793a301e54a4967d5099a9fbfbd21bdea96bbbba7b73c4d7c1268a2f8942923575aaba8e5dc8aaa934c74a51f140b1278dddc236d34b5
|
7
|
+
data.tar.gz: 3ebc133f63dfb06afd11540936bf1a61bfcc0ec0a04494d78d0ba41e429198b1d5bd07e4735de63003c03954b8a9f9669704e163f37f9106011eee58b019ab03
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
AllCops:
|
2
|
+
TargetRubyVersion: 2.3
|
3
|
+
Include:
|
4
|
+
- Rakefile
|
5
|
+
Exclude:
|
6
|
+
- bin/**/*
|
7
|
+
- vendor/bundle/**/*
|
8
|
+
|
9
|
+
Metrics/AbcSize:
|
10
|
+
Max: 50
|
11
|
+
|
12
|
+
Metrics/LineLength:
|
13
|
+
Max: 120
|
14
|
+
|
15
|
+
Metrics/MethodLength:
|
16
|
+
Max: 20
|
17
|
+
|
18
|
+
Metrics/ParameterLists:
|
19
|
+
Max: 6
|
20
|
+
|
21
|
+
Style/Documentation:
|
22
|
+
Enabled: false
|
23
|
+
|
24
|
+
Style/SignalException:
|
25
|
+
Enabled: false
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.3.0
|
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,108 @@
|
|
1
|
+
# Dual Burner
|
2
|
+
|
3
|
+
Cause a two burner stove is better than one!
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'dual_burner', require: false
|
11
|
+
```
|
12
|
+
|
13
|
+
Or to grab a particular branch:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
gem 'dual_burner', git: 'git://github.com/blueapron/dual_burner.git', branch: 'something_neat'
|
17
|
+
```
|
18
|
+
|
19
|
+
And then execute:
|
20
|
+
|
21
|
+
```
|
22
|
+
$ bundle
|
23
|
+
```
|
24
|
+
|
25
|
+
Or install it yourself as:
|
26
|
+
|
27
|
+
```
|
28
|
+
$ gem install dual_burner
|
29
|
+
```
|
30
|
+
|
31
|
+
## Configuration
|
32
|
+
|
33
|
+
### Dual Burner YML
|
34
|
+
|
35
|
+
The YML file manages the environment and clustering information.
|
36
|
+
|
37
|
+
```
|
38
|
+
staging:
|
39
|
+
- remote_url: 'git@heroku.com:blueapron-alpha.git'
|
40
|
+
name: 'Alpha'
|
41
|
+
color: 'blue'
|
42
|
+
- remote_url: 'git@heroku.com:blueapron-alpha.git'
|
43
|
+
name: 'Bravo'
|
44
|
+
color: 'green'
|
45
|
+
production:
|
46
|
+
- remote_url: 'git@heroku.com:blueapron-api.git
|
47
|
+
name: 'API'
|
48
|
+
color: 'blue'
|
49
|
+
- remote_url: 'git@heroku.com:blueapron-admin.git'
|
50
|
+
name: 'Admin'
|
51
|
+
color: 'green'
|
52
|
+
- remote_url: 'git@heroku.com:blueapron-www.git'
|
53
|
+
name: 'WWW'
|
54
|
+
color: 'yellow'
|
55
|
+
```
|
56
|
+
|
57
|
+
These are the possible configurations for your application.
|
58
|
+
|
59
|
+
| Key | Required | Use |
|
60
|
+
| ----------------|:-------------:| ----- |
|
61
|
+
| remote_url | yes | The git target for deploy and release information. |
|
62
|
+
| name | yes | The presentation name for the app. |
|
63
|
+
| color | no | The presentation color for display. |
|
64
|
+
| heroku_app_name | no | The heroku app name. Needed only for Heroku related commands i.e. `dual_burner config_set`. |
|
65
|
+
|
66
|
+
## Deploying
|
67
|
+
|
68
|
+
Use the `dual_burner deploy` executable to deploy your projects.
|
69
|
+
|
70
|
+
Below are some examples.
|
71
|
+
|
72
|
+
#### Deploy of Master to Staging
|
73
|
+
|
74
|
+
`dual_burner deploy -e staging -g master`
|
75
|
+
|
76
|
+
#### Deploy of Master to Staging with Force
|
77
|
+
|
78
|
+
You can use a string for any git reference you would normally do.
|
79
|
+
|
80
|
+
`dual_burner deploy -e staging -g 'master --force'`
|
81
|
+
|
82
|
+
#### Deploy of Master to Staging from Different Configuration Files
|
83
|
+
|
84
|
+
You can pass in file locations of your deploy configuration if it is not under `/config`.
|
85
|
+
|
86
|
+
`dual_burner deploy -c config/dual_burner.yml -e staging -g master`
|
87
|
+
|
88
|
+
## Latest Release
|
89
|
+
|
90
|
+
You can verify that all versions are consistent with the following command.
|
91
|
+
|
92
|
+
`dual_burner last_release --e wms_testing`
|
93
|
+
|
94
|
+
## Heroku Config Management
|
95
|
+
|
96
|
+
You can set, unset, and verify consistency of Heroku configurations.
|
97
|
+
|
98
|
+
#### Set A Key For All Clusters
|
99
|
+
|
100
|
+
`dual_burner config_set -e wms_testing -k FOO -v BAR`
|
101
|
+
|
102
|
+
#### Ensure A Key Is The Same Across Clusters
|
103
|
+
|
104
|
+
`dual_burner config_get -e wms_testing -k FOO`
|
105
|
+
|
106
|
+
#### Remove A Key Across Clusters
|
107
|
+
|
108
|
+
`dual_burner config_unset -e wms_testing -k FOO`
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'bundler/setup'
|
4
|
+
require 'dual_burner'
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
require 'pry'
|
11
|
+
Pry.start
|
12
|
+
|
13
|
+
require 'irb'
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/circle.yml
ADDED
data/dual_burner.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'dual_burner/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "dual_burner"
|
8
|
+
spec.version = DualBurner::VERSION
|
9
|
+
spec.authors = ['Blue Apron Engineering']
|
10
|
+
spec.email = ['engineering@blueapron.com']
|
11
|
+
|
12
|
+
spec.summary = %q{Blue Apron Dual Burner}
|
13
|
+
spec.description = %q{A simply Ruby utility to push to many Heroku applications.}
|
14
|
+
spec.homepage = 'https://github.com/blueapron/dual_burner'
|
15
|
+
|
16
|
+
# Note: Files must be registered with git for things to package properly....
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = 'exe'
|
19
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ['lib']
|
21
|
+
|
22
|
+
spec.add_dependency 'colorize', '~> 0.7'
|
23
|
+
spec.add_dependency 'thor', '~> 0.19'
|
24
|
+
|
25
|
+
spec.add_development_dependency 'bundler', '~> 1.11'
|
26
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
27
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
28
|
+
spec.add_development_dependency 'pry'
|
29
|
+
spec.add_development_dependency 'rubocop'
|
30
|
+
spec.add_development_dependency 'simplecov'
|
31
|
+
end
|
data/exe/dual_burner
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
module DualBurner
|
5
|
+
class BaseCommand
|
6
|
+
attr_reader \
|
7
|
+
:configuration,
|
8
|
+
:env
|
9
|
+
|
10
|
+
def initialize(env:, configuration:)
|
11
|
+
@configuration = configuration
|
12
|
+
@env = env
|
13
|
+
end
|
14
|
+
|
15
|
+
protected
|
16
|
+
|
17
|
+
def apps
|
18
|
+
@apps ||= get_apps_for_environment
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_apps_for_environment
|
22
|
+
raise ArgumentError, 'ENV IS NOT PRESENT!' if env.nil?
|
23
|
+
raise DualBurner::ConfigurationError, 'CONFIG IS NOT PRESENT!' unless File.exists?(configuration.deploy_file)
|
24
|
+
config = YAML.load(File.read(configuration.deploy_file))[env]
|
25
|
+
raise DualBurner::EnvironmentNotFoundError, "ENV #{env} NOT FOUND!" if config.nil?
|
26
|
+
config.map { |c| app_instance(c) }
|
27
|
+
end
|
28
|
+
|
29
|
+
def result_struct
|
30
|
+
Struct.new(:value, :lines, :app)
|
31
|
+
end
|
32
|
+
|
33
|
+
def result_instance
|
34
|
+
result_struct.new(-1, [], nil)
|
35
|
+
end
|
36
|
+
|
37
|
+
def app_struct
|
38
|
+
Struct.new(:remote_url, :name, :color, :heroku_app_name)
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# Return a simple object-esque instance of App.
|
43
|
+
def app_instance(options)
|
44
|
+
app_struct.new(
|
45
|
+
options.fetch('remote_url'),
|
46
|
+
options.fetch('name'),
|
47
|
+
options.fetch('color', nil),
|
48
|
+
options.fetch('heroku_app_name', nil)
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
##
|
53
|
+
# Determine of all processes return exit 0 status.
|
54
|
+
def all_processes_exit_0?(processes)
|
55
|
+
if processes.select { |p| p.exitstatus == 0 }.size == processes.size
|
56
|
+
true
|
57
|
+
else
|
58
|
+
false
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
##
|
63
|
+
# Execute a command and capture the output.
|
64
|
+
#
|
65
|
+
# https://nickcharlton.net/posts/ruby-subprocesses-with-stdout-stderr-streams.html
|
66
|
+
def execute_command(command, app:, print_lines: true)
|
67
|
+
puts "#{app.name} #{Time.now} - executing command [#{command}]".send(app.color)
|
68
|
+
|
69
|
+
result = result_instance
|
70
|
+
Open3.popen2e(command) do |stdin, stdout_and_stderr, thread|
|
71
|
+
Thread.new do
|
72
|
+
until (raw_line = stdout_and_stderr.gets).nil? do
|
73
|
+
# There is a newline automatically appended from the stream.
|
74
|
+
print "#{app.name} #{Time.now} - #{raw_line}".send(app.color) if print_lines
|
75
|
+
result.lines << raw_line
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Return the value of the command line thread.
|
80
|
+
result.value = thread.value
|
81
|
+
result.app = app
|
82
|
+
end
|
83
|
+
|
84
|
+
result
|
85
|
+
end
|
86
|
+
|
87
|
+
##
|
88
|
+
# Given an array of apps and values, determine if they are all consistent or not.
|
89
|
+
def verify_single_value(results:, context:)
|
90
|
+
# Yield to get the transformation to the value.
|
91
|
+
values = []
|
92
|
+
results.each do |result|
|
93
|
+
values << yield(result)
|
94
|
+
end
|
95
|
+
|
96
|
+
# We have different commit hashes, env variables, whatever, we need to warn.
|
97
|
+
if values.uniq.size > 1
|
98
|
+
puts "Inconsistent #{context} found!".red.blink
|
99
|
+
puts ""
|
100
|
+
|
101
|
+
results.each_with_index do |result, i|
|
102
|
+
print result.app.name.send(result.app.color)
|
103
|
+
print " is at #{context} "
|
104
|
+
print values[i].bold
|
105
|
+
puts ""
|
106
|
+
end
|
107
|
+
|
108
|
+
false
|
109
|
+
# Everything is fine!
|
110
|
+
elsif values.uniq.size == 1
|
111
|
+
puts ""
|
112
|
+
print "All apps "
|
113
|
+
print results.map { |r| r.app.name }.join(', ').bold
|
114
|
+
print " are on #{context} "
|
115
|
+
print values.first.green
|
116
|
+
puts ""
|
117
|
+
|
118
|
+
true
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
module DualBurner
|
2
|
+
module Commands
|
3
|
+
class Deployer < DualBurner::BaseCommand
|
4
|
+
def deploy(git_reference: 'master')
|
5
|
+
# Need to handle the explicit passing of nil too....
|
6
|
+
if git_reference.nil? || git_reference.strip.empty?
|
7
|
+
git_reference = 'master'
|
8
|
+
end
|
9
|
+
|
10
|
+
challenge_user!(git_reference: git_reference) if configuration.interactive?
|
11
|
+
|
12
|
+
threads = []
|
13
|
+
results = []
|
14
|
+
|
15
|
+
apps.each do |app|
|
16
|
+
# Execute each command in a separate thread.
|
17
|
+
# Deploys can take a long time....
|
18
|
+
threads << Thread.new do
|
19
|
+
results << execute_command(
|
20
|
+
build_deploy_command(app: app, git_reference: git_reference),
|
21
|
+
app: app
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# Wait for all commands to complete.
|
27
|
+
threads.map(&:join)
|
28
|
+
|
29
|
+
puts "Completed all deploys [#{threads.size}]!"
|
30
|
+
|
31
|
+
all_processes_exit_0?(results.map { |r| r.value })
|
32
|
+
end
|
33
|
+
|
34
|
+
def build_deploy_command(app:, git_reference:)
|
35
|
+
remote = app.remote_url
|
36
|
+
raise DualBurner::RemoteNotFoundException if remote.nil? || remote.strip.empty?
|
37
|
+
"git push #{remote} #{git_reference}"
|
38
|
+
end
|
39
|
+
|
40
|
+
##
|
41
|
+
# Make sure the user knows what he/she is doing!
|
42
|
+
def challenge_user!(git_reference:)
|
43
|
+
# Show the user what Heroku apps are involved.
|
44
|
+
puts "\n"
|
45
|
+
|
46
|
+
print "You are about to deploy "
|
47
|
+
print git_reference.bold
|
48
|
+
print " to "
|
49
|
+
print env.bold
|
50
|
+
print " on the following Apps: "
|
51
|
+
print apps.map { |a| a.name }.join(', ').bold
|
52
|
+
|
53
|
+
puts "\n" * 2
|
54
|
+
|
55
|
+
# Show the user what we are about to do on their machine.
|
56
|
+
puts "These commands will be executed:"
|
57
|
+
apps.each do |app|
|
58
|
+
puts build_deploy_command(app: app, git_reference: git_reference).send(app.color).bold
|
59
|
+
end
|
60
|
+
|
61
|
+
puts "\n"
|
62
|
+
|
63
|
+
# Ensure the user really wants to don this (CSV importer looking at you!).
|
64
|
+
challenge = "#{env}_#{apps.size}"
|
65
|
+
puts "If this is ok, please type in the following: #{challenge}"
|
66
|
+
response = STDIN.gets.chomp
|
67
|
+
if challenge != response
|
68
|
+
puts "You didn't enter the right challenge. Aborting!".red.bold
|
69
|
+
exit(1)
|
70
|
+
else
|
71
|
+
puts "Preparing to deploy...."
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module DualBurner
|
2
|
+
module Commands
|
3
|
+
class HerokuConfig < DualBurner::BaseCommand
|
4
|
+
def get(key:)
|
5
|
+
results = execute_command_with_apps do |app|
|
6
|
+
"heroku config:get #{key} -a #{app.heroku_app_name}"
|
7
|
+
end
|
8
|
+
|
9
|
+
verify_single_value(results: results, context: 'ruby ENV') do |result|
|
10
|
+
result.lines.join
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def set( key:, value:)
|
15
|
+
results = execute_command_with_apps do |app|
|
16
|
+
"heroku config:set #{key}=#{value} -a #{app.heroku_app_name}"
|
17
|
+
end
|
18
|
+
all_processes_exit_0?(results.map { |r| r.value })
|
19
|
+
end
|
20
|
+
|
21
|
+
def unset(key:)
|
22
|
+
results = execute_command_with_apps do |app|
|
23
|
+
"heroku config:unset #{key} -a #{app.heroku_app_name}"
|
24
|
+
end
|
25
|
+
all_processes_exit_0?(results.map { |r| r.value })
|
26
|
+
end
|
27
|
+
|
28
|
+
def execute_command_with_apps
|
29
|
+
results = []
|
30
|
+
apps.each do |app|
|
31
|
+
raise DualBurner::ConfigurationError, 'HEROKU APP NAME NOT CONFIGURED' if app.heroku_app_name.nil?
|
32
|
+
command = yield(app)
|
33
|
+
results << execute_command(command, app: app)
|
34
|
+
end
|
35
|
+
results
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module DualBurner
|
2
|
+
module Commands
|
3
|
+
class LastRelease < DualBurner::BaseCommand
|
4
|
+
def verify_apps
|
5
|
+
results = []
|
6
|
+
commit_hashes = []
|
7
|
+
|
8
|
+
apps.each do |app|
|
9
|
+
remote = app.remote_url
|
10
|
+
command = "git ls-remote #{remote} HEAD"
|
11
|
+
results << execute_command(
|
12
|
+
command,
|
13
|
+
app: app,
|
14
|
+
print_lines: false
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
verify_single_value(results: results, context: 'git commit') do |result|
|
19
|
+
get_commit_hash(content: result.lines.join)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def get_commit_hash(content:)
|
24
|
+
match = content.match(/^([A-Za-z0-9]+)(\s+)HEAD$/)
|
25
|
+
return nil if match.nil?
|
26
|
+
|
27
|
+
match.captures.first
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module DualBurner
|
2
|
+
class Configuration
|
3
|
+
##
|
4
|
+
# The location of the deploy file.
|
5
|
+
attr_accessor :deploy_file
|
6
|
+
|
7
|
+
##
|
8
|
+
# Enable or disable user interaction.
|
9
|
+
attr_accessor :interactive
|
10
|
+
|
11
|
+
alias_method :interactive?, :interactive
|
12
|
+
|
13
|
+
def initialize
|
14
|
+
@interactive = true
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'dual_burner'
|
2
|
+
|
3
|
+
module DualBurner
|
4
|
+
class Runner < Thor
|
5
|
+
|
6
|
+
ENV_DESC = 'The cluster environment.'.freeze unless defined?(ENV_DESC)
|
7
|
+
CONFIG_DESC = 'Your configuration file if not .config/dual_burner.yml'.freeze unless defined?(CONFIG_DESC)
|
8
|
+
HEROKU_KEY_DESC = 'The key to set on the Heroku app.'.freeze unless defined?(HEROKU_KEY_DESC)
|
9
|
+
|
10
|
+
desc 'last_release', 'Finds the HEAD git revision for all applications in cluster <ENV>.'
|
11
|
+
method_option :env, aliases: '-e', type: :string, required: true, desc: ENV_DESC
|
12
|
+
method_option :config, aliases: '-c', type: :string, optional: true, desc: CONFIG_DESC
|
13
|
+
def last_release
|
14
|
+
::DualBurner::Commands::LastRelease.new(
|
15
|
+
env: options.fetch('env'),
|
16
|
+
configuration: get_configuration_instance(deploy_file: options['config'])
|
17
|
+
).verify_apps ? exit(0) : exit(1)
|
18
|
+
end
|
19
|
+
|
20
|
+
desc 'deploy', 'Deploy <REF> to all applications in cluster <ENV>.'
|
21
|
+
method_option :env, aliases: '-e', type: :string, required: true, desc: ENV_DESC
|
22
|
+
method_option :config, aliases: '-c', type: :string, optional: true, desc: CONFIG_DESC
|
23
|
+
method_option :git_reference, aliases: '-g', default: 'master', type: :string, required: false, desc: 'The git reference to deploy.'
|
24
|
+
def deploy
|
25
|
+
::DualBurner::Commands::Deployer.new(
|
26
|
+
env: options.fetch('env'),
|
27
|
+
configuration: get_configuration_instance(deploy_file: options['config'])
|
28
|
+
).deploy(git_reference: options['git_reference']) ? exit(0) : exit(1)
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'config_set', 'Set <KEY> to <VALUE> for all Heroku appslocations in cluster <ENV>.'
|
32
|
+
method_option :env, aliases: '-e', type: :string, required: true, desc: ENV_DESC
|
33
|
+
method_option :config, aliases: '-c', type: :string, optional: true, desc: CONFIG_DESC
|
34
|
+
method_option :key, aliases: '-k', type: :string, required: true, desc: HEROKU_KEY_DESC
|
35
|
+
method_option :value, aliases: '-v', type: :string, required: true, desc: 'The value to set on the Heroku app.'
|
36
|
+
def config_set
|
37
|
+
::DualBurner::Commands::HerokuConfig.new(
|
38
|
+
env: options.fetch('env'),
|
39
|
+
configuration: get_configuration_instance(deploy_file: options['config'])
|
40
|
+
).set(key: options.fetch('key'), value: options['value']) ? exit(0) : exit(1)
|
41
|
+
end
|
42
|
+
|
43
|
+
desc 'config_get', 'Get <KEY> for all Heroku appslocations in cluster <ENV>.'
|
44
|
+
method_option :env, aliases: '-e', type: :string, required: true, desc: ENV_DESC
|
45
|
+
method_option :config, aliases: '-c', type: :string, optional: true, desc: CONFIG_DESC
|
46
|
+
method_option :key, aliases: '-k', type: :string, required: true, desc: HEROKU_KEY_DESC
|
47
|
+
def config_get
|
48
|
+
::DualBurner::Commands::HerokuConfig.new(
|
49
|
+
env: options.fetch('env'),
|
50
|
+
configuration: get_configuration_instance(deploy_file: options['config'])
|
51
|
+
).get(key: options.fetch('key')) ? exit(0) : exit(1)
|
52
|
+
end
|
53
|
+
|
54
|
+
desc 'config_unset', 'Unset <KEY> for all Heroku appslocations in cluster <ENV>.'
|
55
|
+
method_option :env, aliases: '-e', type: :string, required: true, desc: ENV_DESC
|
56
|
+
method_option :config, aliases: '-c', type: :string, optional: true, desc: CONFIG_DESC
|
57
|
+
method_option :key, aliases: '-k', type: :string, required: true, desc: HEROKU_KEY_DESC
|
58
|
+
def config_unset
|
59
|
+
::DualBurner::Commands::HerokuConfig.new(
|
60
|
+
env: options.fetch('env'),
|
61
|
+
configuration: get_configuration_instance(deploy_file: options['config'])
|
62
|
+
).unset(key: options.fetch('key')) ? exit(0) : exit(1)
|
63
|
+
end
|
64
|
+
|
65
|
+
protected
|
66
|
+
|
67
|
+
def get_configuration_instance(deploy_file: nil)
|
68
|
+
deploy_file ||= File.join(Dir.getwd, 'config', 'dual_burner.yml')
|
69
|
+
|
70
|
+
c = DualBurner::Configuration.new
|
71
|
+
c.deploy_file = deploy_file
|
72
|
+
c
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/dual_burner.rb
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'thor'
|
2
|
+
require 'colorize'
|
3
|
+
require 'dual_burner/version'
|
4
|
+
require 'dual_burner/configuration'
|
5
|
+
require 'dual_burner/configuration_error'
|
6
|
+
require 'dual_burner/environment_not_found_error'
|
7
|
+
require 'dual_burner/base_command'
|
8
|
+
require 'dual_burner/commands/deployer'
|
9
|
+
require 'dual_burner/commands/heroku_config'
|
10
|
+
require 'dual_burner/commands/last_release'
|
11
|
+
require 'dual_burner/runner'
|
metadata
ADDED
@@ -0,0 +1,178 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: dual_burner
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Blue Apron Engineering
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-02-29 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: colorize
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.7'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: thor
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.19'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.19'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: bundler
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.11'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.11'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rake
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '10.0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '10.0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: pry
|
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: rubocop
|
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: simplecov
|
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
|
+
description: A simply Ruby utility to push to many Heroku applications.
|
126
|
+
email:
|
127
|
+
- engineering@blueapron.com
|
128
|
+
executables:
|
129
|
+
- dual_burner
|
130
|
+
extensions: []
|
131
|
+
extra_rdoc_files: []
|
132
|
+
files:
|
133
|
+
- ".gitignore"
|
134
|
+
- ".rspec"
|
135
|
+
- ".rubocop.yml"
|
136
|
+
- ".ruby-version"
|
137
|
+
- Gemfile
|
138
|
+
- README.md
|
139
|
+
- Rakefile
|
140
|
+
- bin/console
|
141
|
+
- bin/setup
|
142
|
+
- circle.yml
|
143
|
+
- dual_burner.gemspec
|
144
|
+
- exe/dual_burner
|
145
|
+
- lib/dual_burner.rb
|
146
|
+
- lib/dual_burner/base_command.rb
|
147
|
+
- lib/dual_burner/commands/deployer.rb
|
148
|
+
- lib/dual_burner/commands/heroku_config.rb
|
149
|
+
- lib/dual_burner/commands/last_release.rb
|
150
|
+
- lib/dual_burner/configuration.rb
|
151
|
+
- lib/dual_burner/configuration_error.rb
|
152
|
+
- lib/dual_burner/environment_not_found_error.rb
|
153
|
+
- lib/dual_burner/runner.rb
|
154
|
+
- lib/dual_burner/version.rb
|
155
|
+
homepage: https://github.com/blueapron/dual_burner
|
156
|
+
licenses: []
|
157
|
+
metadata: {}
|
158
|
+
post_install_message:
|
159
|
+
rdoc_options: []
|
160
|
+
require_paths:
|
161
|
+
- lib
|
162
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
163
|
+
requirements:
|
164
|
+
- - ">="
|
165
|
+
- !ruby/object:Gem::Version
|
166
|
+
version: '0'
|
167
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
168
|
+
requirements:
|
169
|
+
- - ">="
|
170
|
+
- !ruby/object:Gem::Version
|
171
|
+
version: '0'
|
172
|
+
requirements: []
|
173
|
+
rubyforge_project:
|
174
|
+
rubygems_version: 2.5.1
|
175
|
+
signing_key:
|
176
|
+
specification_version: 4
|
177
|
+
summary: Blue Apron Dual Burner
|
178
|
+
test_files: []
|