morpheus-heroku 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: dbd167532237ddbed5b8a0c707a49202c858fe3b
4
+ data.tar.gz: 2a4812332e2b925baad0e2c9dbdd693f63030883
5
+ SHA512:
6
+ metadata.gz: 7dc1614c01ad020014cb1a3eb819c2ba8389b944aac12154e0776d635182c9668706f2acb05c917e13b52fa264fcbfd7aa650258ebf03010009fe2bf65dfc560
7
+ data.tar.gz: 00ceab0393dbc2bb10706387ca951dcd1fc6f95d06312cd0384ea7b3504e04eee94808dd2ef98aacee9a9fbd0aca07adffbe0804b7a45124546b7dae07119fbb
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ /*.gem
2
+ .DS_Store
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 Catalin Ionescu
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.
data/README.md ADDED
@@ -0,0 +1,48 @@
1
+ # MorpheusHeroku
2
+
3
+ A set of rake tasks to automate interacting with Heroku.
4
+
5
+ ## Assumptions
6
+
7
+ This gem relies heavily on bash for interacting with Heroku. It's assuming you have the `Heroku CLI`
8
+ installed and `curl`. Your session must be authenticated with heroku (i.e. running `heroku logs` works).
9
+ You must have a Heroku remote set up (`heroku git:remote -a my-app-name`).
10
+ *Warning* We use `--force` when deploying to Heroku.
11
+
12
+ ## Install
13
+
14
+ Add this to your gemfile
15
+
16
+ `gem 'morpheus-heroku'`
17
+
18
+ Generate an initializer for `config/morpheus-heroku.rb` with
19
+
20
+ `bundle exec rails generate morpheus-heroku`
21
+
22
+ ## Automate deploying to Heroku
23
+
24
+ MorpheusHeroku will infer the current branch from git, deploy it to Heroku master, run the migrations and then tag
25
+ the release in git.
26
+
27
+ `bundle exec rake deploy:production`
28
+
29
+ ## Fetch a database backup from Heroku
30
+
31
+ MorpheusHeroku will fetch the latest PG backup. If there is no backup, then it will create one. It is
32
+ strongly recommended to set a recurring Heroku backup to avoid loading stale data.
33
+ https://devcenter.heroku.com/articles/heroku-postgres-backups#scheduling-backups
34
+
35
+ `bundle exec rake db:fetch`
36
+
37
+ ## Load a database backup
38
+
39
+ MorpheusHeroku will fetch the latest database backup and then load it using the `pg_restore` command.
40
+
41
+ `bundle exec rake db:load`
42
+
43
+ ## Rails 5 Tips
44
+
45
+ If you see `ActiveRecord::ProtectedEnvironmentError: You are attempting to run a destructive action against your 'production' database.`
46
+ even when running in development, then you need to do this:
47
+
48
+ `bin/rails db:environment:set RAILS_ENV=development`
@@ -0,0 +1,11 @@
1
+ MorpheusHeroku.configure do |config|
2
+ # config.app_name = "app_name"
3
+
4
+ # config.backup_location = "tmp/latest.dump"
5
+
6
+ # By default, we use ActiveRecord::Base.connection_config[:database]
7
+ # config.database_name = "database_development"
8
+
9
+ # Show debugging events
10
+ # config.log_events = false
11
+ end
@@ -0,0 +1,8 @@
1
+ class MorpheusHerokuGenerator < Rails::Generators::Base
2
+ source_root File.expand_path("../../../", __FILE__)
3
+
4
+ desc "Generate an initializer"
5
+ def create_initializer_file
6
+ copy_file "config/morpheus-heroku-initializer.rb", "config/initializers/morpheus-heroku.rb"
7
+ end
8
+ end
@@ -0,0 +1,39 @@
1
+ require 'morpheus-heroku/fetch'
2
+ require 'morpheus-heroku/load'
3
+ require 'morpheus-heroku/deploy'
4
+
5
+ require 'morpheus-heroku/helper'
6
+ require 'morpheus-heroku/config'
7
+
8
+ require 'morpheus-heroku/railtie'
9
+
10
+ module MorpheusHeroku
11
+ class << self
12
+ attr_accessor :configuration
13
+ end
14
+
15
+ class NotImplemented < StandardError; end
16
+
17
+ extend self
18
+
19
+ def fetch
20
+ MorpheusHeroku::Fetch.run
21
+ end
22
+
23
+ def load
24
+ MorpheusHeroku::Load.run
25
+ end
26
+
27
+ def deploy(environment = :production)
28
+ if environment == :production
29
+ MorpheusHeroku::Deploy.production
30
+ elsif environment == :staging
31
+ raise NotImplemented, "MorpheusHeroku doesn't support deploying to staging yet!"
32
+ end
33
+ end
34
+
35
+ def self.configure
36
+ self.configuration ||= Config.new
37
+ yield(configuration)
38
+ end
39
+ end
@@ -0,0 +1,11 @@
1
+ module MorpheusHeroku
2
+ class Config
3
+ attr_accessor :database_name, :backup_location, :app_name, :log_events
4
+
5
+ def initialize
6
+ @database_name = ActiveRecord::Base.connection_config[:database]
7
+ @backup_location = "tmp/latest.dump"
8
+ @log_events = false
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,48 @@
1
+ module MorpheusHeroku
2
+ module Deploy
3
+ extend self
4
+
5
+ def production
6
+ ensure_local_remote_is_up_to_date!
7
+ deploy_to_heroku!
8
+ run_database_migrations!
9
+ restart_server!
10
+ tag_release!
11
+ update_git!
12
+ end
13
+
14
+ private
15
+
16
+ def git_branch
17
+ @branch ||= `git branch | grep -e "^*"`.strip.gsub("* ", "")
18
+ end
19
+
20
+ def ensure_local_remote_is_up_to_date!
21
+ Helper.bash_run(command: "git pull origin #{git_branch}")
22
+ end
23
+
24
+ def deploy_to_heroku!
25
+ Helper.bash_run(command: "git push heroku #{git_branch}:master --force")
26
+ end
27
+
28
+ def run_database_migrations!
29
+ Helper.heroku_run(command: "heroku run rake db:migrate")
30
+ end
31
+
32
+ def tag_release!
33
+ Helper.bash_run(command: "git tag #{tag_name}")
34
+ end
35
+
36
+ def tag_name
37
+ "heroku_deploy_#{Time.now.to_s(:db).gsub(/[- :]/, "_")}"
38
+ end
39
+
40
+ def update_git!
41
+ Helper.bash_run(command: "git push origin --tags")
42
+ end
43
+
44
+ def restart_server!
45
+ Helper.heroku_run(command: "heroku restart")
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,31 @@
1
+ module MorpheusHeroku
2
+ module Fetch
3
+ extend self
4
+
5
+ def run
6
+ unless backup_available?
7
+ Rails.logger.info "No backup available. Generating one"
8
+ generate_backup!
9
+ end
10
+ download_backup!
11
+ end
12
+
13
+ private
14
+
15
+ def backup_available?
16
+ Helper.heroku_run(command: "heroku pg:backups public-url")
17
+ end
18
+
19
+ def generate_backup!
20
+ Helper.heroku_run(command: "heroku pg:backups capture")
21
+ end
22
+
23
+ def backup_url
24
+ Helper.heroku_run(command: "heroku pg:backups public-url")
25
+ end
26
+
27
+ def download_backup!
28
+ Helper.bash_run(command: "curl -o #{MorpheusHeroku.configuration.backup_location} `heroku pg:backups public-url`")
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,40 @@
1
+ module MorpheusHeroku
2
+ module Helper
3
+ extend self
4
+
5
+ def heroku_run(command: "")
6
+ if MorpheusHeroku.configuration.app_name.present?
7
+ command += " --app #{MorpheusHeroku.configuration.app_name}"
8
+ end
9
+ generic_run(command)
10
+ end
11
+
12
+ def bash_run(command: "")
13
+ generic_run(command)
14
+ end
15
+
16
+ def logger(message = "")
17
+ if MorpheusHeroku.configuration.log_events
18
+ puts "<MORPHEUS>".text_red
19
+ puts "Running: #{message}".text_green
20
+ puts "RAILS_ENV: #{Rails.env}".text_green
21
+ puts "APP_NAME: #{MorpheusHeroku.configuration.app_name}".text_green
22
+ puts "</MORPHEUS>".text_red
23
+ end
24
+ end
25
+
26
+ private
27
+
28
+ def generic_run(command)
29
+ Helper.logger(command)
30
+ Bundler.with_clean_env do
31
+ system(command) || abort("\n== Command #{command} failed ==")
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ class String
38
+ def text_red; "\e[31m#{self}\e[0m" end
39
+ def text_green; "\e[32m#{self}\e[0m" end
40
+ end
@@ -0,0 +1,32 @@
1
+ module MorpheusHeroku
2
+ module Load
3
+ extend self
4
+
5
+ def run
6
+ ensure_db_environment! if Rails.env.development?
7
+ drop_database!
8
+ create_database!
9
+ load_database!
10
+ end
11
+
12
+ private
13
+
14
+ def ensure_db_environment!
15
+ Helper.bash_run(command: "bundle exec rake db:environment:set RAILS_ENV=development")
16
+ end
17
+
18
+ def drop_database!
19
+ Helper.logger("Rake::Task['db:drop']")
20
+ Rake::Task["db:drop"].invoke
21
+ end
22
+
23
+ def create_database!
24
+ Helper.logger("Rake::Task['db:create']")
25
+ Rake::Task["db:create"].invoke
26
+ end
27
+
28
+ def load_database!
29
+ Helper.bash_run(command: "pg_restore -O -n public -d #{MorpheusHeroku.configuration.database_name} #{MorpheusHeroku.configuration.backup_location}")
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,8 @@
1
+ module MorpheusHeroku
2
+ class Railtie < Rails::Railtie
3
+ rake_tasks do
4
+ load "tasks/db.rake"
5
+ load "tasks/deploy.rake"
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,3 @@
1
+ module MorpheusHeroku
2
+ VERSION = "0.1.0"
3
+ end
data/lib/tasks/db.rake ADDED
@@ -0,0 +1,12 @@
1
+ namespace :db do
2
+ desc 'Load a production db into dev'
3
+ task load: :environment do
4
+ MorpheusHeroku.fetch
5
+ MorpheusHeroku.load
6
+ end
7
+
8
+ desc 'Fetch the latest backup db from Heroku'
9
+ task fetch: :environment do
10
+ MorpheusHeroku.fetch
11
+ end
12
+ end
@@ -0,0 +1,6 @@
1
+ namespace :deploy do
2
+ desc 'Deploy current branch onto Heroku Master'
3
+ task production: :environment do
4
+ MorpheusHeroku.deploy(:production)
5
+ end
6
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'morpheus-heroku/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "morpheus-heroku"
8
+ spec.version = MorpheusHeroku::VERSION
9
+ spec.authors = ["Catalin Ionescu"]
10
+ spec.email = ["catalin.ionescu282@gmail.com"]
11
+
12
+ spec.summary = "A set of Rake scrips to automate interactions with Heroku"
13
+ spec.homepage = "https://github.com/cionescu/morpheus-heroku"
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 "rake", ">= 10.0"
22
+
23
+ spec.add_development_dependency "rails", ">= 4.2"
24
+ spec.add_development_dependency "rspec"
25
+ spec.add_development_dependency "pry"
26
+ end
metadata ADDED
@@ -0,0 +1,117 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: morpheus-heroku
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Catalin Ionescu
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-06-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: '10.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '10.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rails
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '4.2'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '4.2'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
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: 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
+ description:
70
+ email:
71
+ - catalin.ionescu282@gmail.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - ".gitignore"
77
+ - LICENSE
78
+ - README.md
79
+ - config/morpheus-heroku-initializer.rb
80
+ - lib/generators/morpheus_heroku_generator.rb
81
+ - lib/morpheus-heroku.rb
82
+ - lib/morpheus-heroku/config.rb
83
+ - lib/morpheus-heroku/deploy.rb
84
+ - lib/morpheus-heroku/fetch.rb
85
+ - lib/morpheus-heroku/helper.rb
86
+ - lib/morpheus-heroku/load.rb
87
+ - lib/morpheus-heroku/railtie.rb
88
+ - lib/morpheus-heroku/version.rb
89
+ - lib/tasks/db.rake
90
+ - lib/tasks/deploy.rake
91
+ - morpheus-heroku.gemspec
92
+ homepage: https://github.com/cionescu/morpheus-heroku
93
+ licenses:
94
+ - MIT
95
+ metadata: {}
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 2.5.1
113
+ signing_key:
114
+ specification_version: 4
115
+ summary: A set of Rake scrips to automate interactions with Heroku
116
+ test_files: []
117
+ has_rdoc: