deis-rails 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +35 -0
- data/.rspec +2 -0
- data/.travis.yml +3 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +40 -0
- data/LICENSE +22 -0
- data/LICENSE.txt +21 -0
- data/README.md +32 -0
- data/Rakefile +1 -0
- data/bin/console +14 -0
- data/bin/deis-rails +348 -0
- data/bin/setup +7 -0
- data/deis-rails.gemspec +27 -0
- data/lib/deis/rails/version.rb +5 -0
- data/lib/deis/rails.rb +7 -0
- metadata +131 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 4a0d197e8f02f0970bff04d1ccaa0dc3786638fa
|
4
|
+
data.tar.gz: e12f349772fec864702e7dbd5149c56d6e6a7fd6
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bd5c59ae888e2e9fa73b68847a8713aff0e76cc6e2dfc0e4cf5c1f5566ddf7995163b3e83724e10540a5d1ba5a9e590b700188bb6acc0678ba9e6c471d6d3a3e
|
7
|
+
data.tar.gz: b150f06d2bed83c050b5b14d030cb0ff74e639b7b893c58b71c13d8e9bde0af84906a334e421a4c127eef863c7f00f933e16dac506310b59f1d89fdd1c882640
|
data/.gitignore
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/test/tmp/
|
9
|
+
/test/version_tmp/
|
10
|
+
/tmp/
|
11
|
+
|
12
|
+
## Specific to RubyMotion:
|
13
|
+
.dat*
|
14
|
+
.repl_history
|
15
|
+
build/
|
16
|
+
|
17
|
+
## Documentation cache and generated files:
|
18
|
+
/.yardoc/
|
19
|
+
/_yardoc/
|
20
|
+
/doc/
|
21
|
+
/rdoc/
|
22
|
+
|
23
|
+
## Environment normalisation:
|
24
|
+
/.bundle/
|
25
|
+
/vendor/bundle
|
26
|
+
/lib/bundler/man/
|
27
|
+
|
28
|
+
# for a library or gem, you might want to ignore these files since the code is
|
29
|
+
# intended to run in multiple environments; otherwise, check them in:
|
30
|
+
# Gemfile.lock
|
31
|
+
# .ruby-version
|
32
|
+
# .ruby-gemset
|
33
|
+
|
34
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
35
|
+
.rvmrc
|
data/.rspec
ADDED
data/.travis.yml
ADDED
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
4
|
+
|
5
|
+
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
|
6
|
+
|
7
|
+
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
8
|
+
|
9
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
10
|
+
|
11
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
12
|
+
|
13
|
+
This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.0.0, available at [http://contributor-covenant.org/version/1/0/0/](http://contributor-covenant.org/version/1/0/0/)
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
deis-rails (1.0.0)
|
5
|
+
activesupport (>= 3.0)
|
6
|
+
colorize (>= 0.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
activesupport (4.2.3)
|
12
|
+
i18n (~> 0.7)
|
13
|
+
json (~> 1.7, >= 1.7.7)
|
14
|
+
minitest (~> 5.1)
|
15
|
+
thread_safe (~> 0.3, >= 0.3.4)
|
16
|
+
tzinfo (~> 1.1)
|
17
|
+
coderay (1.1.0)
|
18
|
+
colorize (0.7.7)
|
19
|
+
i18n (0.7.0)
|
20
|
+
json (1.8.3)
|
21
|
+
method_source (0.8.2)
|
22
|
+
minitest (5.7.0)
|
23
|
+
pry (0.10.1)
|
24
|
+
coderay (~> 1.1.0)
|
25
|
+
method_source (~> 0.8.1)
|
26
|
+
slop (~> 3.4)
|
27
|
+
rake (10.3.2)
|
28
|
+
slop (3.6.0)
|
29
|
+
thread_safe (0.3.5)
|
30
|
+
tzinfo (1.2.2)
|
31
|
+
thread_safe (~> 0.1)
|
32
|
+
|
33
|
+
PLATFORMS
|
34
|
+
ruby
|
35
|
+
|
36
|
+
DEPENDENCIES
|
37
|
+
bundler (~> 1.9)
|
38
|
+
deis-rails!
|
39
|
+
pry
|
40
|
+
rake (~> 10.0)
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Brandfolder
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Jason Waldrip
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# deis-rails
|
2
|
+
A tool for deploying and managing rails apps on deis.
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
|
6
|
+
Add this line to your application's Gemfile:
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
gem 'deis-rails'
|
10
|
+
```
|
11
|
+
|
12
|
+
And then execute:
|
13
|
+
|
14
|
+
$ bundle
|
15
|
+
|
16
|
+
Or install it yourself as:
|
17
|
+
|
18
|
+
$ gem install deis-rails
|
19
|
+
|
20
|
+
## Development
|
21
|
+
|
22
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
23
|
+
|
24
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
25
|
+
|
26
|
+
## Contributing
|
27
|
+
|
28
|
+
1. Fork it ( https://github.com/[my-github-username]/deis-rails/fork )
|
29
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
30
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
31
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
32
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "deis/rails"
|
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/deis-rails
ADDED
@@ -0,0 +1,348 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'yaml'
|
3
|
+
require 'bundler'
|
4
|
+
require 'active_support/all'
|
5
|
+
require 'pry'
|
6
|
+
require 'pty'
|
7
|
+
require 'benchmark'
|
8
|
+
require 'colorize'
|
9
|
+
|
10
|
+
class DeisUtils < Struct.new(:args)
|
11
|
+
|
12
|
+
TRUTHY_STRINGS = %w(t true y yes 1).flat_map do |str|
|
13
|
+
[str.downcase, str.upcase, str.capitalize]
|
14
|
+
end.uniq
|
15
|
+
|
16
|
+
FALSEY_STRINGS = %w(f false n no 0).flat_map do |str|
|
17
|
+
[str.downcase, str.upcase, str.capitalize]
|
18
|
+
end.uniq
|
19
|
+
|
20
|
+
NonZeroExitError = Class.new(StandardError)
|
21
|
+
|
22
|
+
def run
|
23
|
+
command = args.shift
|
24
|
+
status = Helpers.run_util(command, *args)
|
25
|
+
exit status === false ? 1 : 0
|
26
|
+
end
|
27
|
+
|
28
|
+
module Helpers
|
29
|
+
|
30
|
+
module_function def run_util(name, *args)
|
31
|
+
status = false
|
32
|
+
time = Benchmark.realtime do
|
33
|
+
status = get_runner(name).new(*args).run
|
34
|
+
end
|
35
|
+
STDOUT.puts "#{$0} #{name} #{args.join ' '}` took #{seconds_to_human time}".light_blue if debug?
|
36
|
+
status
|
37
|
+
end
|
38
|
+
|
39
|
+
module_function def debug?
|
40
|
+
ENV['DEBUG'].in? TRUTHY_STRINGS
|
41
|
+
end
|
42
|
+
|
43
|
+
module_function def get_runner(name)
|
44
|
+
DeisUtils.const_get(name.gsub('-', '_').camelize)
|
45
|
+
rescue NameError
|
46
|
+
STDERR.puts "command `#{name}` does not exist!".red
|
47
|
+
exit 1
|
48
|
+
end
|
49
|
+
|
50
|
+
def app_exists?(app)
|
51
|
+
!!deis_command('info', app: app)
|
52
|
+
rescue NonZeroExitError
|
53
|
+
false
|
54
|
+
end
|
55
|
+
|
56
|
+
def status(msg)
|
57
|
+
msg = "| #{msg} |"
|
58
|
+
sep = ''.ljust(msg.size, '-')
|
59
|
+
puts "\n\e[0;92;49m#{[sep, msg, sep].join "\n"}\e[0m"
|
60
|
+
end
|
61
|
+
|
62
|
+
def databases(app)
|
63
|
+
databases = deis_command('pg:info', app: app).split('===')
|
64
|
+
databases[1..-1].map do |db|
|
65
|
+
lines = db.lines
|
66
|
+
name = lines[0].split(' ')[0]
|
67
|
+
data = lines[1..-1].join
|
68
|
+
{ 'Name' => name }.merge YAML.load(data)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def info(app)
|
73
|
+
cmd_result = deis_command(:info, app: app)
|
74
|
+
data = JSON.load cmd_result.match(/Application\r\n(?<json>\{.*\})/m)[:json]
|
75
|
+
controller_host = data['url'].split('.').tap { |p| p[p.index app] = 'deis' }.join('.')
|
76
|
+
data['git_url'] = "ssh://git@#{controller_host}:2222/#{app}.git"
|
77
|
+
data['domains'] = cmd_result.match(/Domains\r\n(?<domains>.*)/m)[:domains].lines.map(&:strip).reject(&:empty?)
|
78
|
+
data.sort.to_h
|
79
|
+
end
|
80
|
+
|
81
|
+
def shell(*commands)
|
82
|
+
flags = commands.last.is_a?(Hash) ? commands.pop : {}
|
83
|
+
command = commands.join ' '
|
84
|
+
flags.each_with_object(command) do |(k, v), c|
|
85
|
+
c << case v
|
86
|
+
when TrueClass, FalseClass
|
87
|
+
v ? " --#{k}" : ''
|
88
|
+
when String, Fixnum
|
89
|
+
" --#{k} #{v}"
|
90
|
+
else
|
91
|
+
raise ArgumentError
|
92
|
+
end
|
93
|
+
end
|
94
|
+
result = nil
|
95
|
+
time = Benchmark.realtime do
|
96
|
+
result = capture_syscall command
|
97
|
+
end
|
98
|
+
STDOUT.puts "`#{command}` took #{seconds_to_human time}".light_black if debug?
|
99
|
+
result
|
100
|
+
end
|
101
|
+
|
102
|
+
def deis_command(*cmds)
|
103
|
+
shell :deis, *cmds
|
104
|
+
end
|
105
|
+
|
106
|
+
def git_clone(url, flags = {})
|
107
|
+
shell "git clone #{url}", flags
|
108
|
+
end
|
109
|
+
|
110
|
+
def deploy(url, options = {})
|
111
|
+
ref = options.delete(:ref) || 'master'
|
112
|
+
shell "git push #{url} #{ref}:master", options
|
113
|
+
end
|
114
|
+
|
115
|
+
def capture_syscall(command)
|
116
|
+
puts "\n#{command}".light_yellow if debug?
|
117
|
+
String.new.tap do |output|
|
118
|
+
threads = []
|
119
|
+
PTY.spawn(command) do |p_out, p_in, pid|
|
120
|
+
threads << Thread.new { p_in.close }
|
121
|
+
threads << Thread.new { output << capture_output(p_out) }
|
122
|
+
Process.wait pid
|
123
|
+
threads.each(&:join)
|
124
|
+
end
|
125
|
+
raise NonZeroExitError, output unless $?.exitstatus == 0
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
def capture_output(io)
|
130
|
+
output = ''
|
131
|
+
io.each do |line|
|
132
|
+
output << line
|
133
|
+
STDOUT.puts "#{line.strip}".light_black unless line.nil? || line.strip.empty? if debug?
|
134
|
+
end
|
135
|
+
ensure
|
136
|
+
return output
|
137
|
+
end
|
138
|
+
|
139
|
+
# Warn Slack for upcoming maintenance mode
|
140
|
+
def warn_for_maintenance(app)
|
141
|
+
Slacker.message(text: "WARNING: #{app} will go into maintenance mode shortly.",
|
142
|
+
username: "Deploy Bot",
|
143
|
+
channel: "#pulse-dev",
|
144
|
+
color: "warning",
|
145
|
+
icon_emoji: ":warning:")
|
146
|
+
end
|
147
|
+
|
148
|
+
# Enable Maintenance Mode on Heroku
|
149
|
+
def enable_maintenance_mode(app)
|
150
|
+
get_units!
|
151
|
+
status "#{app} is going into maintenance mode!"
|
152
|
+
Slacker.message(text: "ALERT: #{app} is going into maintenance mode!",
|
153
|
+
username: "Deploy Bot",
|
154
|
+
channel: "#pulse-dev",
|
155
|
+
color: "danger",
|
156
|
+
icon_emoji: ":bangbang:")
|
157
|
+
scale app, units.keys.each_with_object({}) { |k, h| h[k] = 0 }
|
158
|
+
end
|
159
|
+
|
160
|
+
# Disable Maintenance Mode on Heroku
|
161
|
+
def disable_maintenance_mode(app)
|
162
|
+
scale app, units
|
163
|
+
status "#{app} is no longer in maintenance mode!"
|
164
|
+
Slacker.message(text: "NOTICE: #{app} is no longer in maintenance mode.",
|
165
|
+
username: "Deploy Bot",
|
166
|
+
channel: "#pulse-dev",
|
167
|
+
color: "good",
|
168
|
+
icon_emoji: ":white_check_mark:")
|
169
|
+
end
|
170
|
+
|
171
|
+
def scale(app, opts={})
|
172
|
+
process_string = opts.map { |k, v| "#{k}=#{v}" }.join ' '
|
173
|
+
deis_command "scale #{process_string}", app: app
|
174
|
+
end
|
175
|
+
|
176
|
+
def get_units!
|
177
|
+
unit_string = deis_command('ps', app: app)
|
178
|
+
shell('foreman check').strip.sub(/.*\((.*)\)/, "\\1").split(', ').each do |unit|
|
179
|
+
units[unit] ||= unit_string.lines.select { |l| l.include? "#{unit}." }.count
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def units
|
184
|
+
@units ||= {}
|
185
|
+
end
|
186
|
+
|
187
|
+
module_function def seconds_to_human(secs)
|
188
|
+
secs = secs.round
|
189
|
+
output = ''
|
190
|
+
seconds = secs % 60
|
191
|
+
minutes = (secs - seconds) / 60
|
192
|
+
output << "#{minutes}m" if minutes > 0
|
193
|
+
output << "#{seconds}s"
|
194
|
+
end
|
195
|
+
|
196
|
+
end
|
197
|
+
|
198
|
+
class Info < Struct.new :app
|
199
|
+
include Helpers
|
200
|
+
|
201
|
+
def run
|
202
|
+
h = info(app)
|
203
|
+
status "`#{app}` Information"
|
204
|
+
output_hash h
|
205
|
+
end
|
206
|
+
|
207
|
+
def output_hash(hash, indent = 0)
|
208
|
+
hash.each do |k, v|
|
209
|
+
case v
|
210
|
+
when Hash
|
211
|
+
puts (' ' * indent) + k + ':'
|
212
|
+
output_hash(v, indent + 1)
|
213
|
+
when Array
|
214
|
+
puts (' ' * indent) + k + ':', *v.map { |i| (' ' * (indent + 1)) + i.to_s }
|
215
|
+
else
|
216
|
+
puts (' ' * indent) + "#{k}: #{v}"
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
class Exists < Struct.new :app
|
223
|
+
include Helpers
|
224
|
+
|
225
|
+
def run
|
226
|
+
app_exists?(app)
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
class CopyConfig < Struct.new :source_app, :dest_app
|
231
|
+
include Helpers
|
232
|
+
|
233
|
+
def run
|
234
|
+
system <<-sh
|
235
|
+
deis config --app #{source_app} --oneline | xargs deis config:set --app #{dest_app}
|
236
|
+
sh
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
class Disable < Struct.new :app
|
241
|
+
include Helpers
|
242
|
+
|
243
|
+
def run
|
244
|
+
status "Disabling App: #{app}"
|
245
|
+
units = shell('foreman check').strip.sub(/.*\((.*)\)/, "\\1").split(', ')
|
246
|
+
scale app, units.each_with_object({}) { |k, h| h[k] = 0 }
|
247
|
+
end
|
248
|
+
|
249
|
+
end
|
250
|
+
|
251
|
+
class Enable < Struct.new :app
|
252
|
+
include Helpers
|
253
|
+
|
254
|
+
def run
|
255
|
+
status "Enabling App: #{app}"
|
256
|
+
get_units!
|
257
|
+
if units.any? { |_, v| v > 0 }
|
258
|
+
status "App Already enabled!"
|
259
|
+
return
|
260
|
+
end
|
261
|
+
scale app, units.keys.each_with_object({}) { |k, h| h[k] = 1 }
|
262
|
+
status "App enabled!"
|
263
|
+
end
|
264
|
+
|
265
|
+
end
|
266
|
+
|
267
|
+
# Deploy a deis repo
|
268
|
+
class Deploy < Struct.new(:app, :ref)
|
269
|
+
include Helpers
|
270
|
+
|
271
|
+
LAST_MIGRATION_CMD = %{bundle exec rake db:migrate:status}
|
272
|
+
MIGRATION_REGEX = /up\s+(?<migration>[0-9]{8}[0-9])+/
|
273
|
+
|
274
|
+
attr_reader :worker_count
|
275
|
+
attr_reader :web_count
|
276
|
+
|
277
|
+
def run
|
278
|
+
status "Deploying `#{ref}` to `#{app}` on Deis"
|
279
|
+
precheck_migrations!
|
280
|
+
output = deploy info['git_url'], ref: ref
|
281
|
+
if output.include? 'Another git push is ongoing'
|
282
|
+
sleep 60 # one minute
|
283
|
+
return run_util 'deploy', app, ref
|
284
|
+
end
|
285
|
+
run_migrations! if needs_migrations?
|
286
|
+
rescue NonZeroExitError => e
|
287
|
+
raise e unless e.message.include? 'Another git push is ongoing'
|
288
|
+
remove_instance_variable :@needs_migrations
|
289
|
+
sleep 60
|
290
|
+
retry
|
291
|
+
end
|
292
|
+
|
293
|
+
private
|
294
|
+
|
295
|
+
def info
|
296
|
+
@info ||= super(app)
|
297
|
+
end
|
298
|
+
|
299
|
+
def run_migrations!
|
300
|
+
# Todo: put the site in a readonly state but NEVER in maintenance mode
|
301
|
+
status 'Running Migrations'
|
302
|
+
deis_command('run rake "db:migrate"', app: app)
|
303
|
+
end
|
304
|
+
|
305
|
+
def precheck_migrations!
|
306
|
+
needs_migrations?
|
307
|
+
end
|
308
|
+
|
309
|
+
def needs_migrations?
|
310
|
+
return false if TRUTHY_STRINGS.include? ENV['SKIP_MIGRATIONS']
|
311
|
+
return true if TRUTHY_STRINGS.include? ENV['FORCE_MIGRATIONS']
|
312
|
+
@needs_migrations ||= begin
|
313
|
+
status 'Checking Migration Status'
|
314
|
+
(local_migration != remote_migration).tap do |val|
|
315
|
+
if val
|
316
|
+
puts 'Database out of date, Migrations are Required'
|
317
|
+
else
|
318
|
+
puts 'Database is up to date'
|
319
|
+
end
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
def remote_migration
|
325
|
+
@remote_migration ||= sha_from_migration_status deis_command("run #{LAST_MIGRATION_CMD}", app: app)
|
326
|
+
rescue NonZeroExitError
|
327
|
+
'error'
|
328
|
+
end
|
329
|
+
|
330
|
+
def local_migration
|
331
|
+
@local_migration ||= sha_from_migration_status shell(LAST_MIGRATION_CMD)
|
332
|
+
rescue NonZeroExitError
|
333
|
+
'error'
|
334
|
+
end
|
335
|
+
|
336
|
+
def sha_from_migration_status(result)
|
337
|
+
lines = result.lines.reject { |line| line.include? '**** NO FILE ****' }
|
338
|
+
migration_lines = lines.map(&:strip).select { |line| line =~ MIGRATION_REGEX }
|
339
|
+
Digest::SHA2.hexdigest migration_lines.join
|
340
|
+
end
|
341
|
+
|
342
|
+
end
|
343
|
+
|
344
|
+
end
|
345
|
+
|
346
|
+
Bundler.with_clean_env do
|
347
|
+
DeisUtils.new(ARGV).run
|
348
|
+
end
|
data/bin/setup
ADDED
data/deis-rails.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'deis/rails/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "deis-rails"
|
8
|
+
spec.version = Deis::Rails::VERSION
|
9
|
+
spec.authors = ["Jason Waldrip"]
|
10
|
+
spec.email = ["jason@waldrip.net"]
|
11
|
+
|
12
|
+
spec.summary = %q{Tools to assit with deployments of rails apps to deis}
|
13
|
+
spec.homepage = "https://github.com/brandfolder/deis-rails"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = "exe"
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency "activesupport", ">= 3.0"
|
22
|
+
spec.add_runtime_dependency "colorize", ">= 0.0"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.9"
|
25
|
+
spec.add_development_dependency "pry"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
end
|
data/lib/deis/rails.rb
ADDED
metadata
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: deis-rails
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jason Waldrip
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-07-10 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: colorize
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.0'
|
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.9'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.9'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
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: rake
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '10.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '10.0'
|
83
|
+
description:
|
84
|
+
email:
|
85
|
+
- jason@waldrip.net
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- ".gitignore"
|
91
|
+
- ".rspec"
|
92
|
+
- ".travis.yml"
|
93
|
+
- CODE_OF_CONDUCT.md
|
94
|
+
- Gemfile
|
95
|
+
- Gemfile.lock
|
96
|
+
- LICENSE
|
97
|
+
- LICENSE.txt
|
98
|
+
- README.md
|
99
|
+
- Rakefile
|
100
|
+
- bin/console
|
101
|
+
- bin/deis-rails
|
102
|
+
- bin/setup
|
103
|
+
- deis-rails.gemspec
|
104
|
+
- lib/deis/rails.rb
|
105
|
+
- lib/deis/rails/version.rb
|
106
|
+
homepage: https://github.com/brandfolder/deis-rails
|
107
|
+
licenses:
|
108
|
+
- MIT
|
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: Tools to assit with deployments of rails apps to deis
|
130
|
+
test_files: []
|
131
|
+
has_rdoc:
|