wildland_dev_tools 0.8.2
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 +9 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +60 -0
- data/Rakefile +6 -0
- data/lib/tasks/heroku.rake +99 -0
- data/lib/tasks/releases.rake +15 -0
- data/lib/tasks/reports.rake +103 -0
- data/lib/tasks/setup.rake +66 -0
- data/lib/wildland_dev_tools/heroku.rb +200 -0
- data/lib/wildland_dev_tools/railtie.rb +15 -0
- data/lib/wildland_dev_tools/releases.rb +50 -0
- data/lib/wildland_dev_tools/updater.rb +66 -0
- data/lib/wildland_dev_tools/version.rb +3 -0
- data/lib/wildland_dev_tools.rb +11 -0
- data/wildland_dev_tools.gemspec +28 -0
- metadata +152 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7b433a7be6f2d7f72a20ca3fc146235b2b8f175a
|
4
|
+
data.tar.gz: 55423134402dc24c52c13af9e255b95dd66ce843
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 898bc400966c8fbf623656a25778a90f0e74345a88648116556004c03bbe9bc08db1b5667360967d0e6f3883fd8dfc37cdae37d7819e7bfd2169e0af965a28e7
|
7
|
+
data.tar.gz: 7620f5d507ce2fcaa86b7d33dc7aee650b5c1058638a9ae5b4eefe9a16e219bb9a83db29b3270eb52449895f859a74bca6e9fb103b5a411151de8ee4ff2df1e2
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Joe Weakley
|
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,60 @@
|
|
1
|
+
# Wildland DevTools
|
2
|
+
This is a gem that contains all of our dev rake tasks.
|
3
|
+
These are most useful for projects created by [trailhead](https://github.com/wildland/trailhead) and are deployed on [heroku](https://www.heroku.com/home) using the [pipeline](https://devcenter.heroku.com/articles/pipelines) feature. This allows for separate `staging` and `production` enviroments as well as review apps.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add the following to your `Gemfile`:
|
8
|
+
|
9
|
+
`gem 'wildland_dev_tools', '~>0.8.1', github: 'wildland/wildland_dev_tools'`
|
10
|
+
|
11
|
+
Typically for wildland projects you will want to put this inside the dev/test block:
|
12
|
+
```
|
13
|
+
group :development, :test do
|
14
|
+
...
|
15
|
+
gem 'wildland_dev_tools', '~>0.8.1', github: 'wildland/wildland_dev_tools'`
|
16
|
+
...
|
17
|
+
end
|
18
|
+
```
|
19
|
+
|
20
|
+
### *[heroku tools](https://github.com/wildland/wildland_dev_tools#heroku-tools) require the following steps*
|
21
|
+
|
22
|
+
Install the heroku-toolbelt using brew. You can do this by running `brew install heroku`.
|
23
|
+
|
24
|
+
Have your `production` and `staging` git remotes set.
|
25
|
+
- `heroku git:remote -a <staging-app> -r staging` where `<staging-app>` is your heroku staging app name.
|
26
|
+
- `heroku git:remote -a <production-app> -r production` where `<production-app>` is your heroku production app name.
|
27
|
+
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
You will get a new batch of new rake tasks under the wildland namespace. For a full list run `rake -T`.
|
31
|
+
|
32
|
+
### Local Development Tools
|
33
|
+
*Note that you will need to run `bundle install` before being able to use these.*
|
34
|
+
|
35
|
+
*Double Note: if `bundle install` borks on `pg_config` then set the `Pg_config path` with `bundle config build.pg --with-pg-config=/Applications/Postgres.app/Contents/Versions/{YOUR VERSION}/bin/pg_config`
|
36
|
+
|
37
|
+
- `rake wildland:setup` This will run all of the setup tasks to get your local enviroment ready to go.
|
38
|
+
- `rake wildland:db` This will resetup and seed the local database.
|
39
|
+
- `rake wildland:cache_clear` This will clear the local app-ember package cache.
|
40
|
+
- `rake wildland:pre_deploy` This will run all of the pre-deploy tasks to get the project ready to deploy.
|
41
|
+
- `rake wildland:pre_pr` Convenience alias to `rake wildland:pre_pull_request`.
|
42
|
+
- `rake wildland:pre_pull_request` This will run all of the pre pull request tasks to get the project ready for a pull request.
|
43
|
+
|
44
|
+
### Heroku Tools
|
45
|
+
- `rake wildland:heroku:deploy_to_staging` This will deploy `master` to `staging`. This will automatically create a release candidate git tag.
|
46
|
+
- `rake wildland:heroku:deploy_to_staging[verbose]` This perform the deploy as above, but in verbose mode.
|
47
|
+
- - `rake wildland:heroku:deploy_to_staging[verbose,force]` This perform the deploy as above, but this will `--force` deploy `master` to `staging`.
|
48
|
+
- - `rake wildland:heroku:deploy_current_branch_to_staging` This will promote your current branch to `staging` as `master`. This will **NOT** automatically create a release candidate git tag.
|
49
|
+
- - `rake wildland:heroku:deploy_current_branch_to_staging[verbose]` This perform the deploy as above, but in verbose mode.
|
50
|
+
- - `rake wildland:heroku:deploy_current_branch_to_staging[verbose,force]` This perform the deploy as above, but this will `--force` deploy your current branch to `staging`.
|
51
|
+
- `rake wildland:heroku:promote_to_production` This will promote `staging` to `production`. This will automatically create a production git tag.
|
52
|
+
- `rake wildland:heroku:promote_to_production[verbose]` This perform the deploy as above, but in verbose mode.
|
53
|
+
- `rake wildland:heroku:maintenance_mode_on` This turns on maintenance mode for `staging` and `production`.
|
54
|
+
- `rake wildland:heroku:maintenance_mode_off` This turns off maintenance mode for `staging` and `production`.
|
55
|
+
- `rake wildland:heroku:backup_production_database[verbose]` This will create a backup of the `production` database.
|
56
|
+
- `rake wildland:heroku:import_latest_production_database_backup[verbose]` This will import the latest `production` database backup to your local database.
|
57
|
+
|
58
|
+
|
59
|
+
## Code Of Conduct
|
60
|
+
Wildland Open Source [Code Of Conduct](https://github.com/wildland/code-of-conduct)
|
data/Rakefile
ADDED
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'wildland_dev_tools/heroku'
|
2
|
+
|
3
|
+
namespace :wildland do
|
4
|
+
namespace :heroku do
|
5
|
+
desc 'Imports the latest production database backup to local database.'
|
6
|
+
task :import_latest_production_database_backup, [:verbose] => [:check_remotes, :check_heroku] do |_t, args| # rubocop:disable Metrics/LineLength
|
7
|
+
WildlandDevTools::Heroku.import_production_database(args[:verbose])
|
8
|
+
Rake::Task['db:migrate'].invoke
|
9
|
+
end
|
10
|
+
|
11
|
+
desc 'Backups production database'
|
12
|
+
task :backup_production_database, [:verbose] => [:check_remotes, :check_heroku] do |_t, args| # rubocop:disable Metrics/LineLength
|
13
|
+
WildlandDevTools::Heroku.backup_production_database(args[:verbose])
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'Promotes staging to production. This automatically creates a production release tag.'
|
17
|
+
task :promote_to_production, [:verbose] => [:check_remotes, :check_heroku] do |_t, args| # rubocop:disable Metrics/LineLength
|
18
|
+
begin
|
19
|
+
Rake::Task['wildland:heroku:maintenance_mode_on'].execute
|
20
|
+
Rake::Task['wildland:releases:create_release_tag'].execute
|
21
|
+
WildlandDevTools::Heroku.promote_staging_to_production(args[:verbose])
|
22
|
+
WildlandDevTools::Heroku.migrate_production_database(args[:verbose])
|
23
|
+
Rake::Task['wildland:heroku:maintenance_mode_off'].execute
|
24
|
+
rescue RuntimeError => e
|
25
|
+
puts e
|
26
|
+
WildlandDevTools::Heroku.rollback_production_deploy(true)
|
27
|
+
raise
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
desc 'Deploy master to staging. This automatically creates a release candidate tag.'
|
32
|
+
task :deploy_to_staging, [:verbose, :force] => [:check_remotes, :check_heroku] do |_t, args| # rubocop:disable Metrics/LineLength
|
33
|
+
begin
|
34
|
+
WildlandDevTools::Heroku.turn_on_staging_maintenance_mode(args[:verbose])
|
35
|
+
Rake::Task['wildland:releases:create_release_candidate_tag'].execute
|
36
|
+
WildlandDevTools::Heroku.deploy_master_to_staging(args[:verbose], args[:force])
|
37
|
+
WildlandDevTools::Heroku.copy_production_data_to_staging(args[:verbose])
|
38
|
+
WildlandDevTools::Heroku.migrate_staging_database(args[:verbose])
|
39
|
+
rescue WildlandDevTools::GitSyncException => e
|
40
|
+
puts e
|
41
|
+
rescue RuntimeError => e
|
42
|
+
puts e
|
43
|
+
WildlandDevTools::Heroku.rollback_staging_deploy(true)
|
44
|
+
raise
|
45
|
+
ensure
|
46
|
+
WildlandDevTools::Heroku.turn_off_staging_maintenance_mode(args[:verbose])
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
desc 'Deploy current branch to staging as master. This does not create a release canidate tag.'
|
51
|
+
task :deploy_current_branch_to_staging, [:verbose, :force] => [:check_remotes, :check_heroku] do |_t, args| # rubocop:disable Metrics/LineLength
|
52
|
+
begin
|
53
|
+
WildlandDevTools::Heroku.turn_on_staging_maintenance_mode(args[:verbose])
|
54
|
+
WildlandDevTools::Heroku.deploy_current_branch_to_staging(args[:verbose], args[:force])
|
55
|
+
WildlandDevTools::Heroku.copy_production_data_to_staging(args[:verbose])
|
56
|
+
WildlandDevTools::Heroku.migrate_staging_database(args[:verbose])
|
57
|
+
rescue WildlandDevTools::GitSyncException => e
|
58
|
+
puts e
|
59
|
+
rescue RuntimeError => e
|
60
|
+
puts e
|
61
|
+
WildlandDevTools::Heroku.rollback_staging_deploy(true)
|
62
|
+
raise
|
63
|
+
ensure
|
64
|
+
WildlandDevTools::Heroku.turn_off_staging_maintenance_mode(args[:verbose])
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
desc 'Turns on maintenance mode for both heroku remotes.'
|
69
|
+
task :maintenance_mode_on do
|
70
|
+
WildlandDevTools::Heroku.turn_on_heroku_maintenance_mode(true)
|
71
|
+
end
|
72
|
+
|
73
|
+
desc 'Turns off maintenance mode for both heroku remotes.'
|
74
|
+
task :maintenance_mode_off do
|
75
|
+
WildlandDevTools::Heroku.turn_off_heroku_maintenance_mode(true)
|
76
|
+
end
|
77
|
+
|
78
|
+
task :check_heroku do
|
79
|
+
unless WildlandDevTools::Heroku.heroku_toolbelt_available?
|
80
|
+
Kernel.abort(
|
81
|
+
'Missing heroku toolbelt. Run \'brew install heroku-toolbelt\'.'
|
82
|
+
)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
task :check_remotes do
|
87
|
+
unless WildlandDevTools::Heroku.staging_remote_available?
|
88
|
+
Kernel.abort(
|
89
|
+
'Missing staging git remote. Run \'heroku git:remote -a <app-name> -r staging\'' # rubocop:disable Metrics/LineLength
|
90
|
+
)
|
91
|
+
end
|
92
|
+
unless WildlandDevTools::Heroku.production_remote_available?
|
93
|
+
Kernel.abort(
|
94
|
+
'Missing production git remote. Run \'heroku git:remote -a <app-name> -r production\'' # rubocop:disable Metrics/LineLength
|
95
|
+
)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'wildland_dev_tools/releases'
|
2
|
+
|
3
|
+
namespace :wildland do
|
4
|
+
namespace :releases do
|
5
|
+
desc 'Creates a git tag for the release.'
|
6
|
+
task :create_release_tag, [:verbose] do |_t, args|
|
7
|
+
WildlandDevTools::Releases.create_release(args[:verbose])
|
8
|
+
end
|
9
|
+
|
10
|
+
desc 'Creates a git tag for the release candidate.'
|
11
|
+
task :create_release_candidate_tag, [:verbose] do |_t, args|
|
12
|
+
WildlandDevTools::Releases.create_release_candidate(args[:verbose])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,103 @@
|
|
1
|
+
namespace :wildland do
|
2
|
+
desc 'Runs all the pre pull request tasks.'
|
3
|
+
task :pre_pull_request do
|
4
|
+
Rake::Task['wildland:pre_pull_request:all'].invoke
|
5
|
+
end
|
6
|
+
desc 'Alias to pre pull request.'
|
7
|
+
task :pre_pr do
|
8
|
+
Rake::Task['wildland:pre_pull_request'].invoke
|
9
|
+
end
|
10
|
+
namespace :pre_pull_request do
|
11
|
+
task all: [
|
12
|
+
:notes,
|
13
|
+
:fixme_notes,
|
14
|
+
:ruby_debugger,
|
15
|
+
:js_debugger,
|
16
|
+
:rubocop_recent
|
17
|
+
] do
|
18
|
+
puts 'PR Check completed.'
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'Run brakeman & rubocop with html formats and save them to /reports'
|
22
|
+
task :html do
|
23
|
+
system 'bundle exec rubocop -RDf progress -f html -o reports/rubocop.html'
|
24
|
+
system 'bundle exec brakeman -o reports/brakeman.html'
|
25
|
+
end
|
26
|
+
|
27
|
+
desc 'Create a report on all notes'
|
28
|
+
task :notes do
|
29
|
+
puts "\nCollecting all of the standard code notes..."
|
30
|
+
system 'bin/rake notes'
|
31
|
+
puts "\nCollecting all HACK code notes..."
|
32
|
+
system 'bin/rake notes:custom ANNOTATION=HACK'
|
33
|
+
puts "\nCollecting all spec code notes..."
|
34
|
+
system "grep -rnE 'OPTIMIZE:|OPTIMIZE|FIXME:|FIXME|TODO:|TODO|HACK:|HACK'"\
|
35
|
+
' spec'
|
36
|
+
end
|
37
|
+
|
38
|
+
desc 'Print only FIXME notes'
|
39
|
+
task :fixme_notes do
|
40
|
+
puts "\nFIXME Notes:"
|
41
|
+
system 'bin/rake notes:fixme'
|
42
|
+
system "grep -rnE 'FIXME:|FIXME'"\
|
43
|
+
' spec'
|
44
|
+
system "grep -rnE 'FIXME:|FIXME'"\
|
45
|
+
' app/views'
|
46
|
+
end
|
47
|
+
|
48
|
+
desc 'Find ruby debugger statements.'
|
49
|
+
task :ruby_debugger do
|
50
|
+
puts "\nRuby debuggers:"
|
51
|
+
%w(binding.pry puts).each do |debugger|
|
52
|
+
%w(app/).each do |dir|
|
53
|
+
system "grep -rnE '#{debugger}' #{dir}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
desc 'Find js debugger statements.'
|
59
|
+
task :js_debugger do
|
60
|
+
puts "\nJS debuggers:"
|
61
|
+
%w(debugger).each do |debugger|
|
62
|
+
%w(app-ember/app).each do |dir|
|
63
|
+
system "grep -rnE '#{debugger}' #{dir}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
desc 'Run rubocop against all created/changed ruby files'
|
69
|
+
task :rubocop_recent, [:autocorrect] do |_t, args|
|
70
|
+
puts 'Running rubocop...'
|
71
|
+
require 'rubocop'
|
72
|
+
|
73
|
+
module RuboCop
|
74
|
+
# :nodoc:
|
75
|
+
class TargetFinder
|
76
|
+
def find(_args)
|
77
|
+
changed_git_files = `git diff --name-only --cached`.split(/\n/)
|
78
|
+
|
79
|
+
rubocop_target_finder = RuboCop::TargetFinder.new(
|
80
|
+
RuboCop::ConfigStore.new
|
81
|
+
)
|
82
|
+
rubocop_config_store = RuboCop::ConfigStore.new
|
83
|
+
rubocop_base_config = rubocop_config_store.for(
|
84
|
+
File.expand_path(__dir__)
|
85
|
+
)
|
86
|
+
|
87
|
+
files_to_check = changed_git_files.select do |file|
|
88
|
+
rubocop_target_finder.to_inspect?(file, [], rubocop_base_config)
|
89
|
+
end
|
90
|
+
|
91
|
+
files_to_check
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
if args[:autocorrect]
|
97
|
+
exit RuboCop::CLI.new.run(['-aD'])
|
98
|
+
else
|
99
|
+
exit RuboCop::CLI.new.run(['-D'])
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'wildland_dev_tools/updater'
|
2
|
+
|
3
|
+
namespace :wildland do
|
4
|
+
desc 'Updates local dependencies and database.'
|
5
|
+
task setup: [:update_ruby, :update_node, :update_ember_dependencies, :database_online, :db] do
|
6
|
+
puts 'Ready to go!'
|
7
|
+
end
|
8
|
+
|
9
|
+
task :update_ruby do
|
10
|
+
needed_ruby_version = File.read('.ruby-version')
|
11
|
+
if WildlandDevTools::Updater.ruby_version_up_to_date?(needed_ruby_version)
|
12
|
+
puts 'up to date.'
|
13
|
+
else
|
14
|
+
puts 'out of date. Updating.'
|
15
|
+
WildlandDevTools::Updater.update_ruby(needed_ruby_version)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
task :update_node do
|
20
|
+
puts 'Node updater needs written'
|
21
|
+
end
|
22
|
+
|
23
|
+
task :update_ember_dependencies do
|
24
|
+
if WildlandDevTools::Updater.ember_cli_rails_installed?
|
25
|
+
puts 'ember-cli-rails installed'
|
26
|
+
system('npm install')
|
27
|
+
else
|
28
|
+
puts 'install ember dependencies'
|
29
|
+
WildlandDevTools::Updater.old_ember_setup
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
desc 'Clears local cache.'
|
34
|
+
task :cache_clear do
|
35
|
+
WildlandDevTools::Updater.clear_ember_cache
|
36
|
+
end
|
37
|
+
|
38
|
+
task :database_online do
|
39
|
+
unless `ps aux | grep postgres[l]` != ''
|
40
|
+
`open -a postgres`
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
namespace :db do
|
45
|
+
desc 'Resets the database.'
|
46
|
+
task :reset do
|
47
|
+
WildlandDevTools::Updater.reset_database
|
48
|
+
end
|
49
|
+
|
50
|
+
desc 'Reseeds the database.'
|
51
|
+
task :reseed do
|
52
|
+
WildlandDevTools::Updater.reseed_database
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
desc 'Resets and reseeds the database.'
|
57
|
+
task :db do
|
58
|
+
Rake::Task['wildland:db:reset'].execute
|
59
|
+
Rake::Task['wildland:db:reseed'].execute
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
desc 'Gets development environment setup.'
|
64
|
+
task :wildland do
|
65
|
+
Rake::Task['wildland:setup'].invoke
|
66
|
+
end
|
@@ -0,0 +1,200 @@
|
|
1
|
+
require 'git'
|
2
|
+
module WildlandDevTools
|
3
|
+
# :nodoc:
|
4
|
+
module Heroku
|
5
|
+
VALID_REMOTES = %w(production staging)
|
6
|
+
|
7
|
+
class << self
|
8
|
+
def rollback_production_deploy(verbose = false)
|
9
|
+
rollback_production_codebase(verbose)
|
10
|
+
rollback_production_database(verbose)
|
11
|
+
end
|
12
|
+
|
13
|
+
def turn_on_staging_maintenance_mode(verbose = false)
|
14
|
+
remote = 'staging'
|
15
|
+
puts "Turning on maintenance mode for #{remote}" if verbose
|
16
|
+
system("heroku maintenance:on -r #{remote}")
|
17
|
+
end
|
18
|
+
|
19
|
+
def turn_off_staging_maintenance_mode(verbose = false)
|
20
|
+
remote = 'staging'
|
21
|
+
puts "Turning off maintenance mode for #{remote}" if verbose
|
22
|
+
system("heroku maintenance:off -r #{remote}")
|
23
|
+
end
|
24
|
+
|
25
|
+
def turn_on_heroku_maintenance_mode(verbose = false)
|
26
|
+
%w(staging production).each do |remote|
|
27
|
+
puts "Turning on maintenance mode for #{remote}" if verbose
|
28
|
+
system("heroku maintenance:on -r #{remote}")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def turn_off_heroku_maintenance_mode(verbose = false)
|
33
|
+
%w(staging production).each do |remote|
|
34
|
+
puts "Turning off maintenance mode for #{remote}" if verbose
|
35
|
+
system("heroku maintenance:off -r #{remote}")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def deploy_master_to_staging(verbose = false, force = false)
|
40
|
+
puts 'Detecting current branch name.' if verbose
|
41
|
+
branch = get_current_branch_name
|
42
|
+
raise GitSyncException, 'Please checkout master branch' unless branch == 'master'
|
43
|
+
deploy_to_staging(branch, verbose, force)
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def deploy_current_branch_to_staging(verbose = false, force = false)
|
48
|
+
puts 'Detecting current branch name.' if verbose
|
49
|
+
branch = get_current_branch_name
|
50
|
+
deploy_to_staging(branch, verbose, force)
|
51
|
+
end
|
52
|
+
|
53
|
+
def deploy_to_staging(branch, verbose = false, force = false)
|
54
|
+
case status_of_current_branch
|
55
|
+
when 'Up-to-date'
|
56
|
+
if force
|
57
|
+
puts "Force deploying #{branch} to staging." if verbose
|
58
|
+
system("OVERCOMMIT_DISABLE=1 git push -f staging #{branch}:master")
|
59
|
+
else
|
60
|
+
puts "Deploying #{branch} to staging." if verbose
|
61
|
+
system("OVERCOMMIT_DISABLE=1 git push staging #{branch}:master")
|
62
|
+
end
|
63
|
+
when 'Need to pull'
|
64
|
+
raise GitSyncException, "Need to pull #{branch} from origin."
|
65
|
+
when 'Need to push'
|
66
|
+
raise GitSyncException, "Need to push #{branch} to origin."
|
67
|
+
else
|
68
|
+
raise GitSyncException, "Your local #{branch} has diverged from origin."
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def promote_staging_to_production(verbose = false)
|
73
|
+
puts 'Promoting staging to production' if verbose
|
74
|
+
system('heroku pipelines:promote -r staging')
|
75
|
+
end
|
76
|
+
|
77
|
+
def import_production_database(verbose = false)
|
78
|
+
puts 'Determining heroku app names.' if verbose
|
79
|
+
production_app_name = get_app_name('production', verbose)
|
80
|
+
scratch_file_name = 'latest.dump'
|
81
|
+
database_name = Rails.configuration.database_configuration['development']['database']
|
82
|
+
download_database(production_app_name, scratch_file_name, verbose)
|
83
|
+
import_database(database_name, scratch_file_name, verbose)
|
84
|
+
File.delete(scratch_file_name)
|
85
|
+
end
|
86
|
+
|
87
|
+
def copy_production_data_to_staging(verbose = false)
|
88
|
+
puts 'Determining heroku app names.' if verbose
|
89
|
+
staging_app_name = get_app_name('staging', verbose)
|
90
|
+
production_app_name = get_app_name('production', verbose)
|
91
|
+
puts "Copying #{production_app_name} database to #{staging_app_name}." if verbose
|
92
|
+
system(
|
93
|
+
"heroku pg:copy #{production_app_name}::DATABASE_URL DATABASE_URL -a #{staging_app_name} --confirm #{staging_app_name}"
|
94
|
+
)
|
95
|
+
end
|
96
|
+
|
97
|
+
def backup_production_database(verbose = false)
|
98
|
+
remote = 'production'
|
99
|
+
puts "Backing up the database for #{remote}" if verbose
|
100
|
+
system("heroku pg:backups capture DATABASE -r #{remote}")
|
101
|
+
end
|
102
|
+
|
103
|
+
def migrate_production_database(verbose = false)
|
104
|
+
migrate_database('production', verbose)
|
105
|
+
end
|
106
|
+
|
107
|
+
def migrate_staging_database(verbose = false)
|
108
|
+
migrate_database('staging', verbose)
|
109
|
+
end
|
110
|
+
|
111
|
+
def rollback_production_database(verbose = false)
|
112
|
+
rollback_codebase('production', verbose)
|
113
|
+
end
|
114
|
+
|
115
|
+
def rollback_staging_database(verbose = false)
|
116
|
+
rollback_database('staging', verbose)
|
117
|
+
end
|
118
|
+
|
119
|
+
def staging_remote_available?
|
120
|
+
Git.open('.').remotes.map(&:to_s).include?('staging')
|
121
|
+
end
|
122
|
+
|
123
|
+
def production_remote_available?
|
124
|
+
Git.open('.').remotes.map(&:to_s).include?('production')
|
125
|
+
end
|
126
|
+
|
127
|
+
def heroku_toolbelt_available?
|
128
|
+
system('which heroku > /dev/null 2>&1')
|
129
|
+
end
|
130
|
+
|
131
|
+
protected
|
132
|
+
|
133
|
+
def download_database(app_name, filename, verbose = false)
|
134
|
+
puts "Downloading #{app_name} database to tmp file #{filename}" if verbose
|
135
|
+
system(
|
136
|
+
"curl -o #{filename} `heroku pg:backups:public-url --app #{app_name}`"
|
137
|
+
)
|
138
|
+
end
|
139
|
+
|
140
|
+
def import_database(database_name, filename, verbose = false)
|
141
|
+
puts "Importing #{filename} to #{database_name}" if verbose
|
142
|
+
system(
|
143
|
+
"pg_restore --clean --no-owner --no-acl --dbname=#{database_name} #{filename}"
|
144
|
+
)
|
145
|
+
end
|
146
|
+
|
147
|
+
def rollback_codebase(remote, verbose = false)
|
148
|
+
ensure_valid_remote(remote)
|
149
|
+
puts "Rolling back #{remote}" if verbose
|
150
|
+
system("heroku rollback #{remote}")
|
151
|
+
end
|
152
|
+
|
153
|
+
def rollback_database(remote, verbose = false)
|
154
|
+
ensure_valid_remote(remote)
|
155
|
+
if verbose
|
156
|
+
puts "Manually restore database for #{remote}"
|
157
|
+
puts 'Then run \"rake wildland:heroku:maintenance_mode_off\"'
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def migrate_database(remote, verbose = false)
|
162
|
+
ensure_valid_remote(remote)
|
163
|
+
puts "Migrating the database for #{remote}" if verbose
|
164
|
+
system("heroku run rake db:migrate -r #{remote}")
|
165
|
+
end
|
166
|
+
|
167
|
+
def status_of_current_branch
|
168
|
+
local = `OVERCOMMIT_DISABLE=1 git rev-parse @`
|
169
|
+
remote = `OVERCOMMIT_DISABLE=1 git rev-parse @{u}`
|
170
|
+
base = `OVERCOMMIT_DISABLE=1 git merge-base @ @{u}`
|
171
|
+
case
|
172
|
+
when local == remote
|
173
|
+
'Up-to-date'
|
174
|
+
when local == base
|
175
|
+
'Need to pull'
|
176
|
+
when remote == base
|
177
|
+
'Need to push'
|
178
|
+
else
|
179
|
+
'Diverged'
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
def get_current_branch_name
|
184
|
+
`git rev-parse --abbrev-ref HEAD`.strip
|
185
|
+
end
|
186
|
+
|
187
|
+
def get_app_name(remote, verbose = false)
|
188
|
+
ensure_valid_remote(remote)
|
189
|
+
response = `heroku apps:info -r #{remote}`
|
190
|
+
response.split(/\r?\n/).first[4..-1] # This is brittle
|
191
|
+
end
|
192
|
+
|
193
|
+
def ensure_valid_remote(remote)
|
194
|
+
unless VALID_REMOTES.include?(remote)
|
195
|
+
raise ArgumentError, "remote argument is required and must be %{VALID_REMOTES}"
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
end
|
200
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'wildland_dev_tools'
|
2
|
+
require 'rails'
|
3
|
+
module MyPlugin
|
4
|
+
# :nodoc:
|
5
|
+
class Railtie < Rails::Railtie
|
6
|
+
railtie_name :wildland_dev_tools
|
7
|
+
|
8
|
+
rake_tasks do
|
9
|
+
load 'tasks/heroku.rake'
|
10
|
+
load 'tasks/reports.rake'
|
11
|
+
load 'tasks/setup.rake'
|
12
|
+
load 'tasks/releases.rake'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module WildlandDevTools
|
4
|
+
# :nodoc:
|
5
|
+
module Releases
|
6
|
+
VALID_REMOTES = %w(production staging)
|
7
|
+
|
8
|
+
class << self
|
9
|
+
def create_release(verbose = false)
|
10
|
+
return false unless git_up_to_date!
|
11
|
+
tag_name = "PRODUCTION-#{base_tag_name}"
|
12
|
+
create_and_push_tag(tag_name, verbose)
|
13
|
+
end
|
14
|
+
|
15
|
+
def create_release_candidate(verbose = false)
|
16
|
+
return false unless git_up_to_date!
|
17
|
+
tag_name = "RC-#{base_tag_name}"
|
18
|
+
create_and_push_tag(tag_name, verbose)
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def create_and_push_tag(tag_name, verbose = false)
|
24
|
+
puts "Creating tag #{tag_name}" if verbose
|
25
|
+
system("OVERCOMMIT_DISABLE=1 git tag #{tag_name}")
|
26
|
+
system("OVERCOMMIT_DISABLE=1 git push origin #{tag_name}")
|
27
|
+
end
|
28
|
+
|
29
|
+
def base_tag_name
|
30
|
+
DateTime.now.strftime("%y-%m-%d-%H-%M")
|
31
|
+
end
|
32
|
+
|
33
|
+
def git_up_to_date!
|
34
|
+
local = `OVERCOMMIT_DISABLE=1 git rev-parse @`
|
35
|
+
remote = `OVERCOMMIT_DISABLE=1 git rev-parse @{u}`
|
36
|
+
base = `OVERCOMMIT_DISABLE=1 git merge-base @ @{u}`
|
37
|
+
case
|
38
|
+
when local == remote
|
39
|
+
return true
|
40
|
+
when local == base
|
41
|
+
raise GitSyncException, 'Need to pull master from origin.'
|
42
|
+
when remote == base
|
43
|
+
raise GitSyncException, 'Need to push master to origin.'
|
44
|
+
else
|
45
|
+
raise GitSyncException, 'Your local master has diverged from origin.'
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module WildlandDevTools
|
2
|
+
# :nodoc:
|
3
|
+
module Updater
|
4
|
+
class << self
|
5
|
+
def reset_database
|
6
|
+
system('rake db:drop')
|
7
|
+
system('rake db:create')
|
8
|
+
system('rake db:migrate')
|
9
|
+
system('annotate') if system('which annotate > /dev/null 2>&1')
|
10
|
+
end
|
11
|
+
|
12
|
+
def reseed_database
|
13
|
+
system('rake db:seed')
|
14
|
+
system('rake demo:seed')
|
15
|
+
end
|
16
|
+
|
17
|
+
def ruby_version_up_to_date?(needed_ruby_version)
|
18
|
+
ruby_version = `ruby -v`
|
19
|
+
ruby_version.include?(needed_ruby_version.strip)
|
20
|
+
end
|
21
|
+
|
22
|
+
def update_ruby(version)
|
23
|
+
case
|
24
|
+
when system('which rvm > /dev/null 2>&1')
|
25
|
+
update_ruby_with_rvm(version)
|
26
|
+
when system('which rbenv > /dev/null 2>&1')
|
27
|
+
update_ruby_with_rbenv(version)
|
28
|
+
else
|
29
|
+
puts "Please manually update to Ruby #{version}"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def update_ruby_with_rvm(version)
|
34
|
+
# Try to use the version or install and use
|
35
|
+
system("rvm use #{version}")
|
36
|
+
unless ruby_version_up_to_date?(version)
|
37
|
+
system("rvm install #{version}")
|
38
|
+
system("rvm use #{version}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def update_ruby_with_rbenv(version)
|
43
|
+
system("rbenv install #{version}")
|
44
|
+
end
|
45
|
+
|
46
|
+
def ember_cli_rails_installed?
|
47
|
+
File.exist?('bin/heroku_install') && File.exist?('package.json')
|
48
|
+
end
|
49
|
+
|
50
|
+
def old_ember_setup
|
51
|
+
Dir.chdir('app-ember') do
|
52
|
+
system('npm install')
|
53
|
+
system('bower install')
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def clear_ember_cache
|
58
|
+
Dir.chdir('app-ember') do
|
59
|
+
system('npm cache clean && bower cache clean')
|
60
|
+
system('rm -rf node_modules && rm -rf bower_components')
|
61
|
+
system('npm install && bower install')
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'wildland_dev_tools/version'
|
2
|
+
|
3
|
+
# :nodoc:
|
4
|
+
module WildlandDevTools
|
5
|
+
require 'wildland_dev_tools/railtie' if defined?(Rails)
|
6
|
+
require 'wildland_dev_tools/updater'
|
7
|
+
require 'wildland_dev_tools/heroku'
|
8
|
+
require 'wildland_dev_tools/releases'
|
9
|
+
|
10
|
+
class GitSyncException < StandardError; end
|
11
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'wildland_dev_tools/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "wildland_dev_tools"
|
8
|
+
spec.version = WildlandDevTools::VERSION
|
9
|
+
spec.authors = ["Joe Weakley"]
|
10
|
+
spec.email = ["joew@samjoe.com"]
|
11
|
+
|
12
|
+
spec.summary = 'Wildland Dev Tools'
|
13
|
+
spec.description = 'Wildland Dev Tools'
|
14
|
+
spec.homepage = 'http://wild.land'
|
15
|
+
spec.license = "MIT"
|
16
|
+
|
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
|
+
spec.add_dependency 'rails', ['>= 4.1', '< 5']
|
22
|
+
spec.add_runtime_dependency 'rubocop', '>= 0.33'
|
23
|
+
spec.add_runtime_dependency 'git', '>= 1.3.0'
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.10"
|
26
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
27
|
+
spec.add_development_dependency "rspec"
|
28
|
+
end
|
metadata
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: wildland_dev_tools
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.8.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Joe Weakley
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-06-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.1'
|
20
|
+
- - "<"
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '5'
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '4.1'
|
30
|
+
- - "<"
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '5'
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rubocop
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '0.33'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0.33'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: git
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ">="
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: 1.3.0
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: 1.3.0
|
61
|
+
- !ruby/object:Gem::Dependency
|
62
|
+
name: bundler
|
63
|
+
requirement: !ruby/object:Gem::Requirement
|
64
|
+
requirements:
|
65
|
+
- - "~>"
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
version: '1.10'
|
68
|
+
type: :development
|
69
|
+
prerelease: false
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - "~>"
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '1.10'
|
75
|
+
- !ruby/object:Gem::Dependency
|
76
|
+
name: rake
|
77
|
+
requirement: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - "~>"
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '10.0'
|
82
|
+
type: :development
|
83
|
+
prerelease: false
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - "~>"
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '10.0'
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: rspec
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
description: Wildland Dev Tools
|
104
|
+
email:
|
105
|
+
- joew@samjoe.com
|
106
|
+
executables: []
|
107
|
+
extensions: []
|
108
|
+
extra_rdoc_files: []
|
109
|
+
files:
|
110
|
+
- ".gitignore"
|
111
|
+
- ".rspec"
|
112
|
+
- ".travis.yml"
|
113
|
+
- Gemfile
|
114
|
+
- LICENSE.txt
|
115
|
+
- README.md
|
116
|
+
- Rakefile
|
117
|
+
- lib/tasks/heroku.rake
|
118
|
+
- lib/tasks/releases.rake
|
119
|
+
- lib/tasks/reports.rake
|
120
|
+
- lib/tasks/setup.rake
|
121
|
+
- lib/wildland_dev_tools.rb
|
122
|
+
- lib/wildland_dev_tools/heroku.rb
|
123
|
+
- lib/wildland_dev_tools/railtie.rb
|
124
|
+
- lib/wildland_dev_tools/releases.rb
|
125
|
+
- lib/wildland_dev_tools/updater.rb
|
126
|
+
- lib/wildland_dev_tools/version.rb
|
127
|
+
- wildland_dev_tools.gemspec
|
128
|
+
homepage: http://wild.land
|
129
|
+
licenses:
|
130
|
+
- MIT
|
131
|
+
metadata: {}
|
132
|
+
post_install_message:
|
133
|
+
rdoc_options: []
|
134
|
+
require_paths:
|
135
|
+
- lib
|
136
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
137
|
+
requirements:
|
138
|
+
- - ">="
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
version: '0'
|
141
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
142
|
+
requirements:
|
143
|
+
- - ">="
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
requirements: []
|
147
|
+
rubyforge_project:
|
148
|
+
rubygems_version: 2.5.1
|
149
|
+
signing_key:
|
150
|
+
specification_version: 4
|
151
|
+
summary: Wildland Dev Tools
|
152
|
+
test_files: []
|