bb_deploy 0.0.0.1
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/lib/bb_deploy/config.rb +44 -0
- data/lib/bb_deploy/deployer.rb +181 -0
- data/lib/bb_deploy/git.rb +61 -0
- data/lib/bb_deploy/heroku.rb +42 -0
- data/lib/bb_deploy/logger.rb +68 -0
- data/lib/bb_deploy/railtie.rb +12 -0
- data/lib/bb_deploy/task.rb +41 -0
- data/lib/bb_deploy.rb +6 -0
- data/lib/tasks/deploy.rake +17 -0
- metadata +122 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d9cc6005046b0480f59f0ddd824b42ce3db5b4fc
|
4
|
+
data.tar.gz: ef97ccf9b0486fe4222cce699372fbb1aa291c96
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 201d6e780955bd86311528ee7ed3109f3319018b6fd61a903b92a1b6b65ab32e68bb121536d3ce7ad91ec6b02b31c19a827c20aca542a915161123b006d0e82a
|
7
|
+
data.tar.gz: 7892a5234d19ee8bfab1a20395ca22d046676ab073d2189b33ff071bc947b7e6a0619bbbe22f5a2ce2b8fb685d40dd68bb5e83f0d1cf96c79e3d69c246370d95
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require_relative './heroku'
|
3
|
+
|
4
|
+
module BbDeploy
|
5
|
+
class Config
|
6
|
+
attr_accessor :application_name,
|
7
|
+
:application_urls,
|
8
|
+
:logentries_token,
|
9
|
+
:deployment_channel,
|
10
|
+
:engineering_channel,
|
11
|
+
:slack_webhook_key
|
12
|
+
|
13
|
+
class << self
|
14
|
+
def configuration
|
15
|
+
@configuration ||= BbDeploy::Config.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def configure
|
19
|
+
yield(configuration)
|
20
|
+
configuration
|
21
|
+
end
|
22
|
+
|
23
|
+
def configure_from_yaml(file_path)
|
24
|
+
options = YAML.load(ERB.new(File.read(file_path)).result)
|
25
|
+
configure do |config|
|
26
|
+
%w(application_name application_urls deployment_channel engineering_channel).each do |key|
|
27
|
+
config.send("#{key}=", options[key])
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def set_heroku_fields!(phase)
|
33
|
+
configure do |config|
|
34
|
+
config.logentries_token = BbDeploy::Heroku.get_variable(phase, 'DEPLOY_LOG_TOKEN').freeze
|
35
|
+
config.slack_webhook_key = BbDeploy::Heroku.get_variable(phase, 'SLACK_WEBHOOK').freeze
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def method_missing(method, *args)
|
40
|
+
configuration.send(method, *args)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
require 'pp'
|
2
|
+
require_relative './config'
|
3
|
+
require_relative './task'
|
4
|
+
require_relative './logger'
|
5
|
+
require_relative './git'
|
6
|
+
require_relative './heroku'
|
7
|
+
|
8
|
+
class BbDeploy::Deployer
|
9
|
+
|
10
|
+
include BbDeploy::Logger
|
11
|
+
|
12
|
+
attr_reader :phase
|
13
|
+
|
14
|
+
def initialize(phase)
|
15
|
+
BbDeploy::Config.configure_from_yaml('config/deploy.yml')
|
16
|
+
BbDeploy::Config.set_heroku_fields!(phase)
|
17
|
+
@phase = phase
|
18
|
+
end
|
19
|
+
|
20
|
+
# Environment inquiry methods
|
21
|
+
%w(qa staging production).each do |phase|
|
22
|
+
define_method("#{phase}?") { @phase == phase }
|
23
|
+
end
|
24
|
+
|
25
|
+
def deploy!
|
26
|
+
BbDeploy::Git.check_git_status!
|
27
|
+
check_access!
|
28
|
+
staging_checks if phase == 'staging'
|
29
|
+
prompt = "Do you want to deploy #{current_branch} to #{BbDeploy::Config.application_name} #{phase}?"
|
30
|
+
if phase == 'production'
|
31
|
+
do_deploy if BbDeploy::Task.ask(prompt, required_response: 'production', important: true)
|
32
|
+
else
|
33
|
+
do_deploy if BbDeploy::Task.ask(prompt)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private
|
38
|
+
|
39
|
+
def dputs(*msgs)
|
40
|
+
asterisks = "*" * 80
|
41
|
+
puts asterisks
|
42
|
+
puts(*msgs.map(&:to_s))
|
43
|
+
puts asterisks
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def current_branch
|
48
|
+
BbDeploy::Git.current_branch(started_on_master?)
|
49
|
+
end
|
50
|
+
|
51
|
+
def do_deploy
|
52
|
+
branch = current_branch
|
53
|
+
|
54
|
+
chat_broadcast(":alert: '#{ENV['USER']}' is deploying the #{BbDeploy::Config.application_name} branch '#{branch}' to '#{phase}' :alert:", phase: phase, notify_eng_hub: true)
|
55
|
+
|
56
|
+
do_heroku_deploy!
|
57
|
+
|
58
|
+
open_in_browser
|
59
|
+
|
60
|
+
if phase != 'qa' && !started_on_master?
|
61
|
+
puts "Merging back to master ..."
|
62
|
+
puts `git checkout master && git pull && git merge -`
|
63
|
+
puts "You must now resolve any conflicts in the merge and then `git push origin master` ..."
|
64
|
+
end
|
65
|
+
|
66
|
+
chat_broadcast(":alertgreen: Deployment of the #{BbDeploy::Config.application_name} branch '#{branch}' to '#{phase}' completed! :alertgreen:", phase: phase, notify_eng_hub: true)
|
67
|
+
end
|
68
|
+
|
69
|
+
def logger
|
70
|
+
@logger ||= BbDeploy::Logger.logger(phase)
|
71
|
+
end
|
72
|
+
|
73
|
+
def check_access!
|
74
|
+
unless BbDeploy::Heroku.has_access?(phase)
|
75
|
+
exit_with_message("You do not have access to the #{BbDeploy::Config.application_name} #{phase} application!")
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def exit_with_message(msg)
|
80
|
+
puts "\n#{msg}\n"
|
81
|
+
exit(0)
|
82
|
+
end
|
83
|
+
|
84
|
+
def do_heroku_deploy! # rubocop:disable all
|
85
|
+
run_migrations = run_migrations?
|
86
|
+
|
87
|
+
exit(0) if run_migrations && !BbDeploy::Task.ask("There are new migrations to run. If you proceed,\n\n*** YOU WILL INCUR SITE DOWNTIME!!! ***\n\nDo you wish to proceed?")
|
88
|
+
|
89
|
+
enter_maint_mode = run_migrations || BbDeploy::Task.ask("Would you like to put #{BbDeploy::Config.application_name} into maintenance mode even though you don't have any migrations to run?")
|
90
|
+
if enter_maint_mode
|
91
|
+
stay_in_maint_mode = BbDeploy::Task.ask('Would you like to stay in maintenance mode after deployment, e.g. to run some rake tasks?')
|
92
|
+
logger.with_consolidated_logging { BbDeploy::Heroku.toggle_maintenance(mode: :on, phase: phase) }
|
93
|
+
end
|
94
|
+
|
95
|
+
push_release!
|
96
|
+
|
97
|
+
run_migrations! if run_migrations
|
98
|
+
|
99
|
+
if enter_maint_mode
|
100
|
+
if stay_in_maint_mode
|
101
|
+
dputs "********** NOTE: YOU ARE STILL IN MAINTENANCE MODE, AND MUST MANUALLY DISABLE IT VIA `rake heroku:maint:off:#{phase}` **********"
|
102
|
+
else
|
103
|
+
logger.with_consolidated_logging { BbDeploy::Heroku.toggle_maintenance(mode: :off, phase: phase) }
|
104
|
+
end
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def run_migrations!
|
109
|
+
started_at = Time.current
|
110
|
+
|
111
|
+
chat_broadcast("Running migrations from #{BbDeploy::Config.application_name} branch '#{current_branch}' in #{phase} ...", phase: phase)
|
112
|
+
logger.with_consolidated_logging { BbDeploy::Heroku.migrate_db!(phase) }
|
113
|
+
chat_broadcast("Successfully ran migrations from #{BbDeploy::Config.application_name} branch '#{current_branch}' in #{phase}.", phase: phase)
|
114
|
+
|
115
|
+
time_spent = Time.zone.at(Time.current - started_at).getutc.strftime("%H:%M:%S")
|
116
|
+
# The only time started_on_master is non-nil is when creating a new staging branch
|
117
|
+
if started_on_master?
|
118
|
+
chat_broadcast("Yo, @jake - the #{BbDeploy::Config.application_name} branch '#{current_branch}' contains migrations that take #{time_spent} to run", phase: phase, notify_eng_hub: true)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def push_release!
|
123
|
+
puts "Deploying ..."
|
124
|
+
chat_broadcast("Pushing #{BbDeploy::Config.application_name} branch '#{current_branch}' to #{phase} ...", phase: phase)
|
125
|
+
logger.with_consolidated_logging { puts(BbDeploy::Git.push_to_phase(phase)) }
|
126
|
+
end
|
127
|
+
|
128
|
+
def open_in_browser
|
129
|
+
sleep 2 # because removing maint mode takes a couple seconds to propagate
|
130
|
+
host_and_path =
|
131
|
+
case phase
|
132
|
+
when 'qa'; BbDeploy::Config.application_urls['qa']
|
133
|
+
when 'staging'; BbDeploy::Config.application_urls['staging']
|
134
|
+
when 'production'; BbDeploy::Config.application_urls['production']
|
135
|
+
end
|
136
|
+
|
137
|
+
puts "Opening the site for inspection ..."
|
138
|
+
BbDeploy::Task.run("open https://#{host_and_path}")
|
139
|
+
end
|
140
|
+
|
141
|
+
def run_migrations?
|
142
|
+
sha = BbDeploy::Heroku.last_release_sha(phase)
|
143
|
+
BbDeploy::Git.migrations_present?(sha)
|
144
|
+
end
|
145
|
+
|
146
|
+
def started_on_master!
|
147
|
+
@started_on_mater = true
|
148
|
+
end
|
149
|
+
|
150
|
+
def started_on_master?
|
151
|
+
!!@started_on_master
|
152
|
+
end
|
153
|
+
|
154
|
+
def staging_checks
|
155
|
+
if BbDeploy::Git.on_master?
|
156
|
+
do_it = BbDeploy::Task.ask("You are on master. Do you want to create a ***NEW*** release branch from the HEAD of master and deploy it to #{BbDeploy::Config.application_name} #{phase}?")
|
157
|
+
|
158
|
+
if do_it
|
159
|
+
date = Time.zone.today.to_s(:db).tr('-', '_')
|
160
|
+
new_branch = "release_#{date}"
|
161
|
+
|
162
|
+
if BbDeploy::Git.local_release(new_branch).present?
|
163
|
+
exit_with_message("There already exists a local release branch named #{new_branch}!")
|
164
|
+
end
|
165
|
+
|
166
|
+
if BbDeploy::Git.remote_release(new_branch).present?
|
167
|
+
exit_with_message("There already exists a remote release branch named #{new_branch}!")
|
168
|
+
end
|
169
|
+
|
170
|
+
BbDeploy::Git.push_release_branch!
|
171
|
+
|
172
|
+
started_on_master!
|
173
|
+
end
|
174
|
+
elsif BbDeploy::Git.on_a_release_branch?
|
175
|
+
do_it = BbDeploy::Task.ask("Do you want to ***REDEPLOY*** the HEAD of your local version of #{current_branch} to #{BbDeploy::Config.application_name} #{phase}?")
|
176
|
+
else
|
177
|
+
exit_with_message("You may only deploy master or a release branch to #{BbDeploy::Config.application_name} #{phase}!")
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require_relative './task'
|
2
|
+
|
3
|
+
module BbDeploy::Git
|
4
|
+
class << self
|
5
|
+
# NOTE - THE DEFAULT AUTO-MEMOIZATION CAN CAUSE ISSUES IF YOU FORGET IT'S HAPPENING, SO NOTE THAT IT OCCURS!!!
|
6
|
+
def current_branch(reload = false)
|
7
|
+
if reload || !@current_branch
|
8
|
+
# I don't know sed at all, hence I don't know which backslashes need to be doubled and which don't :(
|
9
|
+
cmd = 'git branch 2> /dev/null | sed -e \'/^[^*]/d\' -e \'s/* \(.*\)/\1/\''
|
10
|
+
result = `#{cmd}`
|
11
|
+
raise "Unable to determine the current branch name" if result.blank?
|
12
|
+
@current_branch = result.strip
|
13
|
+
else
|
14
|
+
@current_branch
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def push_to_phase(phase)
|
19
|
+
`git push #{phase} HEAD:master --force`
|
20
|
+
end
|
21
|
+
|
22
|
+
def on_master?
|
23
|
+
current_branch == 'master'
|
24
|
+
end
|
25
|
+
|
26
|
+
def push_release_branch!
|
27
|
+
puts `git checkout -lb #{new_branch} && git push origin #{new_branch} -u`
|
28
|
+
end
|
29
|
+
|
30
|
+
def on_a_release_branch?
|
31
|
+
current_branch.start_with?('release_')
|
32
|
+
end
|
33
|
+
|
34
|
+
def check_git_status! # rubocop:disable Metrics/CyclomaticComplexity
|
35
|
+
puts "Running `git fetch` ... "
|
36
|
+
quietly { `git fetch` }
|
37
|
+
if `git log ..origin/#{current_branch}`.present?
|
38
|
+
exit(0) unless BbDeploy::Task.ask("There are new commits on the remote branch 'origin/#{current_branch}'. Are you sure you want to proceed?")
|
39
|
+
end
|
40
|
+
status_msg_a = `git status`.split(/(?:\n+)/)
|
41
|
+
if status_msg_a[1] =~ /your.branch.is.ahead/i
|
42
|
+
exit(0) unless BbDeploy::Task.ask("You have local, committed changes that have not been pushed to the remote. Are you sure you want to proceed?")
|
43
|
+
end
|
44
|
+
unless status_msg_a.last =~ /nothing to commit/i
|
45
|
+
exit(0) unless BbDeploy::Task.ask("You have local, uncommitted changes. Are you sure you want to proceed?")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def migrations_present?(sha)
|
50
|
+
`git diff #{sha} db/migrate`.present?
|
51
|
+
end
|
52
|
+
|
53
|
+
def local_release(branch_name)
|
54
|
+
`git branch --list "#{branch_name}"`
|
55
|
+
end
|
56
|
+
|
57
|
+
def remote_release(branch_name)
|
58
|
+
`git branch -r --list "origin/#{branch_name}"`
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
require_relative './task'
|
2
|
+
|
3
|
+
module BbDeploy::Heroku
|
4
|
+
class << self
|
5
|
+
def get_variable(phase, var_name)
|
6
|
+
@heroku_env_vars ||= {}
|
7
|
+
return @heroku_env_vars[var_name] if @heroku_env_vars[var_name]
|
8
|
+
token = heroku_run("heroku config:get #{var_name} --remote #{phase}")
|
9
|
+
if token.present?
|
10
|
+
token = token.chomp
|
11
|
+
@heroku_env_vars[var_name] = token.split.last
|
12
|
+
end
|
13
|
+
@heroku_env_vars[var_name]
|
14
|
+
end
|
15
|
+
|
16
|
+
def last_release_sha(phase)
|
17
|
+
heroku_run("heroku releases -n 25 --remote #{phase} | grep Deploy | head -n 1 | awk '{print $3}'")
|
18
|
+
end
|
19
|
+
|
20
|
+
def has_access?(phase)
|
21
|
+
heroku_info = heroku_run("heroku info --remote #{phase} 2>&1")
|
22
|
+
!(heroku_info =~ /You do not have access/i || heroku_info =~ /Enter your Heroku credentials./)
|
23
|
+
end
|
24
|
+
|
25
|
+
def migrate_db!(phase)
|
26
|
+
heroku_run(
|
27
|
+
"heroku run --size=PX rake db:migrate --remote #{phase}",
|
28
|
+
"heroku restart --remote #{phase}" # necessary to not have the web server gag
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def toggle_maintenance(mode:, phase:)
|
33
|
+
Rake::Task["heroku:maint:#{mode}:#{phase}"].invoke
|
34
|
+
end
|
35
|
+
|
36
|
+
def heroku_run(*cmds)
|
37
|
+
# Heroku Toolbelt uses Ruby 1.9, which requires clearing the RUBYOPT var ...
|
38
|
+
puts "Running: #{cmds.map(&:inspect).join(", ")}"
|
39
|
+
BbDeploy::Task.run(*cmds.map { |cmd| cmd =~ /heroku/ ? "export RUBYOPT='' && #{cmd}" : cmd })
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# Helper file for Logging/Slack notifications
|
2
|
+
module BbDeploy::Logger
|
3
|
+
def self.logger(phase)
|
4
|
+
@logger ||= ConsolidatedLogger::Logentries.new(phase) # Phase-specific memoization
|
5
|
+
end
|
6
|
+
|
7
|
+
module ConsolidatedLogger
|
8
|
+
# For logging to our Logentries consolidated logging service
|
9
|
+
class Logentries
|
10
|
+
def initialize(phase)
|
11
|
+
@phase = phase
|
12
|
+
end
|
13
|
+
|
14
|
+
def with_consolidated_logging
|
15
|
+
@original_stdout = $stdout
|
16
|
+
# Logging something before assigning $stdout is necessary
|
17
|
+
# to avoid `SystemStackError: stack level too deep`?!
|
18
|
+
logger.send(:info, "logging #with_consolidated_logging")
|
19
|
+
$stdout = self
|
20
|
+
yield
|
21
|
+
ensure
|
22
|
+
$stdout = @original_stdout
|
23
|
+
end
|
24
|
+
|
25
|
+
# To replace $stdout we must #write
|
26
|
+
def write(msg)
|
27
|
+
# Apparently reassigning $stdout triggers a blank message.
|
28
|
+
@original_stdout.puts(msg)
|
29
|
+
logger.send(:info, "#{ENV['USER']} #{msg}") unless msg.blank?
|
30
|
+
end
|
31
|
+
|
32
|
+
def method_missing(method, *args)
|
33
|
+
# this is mostly a call to #flush. We do nothing.
|
34
|
+
end
|
35
|
+
|
36
|
+
# Logs originating here will be found in the BB
|
37
|
+
# Logentries account in the "Ruby Log" for each phase
|
38
|
+
def logger
|
39
|
+
@logger ||= Le.new(BbDeploy::Config.logentries_token)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def chat_broadcast(msg, phase:, notify_eng_hub: false)
|
45
|
+
attachment = [
|
46
|
+
{
|
47
|
+
fallback: "Deploying to #{phase}",
|
48
|
+
color: " ",
|
49
|
+
fields: [
|
50
|
+
{
|
51
|
+
title: "Details",
|
52
|
+
value: msg,
|
53
|
+
short: false
|
54
|
+
}
|
55
|
+
]
|
56
|
+
}
|
57
|
+
]
|
58
|
+
|
59
|
+
slack.ping("*Deploying to #{phase}*", attachments: attachment, channel: BbDeploy::Config.deployment_channel)
|
60
|
+
slack.ping("*Deploying to #{phase}*", attachments: attachment, channel: BbDeploy::Config.engineering_channel) if notify_eng_hub
|
61
|
+
@consolidated_logger ||= ConsolidatedLogger::Logentries.new(phase)
|
62
|
+
@consolidated_logger.logger.info("DEPLOY--#{msg}")
|
63
|
+
end
|
64
|
+
|
65
|
+
def slack
|
66
|
+
@slack ||= Slack::Notifier.new(BbDeploy::Config.slack_webhook_key)
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module BbDeploy::Task
|
2
|
+
class << self
|
3
|
+
def run(*cmds)
|
4
|
+
dry_run = !!ENV['DRY_RUN']
|
5
|
+
Dir.chdir(Rails.root)
|
6
|
+
result = cmds.map do |cmd|
|
7
|
+
cmd_s = "==> \`#{cmd}\`"
|
8
|
+
if dry_run
|
9
|
+
puts "DRY RUN ONLY"
|
10
|
+
puts cmd_s
|
11
|
+
else
|
12
|
+
with_timing(cmd_s) { `#{cmd}` || raise("System call failed: #{cmd.inspect}") }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
result.last.try(:strip) unless dry_run
|
16
|
+
end
|
17
|
+
|
18
|
+
def ask(prompt, required_response: 'yes', important: false)
|
19
|
+
msg = prompt + "\n\nTyping anything other than '#{required_response}' will abort."
|
20
|
+
if important # Color important text RED and highlight the required response
|
21
|
+
msg = "\e[31m#{msg}\e[0m"
|
22
|
+
msg.sub!(/'#{required_response}'/, "\e[47m'#{required_response}'\e[49m")
|
23
|
+
end
|
24
|
+
puts
|
25
|
+
HighLine.new.ask(msg) =~ /\A#{required_response}\Z/i
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
def with_timing(what)
|
31
|
+
start = Time.current
|
32
|
+
puts
|
33
|
+
puts "Commencing #{what} ..."
|
34
|
+
result = yield
|
35
|
+
time = Time.zone.at(Time.current - start).getutc.strftime("%H:%M:%S")
|
36
|
+
puts "Finished #{what} in #{time}."
|
37
|
+
puts
|
38
|
+
result
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/lib/bb_deploy.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative '../bb_deploy'
|
2
|
+
|
3
|
+
namespace :heroku do
|
4
|
+
namespace :deploy do
|
5
|
+
task qa: :environment do
|
6
|
+
BbDeploy::Deployer.new('qa').deploy!
|
7
|
+
end
|
8
|
+
|
9
|
+
task staging: :environment do
|
10
|
+
BbDeploy::Deployer.new('staging').deploy!
|
11
|
+
end
|
12
|
+
|
13
|
+
task production: :environment do
|
14
|
+
BbDeploy::Deployer.new('production').deploy!
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,122 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: bb_deploy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Peter van Wesep
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-09-01 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rake
|
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: pry
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: highline
|
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: le
|
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: slack-notifier
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
description:
|
84
|
+
email: peter@brightbytes.net
|
85
|
+
executables: []
|
86
|
+
extensions: []
|
87
|
+
extra_rdoc_files: []
|
88
|
+
files:
|
89
|
+
- lib/bb_deploy.rb
|
90
|
+
- lib/bb_deploy/config.rb
|
91
|
+
- lib/bb_deploy/deployer.rb
|
92
|
+
- lib/bb_deploy/git.rb
|
93
|
+
- lib/bb_deploy/heroku.rb
|
94
|
+
- lib/bb_deploy/logger.rb
|
95
|
+
- lib/bb_deploy/railtie.rb
|
96
|
+
- lib/bb_deploy/task.rb
|
97
|
+
- lib/tasks/deploy.rake
|
98
|
+
homepage:
|
99
|
+
licenses:
|
100
|
+
- MIT
|
101
|
+
metadata: {}
|
102
|
+
post_install_message:
|
103
|
+
rdoc_options: []
|
104
|
+
require_paths:
|
105
|
+
- lib
|
106
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
|
+
requirements:
|
113
|
+
- - ">="
|
114
|
+
- !ruby/object:Gem::Version
|
115
|
+
version: '0'
|
116
|
+
requirements: []
|
117
|
+
rubyforge_project:
|
118
|
+
rubygems_version: 2.5.1
|
119
|
+
signing_key:
|
120
|
+
specification_version: 4
|
121
|
+
summary: Shared gem for deploying BrightBytes repositories
|
122
|
+
test_files: []
|