handshake_service 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5b0c53862aa69276500c0eac25fc64bc5108065a
4
- data.tar.gz: aa31a03538a462fd7d917d25e8beca4ff779137e
3
+ metadata.gz: b6014221044bffc0d210e7aecf741aae989ab3f4
4
+ data.tar.gz: 4952eb9e23bd09eb0580c194a5d2300e5405b2e3
5
5
  SHA512:
6
- metadata.gz: 736a7c34be6c55f67551d5463efe994c70a69de1ba40bd36aae5cf635b905d936d3fa1212cff7582541512b33f6cb8feb81fb07b00b19bff1164c232703258ee
7
- data.tar.gz: 1d2b5048abd8a886f2a4d4955beebed6a936e068e24f6564bf7b1a010ef13c76fcf0dce0ca8b8ffeefba6776d5f71b44ae5b1e5cafe7c45dd81308a3821a5c2a
6
+ metadata.gz: 3b97a0224445c81ae9dbb49a28e408c34feea6b6b9b206ff74edc310049c34721f8541d7aee24909891daf5ef8a05384f08b88f3ab2f3e05a875dfb361957202
7
+ data.tar.gz: 4a107452724cdca291e87c1d51fdefad4636344a1188e4e112611ccc47265126dd7a3249a5bb5880d4f747e523aeddf03ab95812309250646158cc53bb8a6f9a
@@ -1,3 +1,3 @@
1
1
  module HandshakeService
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -0,0 +1,34 @@
1
+ # NOTE: only doing this in development as some production environments (Heroku)
2
+ # NOTE: are sensitive to local FS writes, and besides -- it's just not proper
3
+ # NOTE: to have a dev-mode tool do its thing in production.
4
+ if(Rails.env.development?)
5
+ task :set_annotation_options do
6
+ # You can override any of these by setting an environment variable of the
7
+ # same name.
8
+ Annotate.set_defaults({
9
+ 'position_in_routes' => "before",
10
+ 'position_in_class' => "before",
11
+ 'position_in_test' => "before",
12
+ 'position_in_fixture' => "before",
13
+ 'position_in_factory' => "before",
14
+ 'show_indexes' => "true",
15
+ 'simple_indexes' => "false",
16
+ 'model_dir' => "app/models",
17
+ 'include_version' => "false",
18
+ 'require' => "",
19
+ 'exclude_tests' => "false",
20
+ 'exclude_fixtures' => "false",
21
+ 'exclude_factories' => "false",
22
+ 'ignore_model_sub_dir' => "false",
23
+ 'skip_on_db_migrate' => "false",
24
+ 'format_bare' => "true",
25
+ 'format_rdoc' => "false",
26
+ 'format_markdown' => "false",
27
+ 'sort' => "false",
28
+ 'force' => "false",
29
+ 'trace' => "false",
30
+ })
31
+ end
32
+
33
+ Annotate.load_tasks
34
+ end
@@ -0,0 +1,327 @@
1
+ require 'librato/metrics'
2
+
3
+ # A collection of rake tasks to deploy applications to heroku. At the basic level, all that needs to be called
4
+ # in most cases is
5
+ #
6
+ # foreman run rake deploy:staging
7
+ #
8
+ # The foreman gem is used to include .env ENV variables, but if you have those defined elsewhere it can be excluded.
9
+ # Before deploying define the STAGING_APP_NAME ENV variables, etc.
10
+ #
11
+ # These rake tasks will automatically detect schema changes and deploy correctly based on that. To override
12
+ # use the 'rake deploy:staging:migrations' or 'rake deploy:staging:preboot' rake task options.
13
+ class RakeHerokuDeployer
14
+ def initialize app_env
15
+ @app_env = app_env
16
+ @app = ENV["#{app_env.to_s.upcase}_APP_NAME"]
17
+ @start_time = Time.now.to_i
18
+
19
+ if @app.blank?
20
+ puts "Please add #{app_env.to_s.upcase}_APP_NAME environment variable in order to deploy"
21
+ exit(1)
22
+ end
23
+ end
24
+
25
+ # Uses git to determine if there are any DB migrations to run
26
+ def auto_deploy
27
+ if schema_change_since_last_release?
28
+ puts "::::::: Schema Change Detected, Disabling Preboot :::::::::"
29
+ run_migrations
30
+ else
31
+ puts "::::::: No Schema Change, Preboot Enabled :::::::::"
32
+ deploy
33
+ end
34
+ end
35
+
36
+ def run_migrations
37
+ #start_deploy; turn_off_preboot; push; turn_app_off; backup; migrate; restart; run_data_migrations; turn_app_on; tag; stop_deploy;
38
+ start_deploy; turn_off_preboot; backup; push; migrate; restart; run_data_migrations; tag; stop_deploy;
39
+ end
40
+
41
+ def deploy
42
+ # turn_on_preboot; push; restart; tag;
43
+ start_deploy; turn_on_preboot; push; run_data_migrations; tag; stop_deploy;
44
+ #start_deploy; push; turn_app_off; run_data_migrations; turn_app_on; tag; stop_deploy;
45
+ end
46
+
47
+ def backup_deploy
48
+ backup; deploy;
49
+ end
50
+
51
+ def rollback
52
+ turn_app_off; push_previous; restart; turn_app_on;
53
+ end
54
+
55
+ private
56
+
57
+ # 1) Fetch remote heroku branch we are deploying to
58
+ # 2) Do a diff of our branch to the production one
59
+ # 3) See if any migrations were added
60
+ def schema_change_since_last_release?
61
+ remote_name = "#{@app}-deployer"
62
+ system("git remote add #{remote_name} git@heroku.com:#{@app}.git") # may already exist, don't error if so
63
+ exit(1) unless system("git fetch #{remote_name}")
64
+ diff = `git diff --name-only #{remote_name}/master`
65
+
66
+ if diff.blank? # If we get back an empty diff we either have an error or don't want to deploy anyways
67
+ puts 'No diff for deploying'
68
+ exit(0) # No need to fail, just exit. Also means nightly builds are green :).
69
+ end
70
+
71
+ exit(1) unless system("git remote remove #{remote_name}")
72
+ diff.include?("db/migrate/")
73
+ end
74
+
75
+ # Nice to see how long things run
76
+ def print_current_time
77
+ puts Time.now
78
+ end
79
+
80
+ def start_deploy
81
+ return unless ENV["NEPTUNE_API_KEY"].present?
82
+ puts 'Turning off the neptune API while deploy is happening...'
83
+ puts 'curl -X GET "https://www.neptune.io/api/v1/maintenance/<api_key>/on'
84
+ puts `curl -X GET 'https://www.neptune.io/api/v1/maintenance/#{ENV["NEPTUNE_API_KEY"]}/on'`
85
+ end
86
+
87
+ def stop_deploy
88
+ return unless ENV["NEPTUNE_API_KEY"].present?
89
+ puts 'Turning on the neptune API since deploy is finished...'
90
+ puts 'curl -X GET "https://www.neptune.io/api/v1/maintenance/<api_key>/off'
91
+ puts `curl -X GET 'https://www.neptune.io/api/v1/maintenance/#{ENV["NEPTUNE_API_KEY"]}/off'`
92
+ end
93
+
94
+ def turn_on_preboot
95
+ puts 'Turning on preboot...'
96
+ puts `heroku features:enable -a #{@app} preboot`
97
+ print_current_time
98
+ end
99
+
100
+ def turn_off_preboot
101
+ puts 'Turning off preboot...'
102
+ puts `heroku features:disable -a #{@app} preboot`
103
+ print_current_time
104
+ end
105
+
106
+ def push
107
+ current_branch = `git rev-parse --abbrev-ref HEAD`.chomp
108
+ branch_to_branch = (current_branch.length > 0) ? "#{current_branch}:master" : ""
109
+ puts 'Deploying site to Heroku ...'
110
+ puts "git push git@heroku.com:#{@app}.git #{branch_to_branch}"
111
+ puts `git push git@heroku.com:#{@app}.git #{branch_to_branch}`
112
+ print_current_time
113
+ end
114
+
115
+ def restart
116
+ puts 'Restarting app servers ...'
117
+ Bundler.with_clean_env { puts `heroku restart --app #{@app}` }
118
+ print_current_time
119
+ end
120
+
121
+ def tag
122
+ return unless @app_env == :production
123
+
124
+ release_name = "#{@app}_release-#{Time.now.utc.strftime("%Y%m%d%H%M%S")}"
125
+ puts "Tagging release as '#{release_name}'"
126
+ puts `git tag -a #{release_name} -m 'Tagged release'`
127
+ puts `git push --tags git@heroku.com:#{@app}.git`
128
+ print_current_time
129
+ end
130
+
131
+ def backup
132
+ puts 'Backing up the database...'
133
+ puts "heroku pgbackups:capture --expire --app #{@app}'"
134
+ puts `heroku pgbackups:capture --expire --app #{@app}`
135
+ print_current_time
136
+ end
137
+
138
+ def migrate
139
+ puts 'Running database migrations ...'
140
+ Bundler.with_clean_env { puts `heroku run 'bundle exec rake db:migrate LOG_LEVEL=info' --app #{@app}` }
141
+ print_current_time
142
+ end
143
+
144
+ def run_data_migrations
145
+ run_custom_command_cleanly('rake data:migrate', true)
146
+ end
147
+
148
+ def run_custom_command_cleanly(command, detached = false, log_level = 'info')
149
+ Bundler.with_clean_env { puts `heroku run#{detached ? ':detached' : ''} '#{command} LOG_LEVEL=#{log_level}' --app #{@app}` }
150
+ print_current_time
151
+ end
152
+
153
+ def turn_app_off
154
+ puts 'Putting the app into maintenance mode ...'
155
+ Bundler.with_clean_env { puts `heroku maintenance:on --app #{@app}` }
156
+ print_current_time
157
+ end
158
+
159
+ def turn_app_on
160
+ puts 'Taking the app out of maintenance mode ...'
161
+ Bundler.with_clean_env { puts `heroku maintenance:off --app #{@app}` }
162
+ print_current_time
163
+ end
164
+
165
+ def push_previous
166
+ prefix = "#{@app}_release-"
167
+ releases = `git tag`.split("\n").select { |t| t[0..prefix.length-1] == prefix }.sort
168
+ current_release = releases.last
169
+ previous_release = releases[-2] if releases.length >= 2
170
+ if previous_release
171
+ puts "Rolling back to '#{previous_release}' ..."
172
+
173
+ puts "Checking out '#{previous_release}' in a new branch on local git repo ..."
174
+ puts `git checkout #{previous_release}`
175
+ puts `git checkout -b #{previous_release}`
176
+
177
+ puts "Removing tagged version '#{previous_release}' (now transformed in branch) ..."
178
+ puts `git tag -d #{previous_release}`
179
+ puts `git push git@heroku.com:#{@app}.git :refs/tags/#{previous_release}`
180
+
181
+ puts "Pushing '#{previous_release}' to Heroku master ..."
182
+ puts `git push git@heroku.com:#{@app}.git +#{previous_release}:master --force`
183
+
184
+ puts "Deleting rollbacked release '#{current_release}' ..."
185
+ puts `git tag -d #{current_release}`
186
+ puts `git push git@heroku.com:#{@app}.git :refs/tags/#{current_release}`
187
+
188
+ puts "Retagging release '#{previous_release}' in case to repeat this process (other rollbacks)..."
189
+ puts `git tag -a #{previous_release} -m 'Tagged release'`
190
+ puts `git push --tags git@heroku.com:#{@app}.git`
191
+
192
+ puts "Turning local repo checked out on master ..."
193
+ puts `git checkout master`
194
+ puts 'All done!'
195
+ else
196
+ puts "No release tags found - can't roll back!"
197
+ puts releases
198
+ end
199
+ end
200
+ end
201
+
202
+ namespace :deploy do
203
+ namespace :staging do
204
+ task :migrations do
205
+ deployer = RakeHerokuDeployer.new(:staging)
206
+ deployer.run_migrations
207
+ end
208
+
209
+ task :backup_deploy do
210
+ deployer = RakeHerokuDeployer.new(:staging)
211
+ deployer.backup_deploy
212
+ end
213
+
214
+ task :rollback do
215
+ deployer = RakeHerokuDeployer.new(:staging)
216
+ deployer.rollback
217
+ end
218
+
219
+ task :preboot do
220
+ deployer = RakeHerokuDeployer.new(:staging)
221
+ deployer.deploy
222
+ end
223
+ end
224
+
225
+ task :staging do
226
+ deployer = RakeHerokuDeployer.new(:staging)
227
+ deployer.auto_deploy
228
+ end
229
+
230
+ namespace :demo do
231
+ task :migrations do
232
+ deployer = RakeHerokuDeployer.new(:demo)
233
+ deployer.run_migrations
234
+ end
235
+
236
+ task :backup_deploy do
237
+ deployer = RakeHerokuDeployer.new(:demo)
238
+ deployer.backup_deploy
239
+ end
240
+
241
+ task :rollback do
242
+ deployer = RakeHerokuDeployer.new(:demo)
243
+ deployer.rollback
244
+ end
245
+
246
+ task :preboot do
247
+ deployer = RakeHerokuDeployer.new(:demo)
248
+ deployer.deploy
249
+ end
250
+ end
251
+
252
+ task :demo do
253
+ deployer = RakeHerokuDeployer.new(:demo)
254
+ deployer.auto_deploy
255
+ end
256
+
257
+ namespace :production do
258
+ task :migrations do
259
+ deployer = RakeHerokuDeployer.new(:production)
260
+ deployer.run_migrations
261
+ end
262
+
263
+ task :backup_deploy do
264
+ deployer = RakeHerokuDeployer.new(:production)
265
+ deployer.backup_deploy
266
+ end
267
+
268
+ task :rollback do
269
+ deployer = RakeHerokuDeployer.new(:production)
270
+ deployer.rollback
271
+ end
272
+
273
+ task :preboot do
274
+ deployer = RakeHerokuDeployer.new(:production)
275
+ deployer.deploy
276
+ end
277
+ end
278
+
279
+ task :production do
280
+ deployer = RakeHerokuDeployer.new(:production)
281
+ deployer.auto_deploy
282
+ end
283
+
284
+ task :all do
285
+ deployer = RakeHerokuDeployer.new(:staging)
286
+ deployer2 = RakeHerokuDeployer.new(:demo)
287
+ deployer3 = RakeHerokuDeployer.new(:production)
288
+ deployer.auto_deploy
289
+ deployer2.auto_deploy
290
+ deployer3.auto_deploy
291
+ end
292
+
293
+ namespace :all do
294
+ task :migrations do
295
+ deployer = RakeHerokuDeployer.new(:staging)
296
+ deployer2 = RakeHerokuDeployer.new(:demo)
297
+ deployer3 = RakeHerokuDeployer.new(:production)
298
+ deployer.run_migrations
299
+ deployer2.run_migrations
300
+ deployer3.run_migrations
301
+ end
302
+
303
+ task :backup_deploy do
304
+ deployer = RakeHerokuDeployer.new(:staging)
305
+ deployer2 = RakeHerokuDeployer.new(:demo)
306
+ deployer3 = RakeHerokuDeployer.new(:production)
307
+ deployer.backup_deploy
308
+ deployer2.backup_deploy
309
+ deployer3.backup_deploy
310
+ end
311
+
312
+ task :preboot do
313
+ deployer = RakeHerokuDeployer.new(:staging)
314
+ deployer2 = RakeHerokuDeployer.new(:demo)
315
+ deployer3 = RakeHerokuDeployer.new(:production)
316
+ deployer.deploy
317
+ deployer2.deploy
318
+ deployer3.deploy
319
+ end
320
+ end
321
+
322
+ # A Helper method to see what the output is
323
+ task :detect_schema_change do
324
+ deployer = RakeHerokuDeployer.new(:staging)
325
+ puts deployer.schema_change_since_last_release?
326
+ end
327
+ end
@@ -0,0 +1,85 @@
1
+ # Run with: rake environment elasticsearch:reindex
2
+ # Begins by creating the index using tire:import:model command. This will create the "official" index name, e.g. "things" each time.
3
+ # Then we rename it to, e.g. "things_20121001052916" and alias "things" to it.
4
+ # Assumes usage of the elasticsearch-ruby libraries
5
+ # TODO: Assumes you have a library called ElasticsearchAdminHelper defined with the right methods. Move that helper into this gem
6
+
7
+ namespace :elasticsearch do
8
+ desc 'Reindexes all ActiveRecord model indices'
9
+ task "reindex:all" => :environment do
10
+ Rails.application.eager_load!
11
+ include ElasticsearchAdminHelper
12
+
13
+ ActiveRecord::Base.descendants.each do |model_class|
14
+ next unless model_class.respond_to? :__elasticsearch__
15
+ reindex_model(model_class)
16
+ end
17
+
18
+ puts 'All indices reindexed'
19
+ end
20
+
21
+ desc 'Deletes indices and then reindexes all ActiveRecord model indices assuming none exist yet'
22
+ task "reindex:all:fresh" => :environment do
23
+ return unless Rails.env.development? or Rails.env.test?
24
+
25
+ Rails.application.eager_load!
26
+ include ElasticsearchAdminHelper
27
+
28
+ # If we don't create the temporary indices, then mass emails (for example) will try
29
+ # to query users for recipient count and fail
30
+ ActiveRecord::Base.descendants.each do |model_class|
31
+ next unless model_class.respond_to? :__elasticsearch__
32
+ delete_index(model_class.index_name)
33
+ create_temporary_index(model_class)
34
+ end
35
+
36
+ ActiveRecord::Base.descendants.each do |model_class|
37
+ next unless model_class.respond_to? :__elasticsearch__
38
+ reindex_model(model_class, true)
39
+ end
40
+
41
+ puts 'All indices created, aliased and ready'
42
+ end
43
+
44
+ desc 'Deletes indices and then reindexes all ActiveRecord model indices assuming none exist yet. Is used for testing where aliases are not used'
45
+ task "tests:prepare" => :environment do
46
+ return unless Rails.env.development? or Rails.env.test?
47
+
48
+ Rails.application.eager_load!
49
+ include ElasticsearchAdminHelper
50
+
51
+ # If we don't create the temporary indices, then mass emails (for example) will try
52
+ # to query users for recipient count and fail
53
+ ActiveRecord::Base.descendants.each do |model_class|
54
+ next unless model_class.respond_to? :__elasticsearch__
55
+ delete_index(model_class.index_name)
56
+ create_temporary_index(model_class)
57
+ end
58
+
59
+ puts 'All indices created, aliased and ready'
60
+ end
61
+
62
+ Dir.foreach("#{Rails.root}/app/models") do |item|
63
+ next if item == '.' or item == '..' or not item
64
+ name = item.split(".")[0].pluralize
65
+
66
+ desc "Reindexes #{name} using aliases"
67
+ task "reindex:#{name}" => :environment do
68
+ Rails.application.eager_load!
69
+ include ElasticsearchAdminHelper
70
+
71
+ klass = Kernel.const_get(name.classify)
72
+ reindex_model(klass)
73
+ end
74
+
75
+ desc "Reindexes #{name} using aliases, and deletes the old one first" # because Tire tries to create an index for us sometimes
76
+ task "reindex:#{name}:delete_old_first" => :environment do
77
+ Rails.application.eager_load!
78
+ include ElasticsearchAdminHelper
79
+
80
+ klass = Kernel.const_get(name.classify)
81
+ reindex_model(klass, true)
82
+ end
83
+
84
+ end
85
+ end
@@ -0,0 +1,16 @@
1
+ # A simple collection of convenient rake tasks for heroku deployed applications
2
+ namespace :heroku do
3
+ namespace :maintenance do
4
+ task :on do
5
+ app = ENV['APPLICATION_NAME']
6
+ puts `heroku maintenance:on -a #{app}`
7
+ puts `heroku ps:scale worker=0 urgent=0 clock=0 -a #{app}`
8
+ end
9
+
10
+ task :off do
11
+ app = ENV['APPLICATION_NAME']
12
+ puts `heroku maintenance:off -a #{app}`
13
+ puts `heroku ps:scale worker=2 urgent=2 clock=1 -a #{app}`
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,34 @@
1
+ # Simple helpers to find invalid records and print why they are invalid. May
2
+ # take a while to run depending on size of data
3
+ namespace :invalids do
4
+ Dir.foreach("#{Rails.root}/app/models") do |item|
5
+ next if item == '.' or item == '..' or not item
6
+ name = item.split(".")[0].pluralize
7
+
8
+ desc "Finds invalid records for #{name} scaffold"
9
+ task "find:#{name}" => :environment do
10
+ Rails.application.eager_load!
11
+ klass = Kernel.const_get(name.classify)
12
+
13
+ invalids = []
14
+ index = 0
15
+ klass.find_each do |obj|
16
+ index += 1
17
+
18
+ if index % 1000 == 0
19
+ ap "invalids at index #{index}"
20
+ ap invalids
21
+ end
22
+
23
+ next if obj.valid?
24
+ invalids << { id: obj.id, errors: obj.errors }
25
+ end
26
+
27
+ ap "Invalids at end:"
28
+ ap invalids
29
+
30
+ # This is used for log based alerts
31
+ ap "LOG NOTIFIER: INVALID RECORDS EXIST" if invalids.count > 0
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,23 @@
1
+ # Finds missing rspec files and generates them for you. May take a while to run, depending
2
+ # on the number of scaffolds in the project.
3
+ namespace :rspec_generator do
4
+ desc 'Generate rspec specs for all scaffolds that are missing specs'
5
+ task :generate => :environment do
6
+ Rails.application.eager_load!
7
+
8
+ # Iterate over all 'normal' active record classes. By normal
9
+ # I mean that rails includes habtm join tables in the list
10
+ # which we don't want.
11
+ ActiveRecord::Base.descendants.each do |model_class|
12
+ next if model_class.name.starts_with?("HABTM_")
13
+ generate_for_model(model_class)
14
+ end
15
+ end
16
+
17
+ def generate_for_model(model_class)
18
+ underscore_name = model_class.name.underscore
19
+ puts "Generating missing specs for #{underscore_name}"
20
+ system("rails g rspec:scaffold #{underscore_name} -s --view-specs=false --controller-specs=false --request-specs=true")
21
+ system("rails g rspec:model #{underscore_name} -s")
22
+ end
23
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: handshake_service
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Ringwelski
@@ -71,6 +71,12 @@ files:
71
71
  - handshake_service.gemspec
72
72
  - lib/handshake_service.rb
73
73
  - lib/handshake_service/version.rb
74
+ - lib/tasks/auto_annotate_models.rake
75
+ - lib/tasks/deploy.rake
76
+ - lib/tasks/elasticsearch.rake
77
+ - lib/tasks/heroku.rake
78
+ - lib/tasks/invalids.rake
79
+ - lib/tasks/rspec_generator.rake
74
80
  homepage: https://github.com/strydercorp/handshake_service
75
81
  licenses:
76
82
  - MIT